86 lines
4.2 KiB
TypeScript
86 lines
4.2 KiB
TypeScript
import assert from "node:assert/strict";
|
||
import { readFileSync } from "node:fs";
|
||
import test from "node:test";
|
||
|
||
import {
|
||
CHAT_CHART_OPEN_STORAGE_KEY,
|
||
CHAT_CHART_WIDTH_DEFAULT,
|
||
CHAT_CHART_WIDTH_MAX,
|
||
CHAT_CHART_WIDTH_MIN,
|
||
CHAT_CHART_WIDTH_STORAGE_KEY,
|
||
clampChatChartWidth,
|
||
readStoredChatChartOpen,
|
||
readStoredChatChartWidth,
|
||
writeStoredChatChartOpen,
|
||
writeStoredChatChartWidth,
|
||
type ChatChartStorage,
|
||
} from "../src/lib/chat-chart-panel-state.ts";
|
||
|
||
function memoryStorage(seed: Record<string, string> = {}): ChatChartStorage & { values: Map<string, string> } {
|
||
const values = new Map(Object.entries(seed));
|
||
return {
|
||
values,
|
||
getItem: (key) => values.get(key) ?? null,
|
||
setItem: (key, value) => { values.set(key, String(value)); },
|
||
};
|
||
}
|
||
|
||
test("chat natal panel remembers open and width on this machine", () => {
|
||
const storage = memoryStorage();
|
||
// 原值:没存过 → false(默认收起)
|
||
// 新值:没存过 → true(默认打开);用户收起后记住 false
|
||
// 原因:issue #114 Q8 A,产品 2026-10-27 定「一进聊天就出现盘」
|
||
assert.equal(readStoredChatChartOpen(storage), true);
|
||
assert.equal(readStoredChatChartWidth(storage), CHAT_CHART_WIDTH_DEFAULT);
|
||
|
||
writeStoredChatChartOpen(true, storage);
|
||
writeStoredChatChartWidth(480, storage);
|
||
assert.equal(storage.values.get(CHAT_CHART_OPEN_STORAGE_KEY), "1");
|
||
assert.equal(readStoredChatChartOpen(storage), true);
|
||
assert.equal(readStoredChatChartWidth(storage), 480);
|
||
|
||
writeStoredChatChartOpen(false, storage);
|
||
assert.equal(readStoredChatChartOpen(storage), false);
|
||
assert.equal(readStoredChatChartWidth(storage), 480);
|
||
});
|
||
|
||
// 原值:宽度 280~560;新值:320~760(默认 440);原因:issue #114 M8 右栏装完整盘面、检视和九曜表
|
||
test("chat natal panel width stays between 320 and 760", () => {
|
||
assert.equal(CHAT_CHART_WIDTH_MIN, 320);
|
||
assert.equal(CHAT_CHART_WIDTH_MAX, 760);
|
||
assert.equal(clampChatChartWidth(10), CHAT_CHART_WIDTH_MIN);
|
||
assert.equal(clampChatChartWidth(900), CHAT_CHART_WIDTH_MAX);
|
||
assert.equal(clampChatChartWidth(Number.NaN), CHAT_CHART_WIDTH_DEFAULT);
|
||
const storage = memoryStorage();
|
||
writeStoredChatChartWidth(12, storage);
|
||
assert.equal(storage.values.get(CHAT_CHART_WIDTH_STORAGE_KEY), String(CHAT_CHART_WIDTH_MIN));
|
||
assert.equal(readStoredChatChartWidth(memoryStorage({ [CHAT_CHART_WIDTH_STORAGE_KEY]: "nope" })), CHAT_CHART_WIDTH_DEFAULT);
|
||
});
|
||
|
||
// 原值:手机没有入口(`if (!ready || isMobile) return null`)
|
||
// 新值:手机有「看本命盘」按钮,点了才按需加载底部抽屉 chat-chart-sheet
|
||
// 原因:issue #114 Q8 后半句,产品 2026-10-27 同意「手机从底部拉起盘面」
|
||
test("the chat page loads the natal split only when the panel opens, and phones load a bottom sheet on demand", () => {
|
||
const page = readFileSync(new URL("../src/app/(app)/page.tsx", import.meta.url), "utf8");
|
||
const frame = readFileSync(new URL("../src/components/chat-chart-frame.tsx", import.meta.url), "utf8");
|
||
const split = readFileSync(new URL("../src/components/chat-chart-split.tsx", import.meta.url), "utf8");
|
||
assert.match(page, /<ChatChartToggle \/>/);
|
||
// 原值:`<ChatChartFrame>`
|
||
// 新值:`<ChatChartFrame switcher={subjectPicker}>`
|
||
// 原因:issue #150 第 5 条,盘面顶部放同一个人物切换
|
||
assert.match(page, /<ChatChartFrame switcher=\{subjectPicker\}>/);
|
||
assert.doesNotMatch(page, /react-resizable-panels|vedic-chart-svg|chat-chart-split/);
|
||
assert.match(frame, /打开本命盘/);
|
||
assert.match(frame, /收起本命盘/);
|
||
assert.match(frame, /if \(!ready\) return null/);
|
||
assert.match(frame, /看本命盘/);
|
||
assert.match(frame, /import\("@\/components\/chat-chart-sheet"\)/);
|
||
assert.match(frame, /import\("@\/components\/chat-chart-split"\)/);
|
||
// 原值:split 里要有 ResizablePanelGroup 和 collapsible
|
||
// 新值:split 用 useDragWidth,拖到最小以下调 onOpenChange(false) 收起
|
||
// 原因:组里只剩右栏一个面板时把手拖不动(BUG-1456);聊天列不能进组(BUG-1448),所以改成不依赖分组的把手
|
||
assert.match(split, /useDragWidth\(/);
|
||
assert.match(split, /onCollapse: \(\) => onOpenChange\(false\)/);
|
||
assert.doesNotMatch(split, /data-onboarding-draw/);
|
||
});
|