返回 DeepSeek-Reasonix
context-maintenance-notice.test.ts
根目录 / desktop / frontend / src / __tests__ / context-maintenance-notice.test.ts
1 import { readFileSync } from "node:fs";
2 import {
3 formatContextMaintenanceNotice,
4 isNewMaintenanceOperation,
5 rememberMaintenanceOperation,
6 } from "../lib/contextMaintenanceTypes";
7 import type { DictKey, Translator } from "../lib/i18n";
8
9 function ok(value: unknown, message: string) {
10 if (!value) throw new Error(message);
11 }
12
13 const messages: Partial<Record<DictKey, string>> = {
14 "context.maintenanceTitle": "上下文短视图",
15 "context.maintenanceAppliedSummary": "已生成短视图",
16 "context.maintenanceBlockedSummary": "摘要未形成短视图 · 已停重试",
17 "context.maintenanceFailedSummary": "摘要失败 · 已停重试",
18 "context.maintenanceTruncatedSummary": "已裁剪上下文视图",
19 "context.tokensValue": "{value} tokens",
20 "summary.detail": "摘要",
21 };
22
23 const translate: Translator = (key, vars) => {
24 const value = messages[key] ?? key;
25 return value.replace(/\{(\w+)\}/g, (_, name: string) => String(vars?.[name] ?? `{${name}}`));
26 };
27
28 const applied = formatContextMaintenanceNotice({
29 status: "applied",
30 action: "summary",
31 inputTokens: 120,
32 resultTokens: 80,
33 savedTokens: 40,
34 }, translate);
35 ok(applied === "已生成短视图", `unexpected applied notice: ${applied}`);
36
37 const blocked = formatContextMaintenanceNotice({ status: "blocked" }, translate);
38 ok(blocked === "摘要未形成短视图 · 已停重试", `unexpected blocked notice: ${blocked}`);
39
40 const failed = formatContextMaintenanceNotice({ status: "failed" }, translate);
41 ok(failed === "摘要失败 · 已停重试", `unexpected failed notice: ${failed}`);
42
43 const truncated = formatContextMaintenanceNotice({ status: "applied", action: "truncate" }, translate);
44 ok(truncated === "已裁剪上下文视图", `unexpected truncated notice: ${truncated}`);
45
46 const contextPanelSource = readFileSync(new URL("../components/ContextPanel.tsx", import.meta.url), "utf8");
47 ok(
48 !contextPanelSource.includes('className="context-panel__maintenance"'),
49 "ContextPanel must not render the context checkpoint detail block",
50 );
51 ok(
52 !contextPanelSource.includes('t("context.maintenanceCanonical")')
53 && !contextPanelSource.includes('t("context.maintenanceCheckpoint")'),
54 "ContextPanel must not expose canonical, model-visible, or checkpoint details",
55 );
56 ok(
57 !contextPanelSource.includes("checkpointState")
58 && !contextPanelSource.includes("canonicalTokens")
59 && !contextPanelSource.includes("projectedTokens"),
60 "ContextPanel must not derive hidden checkpoint presentation state",
61 );
62 ok(
63 !contextPanelSource.includes("snipTrigger") && !contextPanelSource.includes("forceTrigger"),
64 "ContextPanel must not present retired multi-threshold triggers as user settings",
65 );
66
67 ok(isNewMaintenanceOperation([], "op-1"), "empty seen list accepts first operationId");
68 ok(isNewMaintenanceOperation(["op-1"], "op-1") === false, "duplicate operationId is rejected");
69 ok(isNewMaintenanceOperation(["op-1"], "op-2"), "distinct operationId is accepted");
70 ok(isNewMaintenanceOperation(["op-1"], ""), "missing operationId is still shown");
71 const remembered = rememberMaintenanceOperation(["op-1"], "op-2");
72 ok(remembered.includes("op-1") && remembered.includes("op-2"), "remember keeps prior and new ids");
73 ok(rememberMaintenanceOperation(["op-1"], "op-1").length === 1, "remember is idempotent for same id");
74 const many = Array.from({ length: 70 }, (_, i) => `op-${i}`);
75 const bounded = rememberMaintenanceOperation(many.slice(0, 64), "op-new");
76 ok(bounded.length === 64 && bounded[bounded.length - 1] === "op-new", "remember bounds to 64 ids");
77
78 const settingsSource = readFileSync(new URL("../components/SettingsPanel.tsx", import.meta.url), "utf8");
79 ok(
80 !settingsSource.includes("settings.coldResumePrune") && !settingsSource.includes("SetColdResumePrune"),
81 "SettingsPanel must not expose retired coldResumePrune control",
82 );
83
84 console.log("context-maintenance-notice: ok");
85
85 lines TYPESCRIPT