返回 DeepSeek-Reasonix
path_test.go
根目录 / internal / pathidentity / path_test.go
1 package pathidentity
2
3 import (
4 "errors"
5 "os"
6 "path/filepath"
7 "testing"
8 )
9
10 func TestResolveRejectsEmptyAndUnboundRelativePaths(t *testing.T) {
11 for _, path := range []string{"", " ", "relative"} {
12 _, err := Resolve(path, Options{FollowLeaf: true})
13 var identityErr *Error
14 if !errors.As(err, &identityErr) || identityErr.Kind != ErrorInvalid {
15 t.Fatalf("Resolve(%q) error = %v", path, err)
16 }
17 }
18 }
19
20 func TestResolveMissingTailThroughSymlink(t *testing.T) {
21 realParent := t.TempDir()
22 aliasParent := filepath.Join(t.TempDir(), "alias")
23 if err := os.Symlink(realParent, aliasParent); err != nil {
24 t.Skipf("symlink unavailable: %v", err)
25 }
26 realPhysical, err := filepath.EvalSymlinks(realParent)
27 if err != nil {
28 t.Fatal(err)
29 }
30 want := filepath.Join(realPhysical, "missing", "leaf")
31 got, err := Resolve(filepath.Join(aliasParent, "missing", "leaf"), Options{FollowLeaf: true})
32 if err != nil {
33 t.Fatal(err)
34 }
35 if got.PhysicalPath != want {
36 t.Fatalf("PhysicalPath = %q, want %q", got.PhysicalPath, want)
37 }
38 }
39
40 func TestResolveCanPreserveLeafSymlink(t *testing.T) {
41 dir := t.TempDir()
42 target := filepath.Join(dir, "target")
43 link := filepath.Join(dir, "link")
44 if err := os.Mkdir(target, 0o700); err != nil {
45 t.Fatal(err)
46 }
47 if err := os.Symlink(target, link); err != nil {
48 t.Skipf("symlink unavailable: %v", err)
49 }
50 followed, err := Resolve(link, Options{FollowLeaf: true})
51 if err != nil {
52 t.Fatal(err)
53 }
54 preserved, err := Resolve(link, Options{FollowLeaf: false})
55 if err != nil {
56 t.Fatal(err)
57 }
58 physicalDir, err := filepath.EvalSymlinks(dir)
59 if err != nil {
60 t.Fatal(err)
61 }
62 if followed.PhysicalPath != filepath.Join(physicalDir, "target") || preserved.PhysicalPath != filepath.Join(physicalDir, "link") {
63 t.Fatalf("followed=%q preserved=%q", followed.PhysicalPath, preserved.PhysicalPath)
64 }
65 }
66
67 func TestSameUsesPhysicalIdentity(t *testing.T) {
68 dir := t.TempDir()
69 alias := filepath.Join(t.TempDir(), "alias")
70 if err := os.Symlink(dir, alias); err != nil {
71 t.Skipf("symlink unavailable: %v", err)
72 }
73 same, err := Same(dir, alias, Options{FollowLeaf: true})
74 if err != nil || !same {
75 t.Fatalf("Same = %v, %v", same, err)
76 }
77 }
78
79 func TestResolveIdentityIsStableAcrossMissingTailCreation(t *testing.T) {
80 path := filepath.Join(t.TempDir(), "new", "workspace")
81 before, err := Resolve(path, Options{FollowLeaf: true})
82 if err != nil {
83 t.Fatal(err)
84 }
85 if err := os.MkdirAll(path, 0o700); err != nil {
86 t.Fatal(err)
87 }
88 after, err := Resolve(path, Options{FollowLeaf: true})
89 if err != nil {
90 t.Fatal(err)
91 }
92 if before.Key != after.Key {
93 t.Fatalf("identity changed after creation: %q != %q", before.Key, after.Key)
94 }
95 }
96
97 func TestResolveReportsLinkLoop(t *testing.T) {
98 dir := t.TempDir()
99 left, right := filepath.Join(dir, "left"), filepath.Join(dir, "right")
100 if err := os.Symlink(right, left); err != nil {
101 t.Skipf("symlink unavailable: %v", err)
102 }
103 if err := os.Symlink(left, right); err != nil {
104 t.Fatal(err)
105 }
106 _, err := Resolve(left, Options{FollowLeaf: true})
107 var identityErr *Error
108 if !errors.As(err, &identityErr) || identityErr.Kind != ErrorLinkLoop {
109 t.Fatalf("error = %v", err)
110 }
111 }
112
112 lines GO