文件
hyb-oa/scripts/qa/tests/check-minimal-profile.test.mjs
wangsli 5dac336fbf
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s
修复移动验收门禁漂移(07-27-yang-jun-reimbursement-readiness)
2026-08-01 16:28:14 +08:00

107 行
4.0 KiB
JavaScript

import assert from "node:assert/strict";
import {
chmodSync,
existsSync,
mkdtempSync,
mkdirSync,
readFileSync,
rmSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { spawnSync } from "node:child_process";
import test from "node:test";
const repoRoot = path.resolve(new URL("../../..", import.meta.url).pathname);
const sourceScript = path.join(repoRoot, "scripts/check-minimal.sh");
const localCandidateRunner = path.join(repoRoot, "scripts/qa/run-local-candidate.sh");
function writeExecutable(file, source) {
mkdirSync(path.dirname(file), { recursive: true });
writeFileSync(file, source, "utf8");
chmodSync(file, 0o755);
}
test("local-candidate 基础 profile 在没有 issues 目录时不调用历史 CSV 门禁", () => {
const fixtureRoot = mkdtempSync(path.join(tmpdir(), "hyb-local-candidate-profile-"));
try {
const scriptSource = readFileSync(sourceScript, "utf8");
const fixtureScript = path.join(fixtureRoot, "scripts/check-minimal.sh");
writeExecutable(fixtureScript, scriptSource);
mkdirSync(path.join(fixtureRoot, "server"), { recursive: true });
mkdirSync(path.join(fixtureRoot, "client"), { recursive: true });
for (const match of scriptSource.matchAll(/^\s*bash(?: -n)? ([^\s]+)/gmu)) {
const relativeFile = match[1];
for (const base of [fixtureRoot, path.join(fixtureRoot, "server")]) {
const file = path.join(base, relativeFile);
mkdirSync(path.dirname(file), { recursive: true });
writeFileSync(file, "#!/usr/bin/env bash\n", "utf8");
}
}
const binDir = path.join(fixtureRoot, "bin");
const commandLog = path.join(fixtureRoot, "commands.log");
writeExecutable(path.join(binDir, "node"), `#!/usr/bin/env bash
printf 'node %s\\n' "$*" >> "$CHECK_MINIMAL_COMMAND_LOG"
if [[ "$*" == *check-process-contract.mjs* ]]; then exit 91; fi
exit 0
`);
writeExecutable(path.join(binDir, "npm"), `#!/usr/bin/env bash
printf 'npm %s\\n' "$*" >> "$CHECK_MINIMAL_COMMAND_LOG"
exit 0
`);
writeExecutable(path.join(binDir, "python3"), `#!/usr/bin/env bash
printf 'python3 %s\\n' "$*" >> "$CHECK_MINIMAL_COMMAND_LOG"
exit 92
`);
const result = spawnSync("bash", [fixtureScript, "local-candidate"], {
cwd: fixtureRoot,
encoding: "utf8",
env: {
...process.env,
PATH: `${binDir}:${process.env.PATH ?? ""}`,
CHECK_MINIMAL_COMMAND_LOG: commandLog,
},
});
assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
const commands = readFileSync(commandLog, "utf8");
assert.doesNotMatch(commands, /check-process-contract|validate-feature-matrix|python3/u);
assert.equal(existsSync(path.join(fixtureRoot, "issues")), false);
} finally {
rmSync(fixtureRoot, { recursive: true, force: true });
}
});
test("local-candidate 结果标签严格区分 full、focused 与 list", () => {
const source = readFileSync(localCandidateRunner, "utf8");
const blockStart = source.lastIndexOf('if [[ "$MODE" == "full" ]]; then');
const blockEnd = source.indexOf("\nfi", blockStart);
assert.notEqual(blockStart, -1, "缺少 full/focused 结果标签分支");
assert.notEqual(blockEnd, -1, "full/focused 结果标签分支不完整");
const resultLabelBlock = source.slice(blockStart, blockEnd + "\nfi".length);
const runLabelBlock = (mode) => spawnSync("bash", ["-c", resultLabelBlock], {
encoding: "utf8",
env: { ...process.env, MODE: mode },
});
const full = runLabelBlock("full");
const focused = runLabelBlock("focused");
assert.equal(full.status, 0, full.stderr);
assert.match(full.stdout, /LOCAL_CANDIDATE_PASS/u);
assert.doesNotMatch(full.stdout, /FOCUSED_BROWSER_PASS/u);
assert.equal(focused.status, 0, focused.stderr);
assert.match(focused.stdout, /FOCUSED_BROWSER_PASS/u);
assert.doesNotMatch(focused.stdout, /LOCAL_CANDIDATE_PASS/u);
assert.equal(source.match(/LOCAL_CANDIDATE_PASS/gu)?.length, 1);
assert.match(
source,
/if \[\[ "\$MODE" == "list" \]\]; then[\s\S]*?LIST_ONLY[\s\S]*?exit 0[\s\S]*?\nfi/u,
);
});