返回 DeepSeek-Reasonix
creation_target_test.go
根目录 / desktop / internal / workspacestate / creation_target_test.go
1 package workspacestate
2
3 import (
4 "errors"
5 "os"
6 "path/filepath"
7 "testing"
8 )
9
10 func TestCreationFollowsWorkspaceMergeBetweenReserveAndAttach(t *testing.T) {
11 s := NewStore(filepath.Join(t.TempDir(), "registry.json"))
12 root := t.TempDir()
13 if err := s.EnsureWorkspace(t.Context(), Workspace{ID: "old", Root: root}); err != nil {
14 t.Fatal(err)
15 }
16 p := PendingCreate{OperationID: "create", WorkspaceID: "old", SessionID: "new-session"}
17 if _, err := s.BeginCreateAtRoot(t.Context(), p, root); err != nil {
18 t.Fatal(err)
19 }
20 // A historical writer had also registered Global for the same directory.
21 if err := s.mutate(t.Context(), func(state *State) error {
22 state.Workspaces[GlobalWorkspaceID] = Workspace{ID: GlobalWorkspaceID, Root: root}
23 state.WorkspaceIDs = append(state.WorkspaceIDs, GlobalWorkspaceID)
24 return nil
25 }); err != nil {
26 t.Fatal(err)
27 }
28 if _, err := s.EnsureWorkspaceResolved(t.Context(), Workspace{ID: GlobalWorkspaceID, Root: root}); err != nil {
29 t.Fatal(err)
30 }
31 // Publication still carries the pre-merge ID. The registry must resolve it
32 // inside its mutation, including when another process reopens the store.
33 s = NewStore(s.Path())
34 if err := s.AttachCreatedSessionAtRoot(t.Context(), p.OperationID, p.WorkspaceID, p.SessionID, root); err != nil {
35 t.Fatal(err)
36 }
37 if _, err := s.BeginCreateAtRoot(t.Context(), p, root); err != nil {
38 t.Fatal(err)
39 }
40 if err := s.AttachCreatedSessionAtRoot(t.Context(), p.OperationID, p.WorkspaceID, p.SessionID, root); err != nil {
41 t.Fatal(err)
42 }
43 state, err := s.Load(t.Context())
44 if err != nil {
45 t.Fatal(err)
46 }
47 assertStrings(t, state.Workspaces[GlobalWorkspaceID].SessionIDs, []string{p.SessionID})
48 if len(state.PendingCreates) != 0 || len(state.Workspaces) != 1 {
49 t.Fatalf("duplicate state: %+v", state)
50 }
51 }
52
53 func TestCreationTargetPreservesDirectoryAndLifecycleBoundaries(t *testing.T) {
54 s := NewStore(filepath.Join(t.TempDir(), "registry.json"))
55 root := t.TempDir()
56 if err := s.EnsureWorkspace(t.Context(), Workspace{ID: "project", Root: root}); err != nil {
57 t.Fatal(err)
58 }
59 p := PendingCreate{OperationID: "create", WorkspaceID: "project", SessionID: "session"}
60 if _, err := s.BeginCreateAtRoot(t.Context(), p, t.TempDir()); !errors.Is(err, ErrCreationWorkspaceChanged) {
61 t.Fatalf("wrong directory: %v", err)
62 }
63 if _, err := s.BeginCreateAtRoot(t.Context(), p, filepath.Join(root, "missing")); !errors.Is(err, ErrCreationWorkspaceUnavailable) {
64 t.Fatalf("missing directory: %v", err)
65 }
66 if _, err := s.BeginCreateAtRoot(t.Context(), p, root); err != nil {
67 t.Fatal(err)
68 }
69 if err := s.AttachCreatedSessionAtRoot(t.Context(), p.OperationID, p.WorkspaceID, p.SessionID, root); err != nil {
70 t.Fatal(err)
71 }
72 if err := s.ArchiveSession(t.Context(), p.SessionID); err != nil {
73 t.Fatal(err)
74 }
75 if _, err := s.BeginCreateAtRoot(t.Context(), p, root); !errors.Is(err, ErrCreationSessionInactive) {
76 t.Fatalf("archived reservation: %v", err)
77 }
78 if err := s.AttachCreatedSessionAtRoot(t.Context(), p.OperationID, p.WorkspaceID, p.SessionID, root); !errors.Is(err, ErrCreationSessionInactive) {
79 t.Fatalf("archived publication: %v", err)
80 }
81 p.OperationID, p.SessionID = "fresh-click", "fresh-session"
82 if _, err := s.BeginCreateAtRoot(t.Context(), p, root); err != nil {
83 t.Fatal(err)
84 }
85 other := p
86 other.OperationID = "competing-operation"
87 if _, err := s.BeginCreateAtRoot(t.Context(), other, root); !errors.Is(err, ErrMutationConflict) {
88 t.Fatalf("other operation: %v", err)
89 }
90 if err := s.mutate(t.Context(), func(state *State) error { delete(state.Workspaces, "project"); state.WorkspaceIDs = nil; return nil }); err != nil {
91 t.Fatal(err)
92 }
93 if _, err := s.BeginCreateAtRoot(t.Context(), p, root); !errors.Is(err, ErrWorkspaceNotFound) {
94 t.Fatalf("removed registration: %v", err)
95 }
96 if _, err := os.Stat(root); err != nil {
97 t.Fatal("test removed physical directory", err)
98 }
99 }
100
100 lines GO