fix: 支持 selftest case selector

This commit is contained in:
lyon
2026-06-19 23:46:12 +08:00
parent af6067f387
commit 798a604449
+52 -12
View File
@@ -5,24 +5,64 @@ import { createSelfTestContext, type SelfTestCase, type SelfTestResult } from ".
const root = path.resolve(import.meta.dirname, "../..");
const casesDir = path.join(root, "src/selftest/cases");
const context = await createSelfTestContext(root);
const args = process.argv.slice(2);
const listOnly = args.includes("--list");
const helpRequested = args.some((arg) => arg === "--help" || arg === "-h");
const requestedCases = args.filter((arg) => arg !== "--list" && arg !== "--help" && arg !== "-h");
function caseName(file: string): string {
return file.replace(/\.ts$/u, "");
}
function normalizeSelector(value: string): string {
return caseName(path.basename(value));
}
try {
const caseFiles = (await readdir(casesDir))
.filter((file) => file.endsWith(".ts") && !file.endsWith(".d.ts"))
.sort();
const results: SelfTestResult[] = [];
const availableCases = caseFiles.map(caseName);
for (const file of caseFiles) {
const moduleUrl = pathToFileURL(path.join(casesDir, file)).href;
const imported = await import(moduleUrl) as { default?: SelfTestCase; selfTest?: SelfTestCase };
const selfTest = imported.default ?? imported.selfTest;
if (typeof selfTest !== "function") throw new Error(`self-test case ${file} must export default or selfTest function`);
const result = await selfTest(context);
results.push({ name: result.name ?? file.replace(/\.ts$/u, ""), tests: result.tests ?? [] });
if (helpRequested) {
console.log(JSON.stringify({ ok: true, usage: "bun run src/selftest/run.ts [--list] [case ...]", availableCases }));
process.exit(0);
}
console.log(JSON.stringify({ ok: true, cases: results, tests: results.flatMap((result) => result.tests) }));
} finally {
await context.cleanup();
if (listOnly) {
console.log(JSON.stringify({ ok: true, cases: availableCases }));
process.exit(0);
}
const requestedSet = new Set(requestedCases.map(normalizeSelector));
const selectedCaseFiles = requestedSet.size === 0
? caseFiles
: caseFiles.filter((file) => requestedSet.has(caseName(file)));
const missingCases = [...requestedSet].filter((name) => !availableCases.includes(name));
if (missingCases.length > 0) {
console.error(JSON.stringify({ ok: false, error: "unknown-selftest-case", requestedCases: [...requestedSet], missingCases, availableCases }));
process.exit(1);
}
const context = await createSelfTestContext(root);
const results: SelfTestResult[] = [];
try {
for (const file of selectedCaseFiles) {
const moduleUrl = pathToFileURL(path.join(casesDir, file)).href;
const imported = await import(moduleUrl) as { default?: SelfTestCase; selfTest?: SelfTestCase };
const selfTest = imported.default ?? imported.selfTest;
if (typeof selfTest !== "function") throw new Error(`self-test case ${file} must export default or selfTest function`);
const result = await selfTest(context);
results.push({ name: result.name ?? caseName(file), tests: result.tests ?? [] });
}
} finally {
await context.cleanup();
}
console.log(JSON.stringify({ ok: true, selectedCases: selectedCaseFiles.map(caseName), cases: results, tests: results.flatMap((result) => result.tests) }));
} catch (error) {
console.error(JSON.stringify({ ok: false, error: error instanceof Error ? error.message : String(error) }));
process.exit(1);
}