| 1 | import { |
| 2 | applyReasoningDisplayMode, |
| 3 | getReasoningDisplayMode, |
| 4 | hydrateReasoningDisplayMode, |
| 5 | resolveReasoningDisplayMode, |
| 6 | setReasoningDisplayPending, |
| 7 | } from "../lib/reasoningDisplayPreference"; |
| 8 | |
| 9 | let passed = 0; |
| 10 | let failed = 0; |
| 11 | |
| 12 | function ok(value: boolean, label: string) { |
| 13 | if (value) { |
| 14 | process.stdout.write(` PASS ${label}\n`); |
| 15 | passed += 1; |
| 16 | } else { |
| 17 | process.stdout.write(` FAIL ${label}\n`); |
| 18 | failed += 1; |
| 19 | } |
| 20 | } |
| 21 | |
| 22 | console.log("\nreasoning display preference"); |
| 23 | |
| 24 | const storage = new Map<string, string>(); |
| 25 | Object.defineProperty(globalThis, "localStorage", { |
| 26 | configurable: true, |
| 27 | value: { |
| 28 | getItem: (key: string) => storage.get(key) ?? null, |
| 29 | setItem: (key: string, value: string) => void storage.set(key, value), |
| 30 | removeItem: (key: string) => void storage.delete(key), |
| 31 | }, |
| 32 | }); |
| 33 | |
| 34 | storage.clear(); |
| 35 | hydrateReasoningDisplayMode(undefined, false); |
| 36 | ok(getReasoningDisplayMode() === "auto", "missing preferences default to live follow"); |
| 37 | |
| 38 | hydrateReasoningDisplayMode("future-mode", false); |
| 39 | ok(getReasoningDisplayMode() === "auto", "unknown preferences use the live-follow fallback"); |
| 40 | |
| 41 | storage.set("reasonix-reasoning-summary", "0"); |
| 42 | hydrateReasoningDisplayMode("auto", false); |
| 43 | ok(getReasoningDisplayMode() === "legacy-collapsed", "legacy summary-off preserves the old compatible behavior"); |
| 44 | |
| 45 | storage.set("reasonix-reasoning-summary", "1"); |
| 46 | hydrateReasoningDisplayMode("auto", false); |
| 47 | ok(getReasoningDisplayMode() === "summary", "legacy summary-on wins over the old expand flag"); |
| 48 | |
| 49 | storage.set("reasonix-reasoning-summary", "0"); |
| 50 | hydrateReasoningDisplayMode("hidden", true); |
| 51 | ok(getReasoningDisplayMode() === "hidden", "explicit new mode wins over every legacy preference"); |
| 52 | |
| 53 | hydrateReasoningDisplayMode("summary", true); |
| 54 | ok(getReasoningDisplayMode() === "summary", "an explicit summary selection remains persisted"); |
| 55 | |
| 56 | hydrateReasoningDisplayMode("expanded", true); |
| 57 | ok(getReasoningDisplayMode() === "expanded", "an explicit expanded selection remains persisted"); |
| 58 | |
| 59 | storage.set("reasonix-reasoning-summary", "0"); |
| 60 | ok(resolveReasoningDisplayMode("auto", false) === "legacy-collapsed", "resolver applies legacy precedence without hydration"); |
| 61 | hydrateReasoningDisplayMode("auto", false); |
| 62 | applyReasoningDisplayMode("auto"); |
| 63 | ok(getReasoningDisplayMode() === "auto", "successful selection applies the new mode"); |
| 64 | ok(!storage.has("reasonix-reasoning-summary"), "successful selection clears the legacy key"); |
| 65 | |
| 66 | setReasoningDisplayPending(); |
| 67 | ok(getReasoningDisplayMode() === "pending", "startup can hold reasoning until settings hydrate"); |
| 68 | |
| 69 | console.log(`\n${passed} passed, ${failed} failed`); |
| 70 | if (failed > 0) process.exit(1); |
| 71 |