Files
2026-07-13 13:39:12 +08:00

198 lines
6.1 KiB
TypeScript

// tests/unit/build/check-pr-evidence.test.ts
// TDD tests for the evaluatePrBody() pure function in check-pr-evidence.mjs.
// Validates that the gate correctly detects outcome claims and evidence blocks.
import test from "node:test";
import assert from "node:assert/strict";
import { evaluatePrBody } from "../../../scripts/check/check-pr-evidence.mjs";
// ---------------------------------------------------------------------------
// (a) Body with claim + evidence block => PASS
// ---------------------------------------------------------------------------
test("evaluatePrBody: strong claim + fenced code block with test output => pass", () => {
const body = `
## Summary
Fixed the null-pointer bug.
All tests pass.
## Output
\`\`\`
42 passing (3s)
0 failing
\`\`\`
`;
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
test("evaluatePrBody: strong claim + inline result code span => pass", () => {
const body = "Typecheck is clean. Result: `42 passing`";
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
test("evaluatePrBody: strong claim + Evidence section header with content => pass", () => {
const body = `
Fixed the regression.
Validated locally.
## Evidence
node --import tsx/esm --test tests/unit/foo.test.ts
14 tests passed, 0 failed.
`;
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
test("evaluatePrBody: 'all green' claim + fenced block with PASS token => pass", () => {
const body = `
All tests are green.
\`\`\`
PASS src/foo.test.ts
Test Suites: 1 passed, 1 total
Tests: 5 passed, 5 total
\`\`\`
`;
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
test("evaluatePrBody: two weak triggers + fenced code block with output => pass", () => {
const body = `
Added a new endpoint for health checks.
Resolves #123.
\`\`\`
npm run test
14 passing (1s)
\`\`\`
`;
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
// ---------------------------------------------------------------------------
// (b) Body with claim + NO evidence block => FAIL
// ---------------------------------------------------------------------------
test("evaluatePrBody: 'all tests pass' with no evidence => fail", () => {
const body = "Fixed the bug. All tests pass and I added a new endpoint.";
const { result, reason } = evaluatePrBody(body);
assert.equal(result, "fail");
assert.ok(reason.includes("Rule #18"), `reason should mention Rule #18, got: ${reason}`);
});
test("evaluatePrBody: 'typecheck is clean' with no evidence => fail", () => {
const body = "Refactored the module. Typecheck pass and lint is clean.";
const { result } = evaluatePrBody(body);
assert.equal(result, "fail");
});
test("evaluatePrBody: 'tests passing' + fenced block with no output-like content => fail", () => {
const body = `
Tests are passing!
\`\`\`ts
// just a code snippet, not output
export function foo() { return 42; }
\`\`\`
`;
const { result } = evaluatePrBody(body);
assert.equal(result, "fail");
});
test("evaluatePrBody: two weak triggers + no evidence => fail", () => {
const body = "Fixed the issue. Resolves #456. Looks good to me.";
const { result } = evaluatePrBody(body);
assert.equal(result, "fail");
});
test("evaluatePrBody: 'validated on VPS' with no evidence block => fail", () => {
const body = "Validated on VPS. Everything works correctly.";
const { result } = evaluatePrBody(body);
assert.equal(result, "fail");
});
// ---------------------------------------------------------------------------
// (c) Body with no claim terms => PASS
// ---------------------------------------------------------------------------
test("evaluatePrBody: body without any claim terms => pass", () => {
const body = `
## Summary
Update the README with new provider list.
Adds documentation for the new streaming format.
`;
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
test("evaluatePrBody: body with only one weak trigger => pass (not enough to fire)", () => {
const body = "Resolves #789 by updating the config file.";
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
test("evaluatePrBody: body describing a pure docs change with no claims => pass", () => {
const body = "Updates ARCHITECTURE.md to reflect the new combo routing design.";
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
// ---------------------------------------------------------------------------
// (d) Empty/missing body => SKIP (or pass — no blocking)
// ---------------------------------------------------------------------------
test("evaluatePrBody: empty string => skip", () => {
const { result } = evaluatePrBody("");
assert.equal(result, "skip");
});
test("evaluatePrBody: whitespace-only string => skip", () => {
const { result } = evaluatePrBody(" \n \t ");
assert.equal(result, "skip");
});
test("evaluatePrBody: undefined body => skip (treat as empty)", () => {
// @ts-expect-error — testing defensive path
const { result } = evaluatePrBody(undefined);
assert.equal(result, "skip");
});
// ---------------------------------------------------------------------------
// Edge cases
// ---------------------------------------------------------------------------
test("evaluatePrBody: fenced block with exit-code output => pass (strong trigger present)", () => {
const body = `
Fixes the build. Zero errors after this change.
\`\`\`
$ npm run typecheck
exit code 0
\`\`\`
`;
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
test("evaluatePrBody: evidence section header present but with minimal content => pass (strong trigger)", () => {
// "Validated locally" is a strong trigger. Evidence section has 25+ chars.
const body = `
Validated locally on the production VPS.
## Validation
Ran the full test suite and observed 0 failures from the terminal.
`;
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});
test("evaluatePrBody: inline PASSED span counts as evidence", () => {
const body = "All tests pass. Result: `PASSED 14 tests`";
const { result } = evaluatePrBody(body);
assert.equal(result, "pass");
});