返回 DeepSeek-Reasonix
session-title-contract.test.ts
根目录 / desktop / frontend / src / __tests__ / session-title-contract.test.ts
1 // Run: tsx src/__tests__/session-title-contract.test.ts
2
3 import {
4 historySearchHitDisplayTitle,
5 historySessionDisplayTitle,
6 paletteSessionDisplayTitle,
7 paletteSessionHint,
8 paletteSessionKeywords,
9 } from "../lib/session";
10 import type { SessionMeta } from "../lib/types";
11
12 let passed = 0;
13 let failed = 0;
14
15 function eq<T>(actual: T, expected: T, label: string) {
16 if (Object.is(actual, expected)) {
17 process.stdout.write(` PASS ${label}\n`);
18 passed += 1;
19 } else {
20 process.stdout.write(` FAIL ${label}\n expected: ${String(expected)}\n actual: ${String(actual)}\n`);
21 failed += 1;
22 }
23 }
24
25 function deepEq<T>(actual: T, expected: T, label: string) {
26 const actualJson = JSON.stringify(actual);
27 const expectedJson = JSON.stringify(expected);
28 if (actualJson === expectedJson) {
29 process.stdout.write(` PASS ${label}\n`);
30 passed += 1;
31 } else {
32 process.stdout.write(` FAIL ${label}\n expected: ${expectedJson}\n actual: ${actualJson}\n`);
33 failed += 1;
34 }
35 }
36
37 function session(overrides: Partial<SessionMeta> = {}): SessionMeta {
38 return {
39 path: "/sessions/topic-backed.jsonl",
40 preview: "first saved prompt preview",
41 title: "Renamed saved session",
42 turns: 3,
43 createdAt: 100,
44 lastActivityAt: 200,
45 modTime: 200,
46 current: false,
47 open: false,
48 workspaceRoot: "/work/project-alpha",
49 topicId: "topic-1",
50 topicTitle: "Shared topic",
51 ...overrides,
52 };
53 }
54
55 console.log("\nsession title contracts");
56
57 {
58 const hit = {
59 sessionPath: "/sessions/version.jsonl",
60 sessionTitle: "Private version note",
61 topicTitle: "Shared topic",
62 };
63 eq(
64 historySearchHitDisplayTitle(hit),
65 "Shared topic",
66 "History content search keeps physical-version notes out of the logical title",
67 );
68 eq(
69 historySearchHitDisplayTitle({ ...hit, topicTitle: "" }),
70 "Private version note",
71 "Legacy search hits without a topic title retain the session-title fallback",
72 );
73 }
74
75 {
76 const item = session();
77 eq(
78 paletteSessionDisplayTitle(item, "Untitled"),
79 "Shared topic",
80 "Cmd+K displays the topic title for topic-backed sessions",
81 );
82 deepEq(
83 paletteSessionKeywords(item),
84 ["first saved prompt preview"],
85 "Cmd+K keeps per-version notes out of the logical session search contract",
86 );
87 eq(
88 paletteSessionHint(item),
89 "first saved prompt preview · /work/project-alpha",
90 "Cmd+K uses the content preview rather than a physical-version note",
91 );
92 }
93
94 {
95 const item = session();
96 eq(
97 historySessionDisplayTitle(item, "Untitled"),
98 "Shared topic",
99 "History displays the logical topic title instead of a physical-version note",
100 );
101 }
102
103 {
104 const item = session({ title: " " });
105 eq(
106 historySessionDisplayTitle(item, "Untitled"),
107 "Shared topic",
108 "Unrenamed topic-backed history sessions fall back to topic title",
109 );
110 deepEq(
111 paletteSessionKeywords(item),
112 ["first saved prompt preview"],
113 "Blank session titles are not added as Cmd+K keywords",
114 );
115 eq(
116 paletteSessionHint(item),
117 "first saved prompt preview · /work/project-alpha",
118 "Cmd+K falls back to preview text in the hint when there is no custom session title",
119 );
120 }
121
122 {
123 const item = session({ title: "Shared topic", preview: "first saved prompt preview" });
124 eq(
125 paletteSessionHint(item),
126 "first saved prompt preview · /work/project-alpha",
127 "Cmd+K skips duplicate title hints that repeat the visible topic title",
128 );
129 }
130
131 console.log(`\n${passed} passed, ${failed} failed`);
132 if (failed > 0) process.exit(1);
133
133 lines TYPESCRIPT