financial_system/frontend/tests/reportsViewLayout.test.ts
2026-06-23 09:13:13 +08:00

88 lines
3.2 KiB
TypeScript

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 view = readFileSync(join(process.cwd(), "src/views/ReportsView.vue"), "utf-8");
const css = readFileSync(join(process.cwd(), "src/assets/styles.css"), "utf-8");
assertIncludes(view, "report-page");
assertIncludes(view, "report-ledger-workspace");
assertIncludes(view, "工资明细台账");
assertIncludes(view, "report-ledger-toolbar");
assertIncludes(view, "report-ledger-totals");
assertIncludes(view, "report-inline-metrics");
assertIncludes(view, "report-detail-grid");
assertIncludes(view, "report-record-panel");
assertIncludes(view, "最近工资明细");
assertNotIncludes(view, "<section class=\"stats-grid\">");
assertNotIncludes(view, "StatCard");
assertNotIncludes(view, "report-summary-panel");
assertNotIncludes(view, "report-metric-card");
assertNotIncludes(view, "先看明细再看拆分");
assertNotIncludes(view, "汇总金额和最近工资明细");
assertBefore(view, "report-ledger-workspace", "report-detail-grid");
assertBefore(view, "最近工资明细", "report-detail-grid");
assertIncludes(css, ".report-ledger-workspace");
assertIncludes(css, ".report-ledger-toolbar");
assertIncludes(css, ".report-ledger-totals");
assertIncludes(css, ".report-inline-metrics");
assertIncludes(css, ".report-record-panel");
assertIncludes(css, ".report-detail-grid");
assertNotIncludes(css, ".report-summary-panel");
assertNotIncludes(css, ".report-metric-card");
const ledgerToolbarBlock = cssBlock(".report-ledger-toolbar");
assertIncludes(ledgerToolbarBlock, "padding: 10px var(--panel-padding) 8px;");
const totalItemBlock = cssBlock(".report-total-item");
assertIncludes(totalItemBlock, "min-height: 52px;");
const inlineMetricsBlock = cssBlock(".report-inline-metrics");
assertIncludes(inlineMetricsBlock, "padding: 7px var(--panel-padding);");
const tableHeadingBlock = cssBlock(".report-table-heading");
assertIncludes(tableHeadingBlock, "padding: 9px var(--panel-padding) 6px;");
function assertIncludes(content: string, expected: string): void {
if (!content.includes(expected)) {
throw new Error(`期望包含 ${expected}`);
}
}
function assertNotIncludes(content: string, unexpected: string): void {
if (content.includes(unexpected)) {
throw new Error(`不应包含 ${unexpected}`);
}
}
function assertBefore(content: string, earlier: string, later: string): void {
const earlierIndex = content.indexOf(earlier);
const laterIndex = content.indexOf(later);
if (earlierIndex === -1 || laterIndex === -1 || earlierIndex >= laterIndex) {
throw new Error(`期望 ${earlier} 出现在 ${later} 之前`);
}
}
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 escapeRegExp(value: string): string {
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}