返回 DeepSeek-Reasonix
writescope_test.go
根目录 / internal / evidence / writescope_test.go
1 package evidence
2
3 import (
4 "os"
5 "path/filepath"
6 "runtime"
7 "testing"
8 )
9
10 func TestClassifyWriteScopeTempIsScratch(t *testing.T) {
11 cases := []string{filepath.Join(os.TempDir(), "btc_klines.py")}
12 if runtime.GOOS != "windows" {
13 cases = append(cases, "/tmp/btc_klines.py")
14 if runtime.GOOS == "darwin" {
15 cases = append(cases, "/private/tmp/btc_klines.py")
16 }
17 }
18 for _, path := range cases {
19 if got := ClassifyWriteScope(path, "/home/dev/project", nil); got != WriteScopeScratch {
20 t.Fatalf("ClassifyWriteScope(%q) = %s, want scratch", path, got)
21 }
22 }
23 }
24
25 func TestClassifyWriteScopeWorkspaceAndOutside(t *testing.T) {
26 root := t.TempDir()
27 inside := filepath.Join(root, "internal", "agent", "agent.go")
28 if got := ClassifyWriteScope(inside, root, nil); got != WriteScopeWorkspace {
29 t.Fatalf("abs workspace path = %s, want workspace", got)
30 }
31 if got := ClassifyWriteScope("internal/agent/agent.go", root, nil); got != WriteScopeWorkspace {
32 t.Fatalf("rel workspace path = %s, want workspace", got)
33 }
34 if got := ClassifyWriteScope("parser.go", "", nil); got != WriteScopeWorkspace {
35 t.Fatalf("relative without root = %s, want workspace", got)
36 }
37 volumeRoot := filepath.VolumeName(os.TempDir()) + string(filepath.Separator)
38 outside := filepath.Join(volumeRoot, "reasonix-outside-home", "Notes", "idea.md")
39 if got := ClassifyWriteScope(outside, root, nil); got != WriteScopeOutside {
40 t.Fatalf("outside file = %s, want outside", got)
41 }
42 }
43
44 func TestClassifyWriteScopeSessionTempRoot(t *testing.T) {
45 scratch := t.TempDir()
46 path := filepath.Join(scratch, "probe.py")
47 if got := ClassifyWriteScope(path, t.TempDir(), []string{scratch}); got != WriteScopeScratch {
48 t.Fatalf("session temp = %s, want scratch", got)
49 }
50 volumeRoot := filepath.VolumeName(os.TempDir()) + string(filepath.Separator)
51 named := filepath.Join(volumeRoot, "reasonix-unowned-scope", "reasonix-session-tmp-abc", "probe.py")
52 if got := ClassifyWriteScope(named, t.TempDir(), nil); got != WriteScopeOutside {
53 t.Fatalf("unowned named temp = %s, want outside", got)
54 }
55 }
56
57 func TestClassifyWriteScopeKeepsLexicalWorkspaceSymlinksInWorkspace(t *testing.T) {
58 root := t.TempDir()
59 outside := t.TempDir()
60 if err := os.Symlink(outside, filepath.Join(root, "link")); err != nil {
61 t.Skipf("symlink unavailable: %v", err)
62 }
63 path := filepath.Join(root, "link", "probe.py")
64 if got := ClassifyWriteScope(path, root, nil); got != WriteScopeWorkspace {
65 t.Fatalf("workspace symlink path = %s, want workspace for the safety layer", got)
66 }
67 }
68
69 func TestClassifyWriteScopeScratchSymlinkIntoWorkspaceIsWorkspace(t *testing.T) {
70 workspace := t.TempDir()
71 scratch := t.TempDir()
72 link := filepath.Join(scratch, "workspace-link")
73 if err := os.Symlink(workspace, link); err != nil {
74 t.Skipf("symlink unavailable: %v", err)
75 }
76 path := filepath.Join(link, "probe.py")
77 if got := ClassifyWriteScope(path, workspace, []string{scratch}); got != WriteScopeWorkspace {
78 t.Fatalf("scratch alias into workspace = %s, want workspace", got)
79 }
80 }
81
81 lines GO