-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathproject-verify.test.ts
More file actions
97 lines (85 loc) · 4.47 KB
/
project-verify.test.ts
File metadata and controls
97 lines (85 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/**
* Purpose: Lock the maintainer npm verification facade so queue/release gates do not silently drop required checks.
* Responsibilities: Assert `npm run verify` orchestration keeps docs drift, typecheck, unit/fake tests, command-reference, real-upstream, and package Pi smoke steps wired to their focused scripts.
* Scope: Unit coverage for scripts/project.mjs command planning only; the focused scripts own their own runtime behavior.
* Usage: Runs under `npm test` via tsx's test runner.
* Invariants/Assumptions: The default gate is local and deterministic except for live command-reference sampling; real-upstream and packaged Pi smoke stay explicit opt-in modes.
*/
import assert from "node:assert/strict";
import test from "node:test";
// @ts-expect-error scripts/project.mjs is an executable ESM maintainer script without a .d.ts surface.
const projectModule = (await import("../scripts/project.mjs")) as {
docsSteps: (options: { mode: string; target: string }) => Array<{ command: string; args: string[]; env?: Record<string, string> }>;
parseVerifyArgs: (argv?: string[]) => { mode: string; passthrough: string[]; showHelp: boolean };
verifySteps: (options: { mode: string; passthrough: string[]; showHelp: boolean }) => Array<{ command: string; args: string[]; env?: Record<string, string> }>;
};
const { docsSteps, parseVerifyArgs, verifySteps } = projectModule;
function labels(steps: Array<{ args: string[]; env?: Record<string, string> }>): string[] {
return steps.map((step) => step.args.join(" "));
}
test("verify facade default gate keeps docs, typecheck, unit/fake, and command-reference drift checks", () => {
const steps = verifySteps({ mode: "default", passthrough: [], showHelp: false });
const stepLabels = labels(steps);
assert.deepEqual(stepLabels, [
"./scripts/check-playbook-drift.ts --check",
"--noEmit",
"--test test/**/*.test.ts",
"./scripts/check-command-reference-baseline.mjs --check",
"./scripts/verify-command-reference.mjs",
]);
});
test("verify facade opt-in modes keep real-upstream and package-pi gates explicit", () => {
const realUpstream = verifySteps({ mode: "real-upstream", passthrough: [], showHelp: false });
assert.deepEqual(labels(realUpstream), ["--test test/agent-browser.real-upstream-contract.test.ts"]);
assert.equal(realUpstream[0]?.env?.PI_AGENT_BROWSER_REAL_UPSTREAM, "1");
const packagePi = verifySteps({ mode: "package-pi", passthrough: [], showHelp: false });
assert.deepEqual(labels(packagePi), ["./scripts/verify-package.mjs --smoke-pi"]);
});
test("verify facade release gate composes default verification and packaged Pi smoke", () => {
const release = verifySteps({ mode: "release", passthrough: [], showHelp: false });
assert.deepEqual(labels(release), [
"./scripts/check-playbook-drift.ts --check",
"--noEmit",
"--test test/**/*.test.ts",
"./scripts/check-command-reference-baseline.mjs --check",
"./scripts/verify-command-reference.mjs",
"./scripts/verify-package.mjs --smoke-pi",
]);
});
test("verify facade docs mode checks both generated playbook and command-reference blocks", () => {
assert.deepEqual(labels(docsSteps({ mode: "check", target: "all" })), [
"./scripts/check-playbook-drift.ts --check",
"./scripts/check-command-reference-baseline.mjs --check",
]);
});
test("verify facade rejects unsupported options before running a partial gate", () => {
assert.throws(
() => verifySteps({ mode: "real-upstream", passthrough: ["--list-files"], showHelp: false }),
/Option --list-files is not supported for verify mode real-upstream/,
);
assert.deepEqual(parseVerifyArgs(["package", "--list-files"]), {
mode: "package",
passthrough: ["--list-files"],
showHelp: false,
});
});
test("verify facade lifecycle mode passes --model and other allowed flags through to verify-lifecycle.mjs", () => {
const steps = verifySteps({
mode: "lifecycle",
passthrough: ["--model", "openai-codex/gpt-5.5:minimal", "--keep-artifacts", "--verbose", "--timeout-ms", "600000"],
showHelp: false,
});
assert.deepEqual(labels(steps), [
"./scripts/verify-lifecycle.mjs --model openai-codex/gpt-5.5:minimal --keep-artifacts --verbose --timeout-ms 600000",
]);
});
test("verify facade lifecycle mode rejects --model without a value", () => {
assert.throws(
() => verifySteps({ mode: "lifecycle", passthrough: ["--model"], showHelp: false }),
/--model requires a value/,
);
assert.throws(
() => verifySteps({ mode: "lifecycle", passthrough: ["--model", "--keep-artifacts"], showHelp: false }),
/--model requires a value/,
);
});