返回 DeepSeek-Reasonix
runtime-turn-done-chime.test.ts
根目录 / desktop / frontend / src / __tests__ / runtime-turn-done-chime.test.ts
1 import assert from "node:assert/strict";
2 import { setAttentionPreference, setSuccessPreference } from "../lib/sound";
3 import { createRuntimeNotifications } from "../lib/runtimeNotifications";
4 import { t } from "../lib/i18n";
5
6 const stored = new Map<string, string>();
7 Object.defineProperty(globalThis, "localStorage", {
8 configurable: true,
9 value: {
10 getItem(key: string) { return stored.get(key) ?? null; },
11 setItem(key: string, value: string) { stored.set(key, value); },
12 removeItem(key: string) { stored.delete(key); },
13 clear() { stored.clear(); },
14 },
15 });
16 let contexts = 0;
17 class FakeAudioContext {
18 destination = {};
19 constructor() { contexts++; }
20 createOscillator() { return { type: "sine", frequency: { setValueAtTime() {} }, connect() {}, start() {}, stop() {} }; }
21 createGain() {
22 return { gain: { setValueAtTime() {}, linearRampToValueAtTime() {}, exponentialRampToValueAtTime() {} }, connect() {} };
23 }
24 close() {}
25 }
26 Object.defineProperty(globalThis, "AudioContext", { configurable: true, value: FakeAudioContext });
27
28 const owner = createRuntimeNotifications(() => ({ activeTabId: "A", t, showToast() {} }));
29
30 function chimesFor(event: { err?: string; outcome?: string }, only: "success" | "attention"): number {
31 setSuccessPreference(only === "success" ? "synth" : "off");
32 setAttentionPreference(only === "attention" ? "synth" : "off");
33 const before = contexts;
34 owner.accept({ event: { kind: "turn_done", tabId: "A", ...event } });
35 return contexts - before;
36 }
37
38 const readiness = { err: "delivery checks are incomplete", outcome: "final_readiness" };
39 assert.equal(chimesFor(readiness, "attention"), 1, "a turn that stopped for delivery checks must alert the user");
40 assert.equal(chimesFor(readiness, "success"), 0, "a turn that stopped for delivery checks is not a success");
41 for (const outcome of ["recovery_paused", "incomplete_read", "completion_uncertain"]) {
42 assert.equal(chimesFor({ err: "paused", outcome }, "attention"), 1, `${outcome} waits on the user`);
43 }
44 assert.equal(chimesFor({}, "success"), 1, "a clean finish keeps the success chime");
45 assert.equal(chimesFor({}, "attention"), 0, "a clean finish does not ring the attention chime");
46 assert.equal(chimesFor({ err: "provider failed" }, "success") + chimesFor({ err: "provider failed" }, "attention"), 0,
47 "an ordinary failure stays silent");
48 owner.dispose();
49 console.log("runtime notifications: paused turn outcomes ring the attention chime");
50
50 lines TYPESCRIPT