测试里的类型标注补全。侧栏拖宽把手改用组件库按钮,样子仍是 6px 透明细条。报告列表换人时不再在渲染中改引用。删掉已经没人用的证据回执类名。 Co-Authored-By: Grok (agent loop)
86 lines
3.2 KiB
TypeScript
86 lines
3.2 KiB
TypeScript
import "./install-test-document";
|
|
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { useEffect } from "react";
|
|
|
|
import { ChatChartFrame } from "../src/components/chat-chart-frame.tsx";
|
|
import { ShellFrame } from "../src/components/shell-frame.tsx";
|
|
import { SidebarProvider } from "../src/components/ui/sidebar.tsx";
|
|
import { useUiStore } from "../src/stores/ui-store.ts";
|
|
import { createClientLifecycleHarness } from "./react-client-lifecycle-test-support.ts";
|
|
|
|
function watchMount(record: { mount: number; unmount: number }) {
|
|
record.mount += 1;
|
|
return () => {
|
|
record.unmount += 1;
|
|
};
|
|
}
|
|
|
|
function Probe({ record }: { record: { mount: number; unmount: number } }) {
|
|
useEffect(() => watchMount(record), [record]);
|
|
return <span>probe</span>;
|
|
}
|
|
|
|
function listenForResize(win: Window) {
|
|
const buckets = new Map<string, Set<EventListener>>();
|
|
win.addEventListener = ((type: string, listener: EventListener) => {
|
|
const set = buckets.get(type) ?? new Set<EventListener>();
|
|
set.add(listener);
|
|
buckets.set(type, set);
|
|
}) as Window["addEventListener"];
|
|
win.removeEventListener = ((type: string, listener: EventListener) => {
|
|
buckets.get(type)?.delete(listener);
|
|
}) as Window["removeEventListener"];
|
|
win.dispatchEvent = ((event: Event) => {
|
|
for (const listener of buckets.get(event.type) ?? []) listener(event);
|
|
return true;
|
|
}) as Window["dispatchEvent"];
|
|
}
|
|
|
|
test("the shell and the chat column stay mounted when the desktop split arrives", async () => {
|
|
const sidebar = { mount: 0, unmount: 0 };
|
|
const column = { mount: 0, unmount: 0 };
|
|
const harness = createClientLifecycleHarness();
|
|
listenForResize(globalThis.window);
|
|
const win = globalThis.window as Window & { innerWidth: number };
|
|
try {
|
|
await harness.render(
|
|
<SidebarProvider>
|
|
<ShellFrame sidebar={<Probe record={sidebar} />}>
|
|
<ChatChartFrame>
|
|
<Probe record={column} />
|
|
</ChatChartFrame>
|
|
</ShellFrame>
|
|
</SidebarProvider>,
|
|
);
|
|
await harness.idle();
|
|
assert.equal(sidebar.mount, 1, "sidebar mounted once before the split");
|
|
assert.equal(sidebar.unmount, 0, "sidebar unmounted before the split");
|
|
assert.equal(column.mount, 1, "chat column mounted once before the split");
|
|
assert.equal(column.unmount, 0, "chat column unmounted before the split");
|
|
|
|
await harness.update(() => {
|
|
win.innerWidth = 500;
|
|
win.dispatchEvent(new Event("resize"));
|
|
});
|
|
await harness.idle();
|
|
await harness.update(() => {
|
|
win.innerWidth = 1440;
|
|
win.dispatchEvent(new Event("resize"));
|
|
});
|
|
await harness.idle();
|
|
await harness.update(() => {
|
|
useUiStore.getState().setChatChartOpen(true);
|
|
});
|
|
for (let attempt = 0; attempt < 8; attempt += 1) await harness.idle();
|
|
|
|
assert.equal(sidebar.mount, 1, "sidebar mounted once across the breakpoint");
|
|
assert.equal(sidebar.unmount, 0, "sidebar unmounted across the breakpoint");
|
|
assert.equal(column.mount, 1, "chat column mounted once when the chart split arrived");
|
|
assert.equal(column.unmount, 0, "chat column unmounted when the chart split arrived");
|
|
assert.equal(harness.errors.length, 0, harness.errors.map(String).join("\n"));
|
|
} finally {
|
|
await harness.close();
|
|
}
|
|
});
|