新增 useThemePreference hook 和纯工具函数,支持系统/明亮/黑暗三态主题选择、 matchMedia 系统主题跟随、localStorage 持久化和启动期主题预应用,通过 <html theme-mode> 驱动 TDesign 主题变量切换。 Header 右侧控件重新组织为 .dashboard-header-controls 单行桌面布局,主题 RadioGroup 位于刷新频率 RadioGroup 前。 附带:build.ts import specifier 改为跨平台 sep 转换;config-loader 测试适配 Windows PATH 和 YAML 路径转义;test-utils 类型窄化修复。
52 lines
1.9 KiB
TypeScript
52 lines
1.9 KiB
TypeScript
import { mock } from "bun:test";
|
|
|
|
// Note: jsdom and polyfills are now set up in tests/setup.ts
|
|
// This file only contains component-specific mocks
|
|
|
|
// Mock recharts BEFORE any component imports
|
|
void mock.module("recharts", () => ({
|
|
Area: () => null,
|
|
CartesianGrid: () => null,
|
|
Line: () => null,
|
|
LineChart: ({ children }: { children: unknown }) => children,
|
|
ResponsiveContainer: ({ children }: { children: unknown }) => children,
|
|
Tooltip: () => null,
|
|
XAxis: () => null,
|
|
YAxis: () => null,
|
|
}));
|
|
|
|
// Custom test helpers (替代 jest-dom matchers)
|
|
export const testHelpers = {
|
|
toBeInTheDocument: (element: Element | null) => {
|
|
const pass = element !== null && document.contains(element);
|
|
return {
|
|
message: () => (pass ? "Expected element not to be in document" : "Expected element to be in document"),
|
|
pass,
|
|
};
|
|
},
|
|
toHaveAttribute: (element: Element | null, attr: string, value?: string) => {
|
|
const pass = value === undefined ? (element?.hasAttribute(attr) ?? false) : element?.getAttribute(attr) === value;
|
|
return {
|
|
message: () =>
|
|
pass ? `Expected element not to have attribute "${attr}"` : `Expected element to have attribute "${attr}"`,
|
|
pass,
|
|
};
|
|
},
|
|
toHaveClass: (element: Element | null, className: string) => {
|
|
const pass = element?.classList.contains(className) ?? false;
|
|
return {
|
|
message: () =>
|
|
pass ? `Expected element not to have class "${className}"` : `Expected element to have class "${className}"`,
|
|
pass,
|
|
};
|
|
},
|
|
toHaveTextContent: (element: Element | null, text: RegExp | string) => {
|
|
const content = element?.textContent ?? "";
|
|
const pass = element !== null && (typeof text === "string" ? content.includes(text) : text.test(content));
|
|
return {
|
|
message: () => (pass ? `Expected element not to have text "${text}"` : `Expected element to have text "${text}"`),
|
|
pass,
|
|
};
|
|
},
|
|
};
|