financial_system/frontend/tests/datePickerUnification.test.ts
2026-06-29 14:59:49 +08:00

89 lines
3.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

declare const process: { cwd(): string };
declare function require(name: string): {
readFileSync?: (path: string, encoding: string) => string;
join?: (...parts: string[]) => string;
};
const { readFileSync } = require("node:fs");
const { join } = require("node:path");
if (!readFileSync || !join) {
throw new Error("测试运行环境缺少文件读取能力");
}
const root = process.cwd();
const component = readFileSync(join(root, "src/components/DatePicker.vue"), "utf-8");
const css = readFileSync(join(root, "src/assets/styles.css"), "utf-8");
const datePages = [
"CommissionsView.vue",
"MonthlyPayrollView.vue",
"PayrollView.vue",
"RealtimeAttendanceView.vue",
"ReportsView.vue",
"SalaryProfilesView.vue",
];
for (const page of datePages) {
const content = readFileSync(join(root, "src/views", page), "utf-8");
assertIncludes(content, "DatePicker", `${page} 应使用统一 DatePicker 组件`);
assertNotIncludes(content, "type=\"month\"", `${page} 不应再使用浏览器原生月份选择器`);
assertNotIncludes(content, "type=\"date\"", `${page} 不应再使用浏览器原生日期选择器`);
}
assertIncludes(component, 'mode: "month" | "date"');
assertIncludes(component, "date-picker-panel");
assertIncludes(component, "<Teleport to=\"body\">", "日期面板应挂到 body避免被父级面板裁剪");
assertIncludes(component, "panelRef", "日期面板应独立追踪自身节点,保证弹层内部点击不会被当成外部点击");
assertIncludes(component, "panelStyle", "日期面板应使用运行时坐标定位到触发按钮附近");
assertIncludes(component, "updatePanelPosition", "日期面板打开、滚动或窗口变化时应重新定位");
assertIncludes(component, "month-grid");
assertIncludes(component, "calendar-grid");
assertIncludes(component, "emit(\"change\"");
assertIncludes(component, "本月");
assertIncludes(component, "今天");
const pickerBlock = cssBlock(".date-picker");
assertIncludes(pickerBlock, "position: relative;");
const triggerBlock = cssBlock(".date-picker-trigger");
assertIncludes(triggerBlock, "min-height: var(--control-height);");
assertIncludes(triggerBlock, "border: 1px solid var(--line);");
const panelBlock = cssBlock(".date-picker-panel");
assertIncludes(panelBlock, "position: fixed;");
assertIncludes(panelBlock, "max-height: min(420px, calc(100vh - 24px));");
assertIncludes(panelBlock, "overflow: auto;");
assertIncludes(panelBlock, "box-shadow: var(--shadow);");
const monthGridBlock = cssBlock(".month-grid");
assertIncludes(monthGridBlock, "grid-template-columns: repeat(4, minmax(0, 1fr));");
const calendarGridBlock = cssBlock(".calendar-grid");
assertIncludes(calendarGridBlock, "grid-template-columns: repeat(7, minmax(0, 1fr));");
function cssBlock(selector: string): string {
const pattern = new RegExp(`${escapeRegExp(selector)}\\s*\\{([\\s\\S]*?)\\n\\}`, "m");
const match = css.match(pattern);
if (!match) {
throw new Error(`缺少样式块 ${selector}`);
}
return match[1];
}
function assertIncludes(content: string, expected: string, message?: string): void {
if (!content.includes(expected)) {
throw new Error(message || `期望包含 ${expected}`);
}
}
function assertNotIncludes(content: string, unexpected: string, message?: string): void {
if (content.includes(unexpected)) {
throw new Error(message || `不应包含 ${unexpected}`);
}
}
function escapeRegExp(value: string): string {
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}