返回 DeepSeek-Reasonix
tab_goal_restore_test.go
根目录 / desktop / tab_goal_restore_test.go
1 package main
2
3 import (
4 "os"
5 "path/filepath"
6 "testing"
7
8 "reasonix/internal/agent"
9 "reasonix/internal/control"
10 "reasonix/internal/event"
11 "reasonix/internal/tool"
12 )
13
14 // TestRestoredTabGoalFollowsSessionGoalState pins the restart half of the
15 // goal-reset contract: a typed /new or /clear rotates the session through the
16 // controller (never touching App.NewSession/ClearSession), so the goal saved
17 // in desktop-tabs.json can be stale. Startup restore must validate it against
18 // the session's goal-state sidecar — which the rotation wrote as stopped on
19 // the fresh path — instead of re-seeding the cleared goal via SetGoal.
20 func TestRestoredTabGoalFollowsSessionGoalState(t *testing.T) {
21 isolateDesktopUserDirs(t)
22 dir := t.TempDir()
23 oldPath := filepath.Join(dir, "session.jsonl")
24
25 exec := agent.New(stubProvider{}, tool.NewRegistry(), agent.NewSession("sys"), agent.Options{}, event.Discard)
26 ctrl := control.New(control.Options{Executor: exec, SystemPrompt: "sys", SessionDir: dir, SessionPath: oldPath, Label: "test", Sink: event.Discard})
27 ctrl.SetGoal("finish the migration")
28
29 // Typed /new: controller-side rotation only.
30 if err := ctrl.NewSession(); err != nil {
31 t.Fatalf("NewSession: %v", err)
32 }
33 newPath := ctrl.SessionPath()
34 ctrl.Close()
35
36 // desktop-tabs.json still carries the pre-rotation goal with the rotated
37 // path (the tab profile was never told about the /new). Restore must not
38 // resurrect it: the rotated session's sidecar says stopped.
39 if got := runningTabSessionGoal(newPath, "finish the migration"); got != "" {
40 t.Fatalf("restored goal for rotated session = %q, want empty", got)
41 }
42
43 // The OLD session's sidecar still says running: restoring a tab that
44 // points at the old session keeps its goal (resume semantics).
45 if got := runningTabSessionGoal(oldPath, "finish the migration"); got != "finish the migration" {
46 t.Fatalf("restored goal for old session = %q, want preserved", got)
47 }
48
49 // A session without a goal-state sidecar keeps the persisted goal
50 // (legacy sessions predating the sidecar).
51 bare := filepath.Join(dir, "bare.jsonl")
52 if err := os.WriteFile(bare, []byte("{}\n"), 0o644); err != nil {
53 t.Fatalf("write bare session: %v", err)
54 }
55 if got := runningTabSessionGoal(bare, "legacy goal"); got != "legacy goal" {
56 t.Fatalf("restored goal without sidecar = %q, want fallback preserved", got)
57 }
58 }
59
59 lines GO