Files
pbakaus_impeccable/tests/ci-test-plan.test.mjs
T
Paul Bakaus b6a34de55a Tests: gate behavior on the oracle and the engine binary
Unit tests of the deleted Node scripts and the JS detector are removed;
their behavior is pinned by tests/oracle goldens (frozen JS behavior plus
reviewed deltas) and the engine's own tests. tests/oracle.test.mjs replays
the corpus against the binary (IMPECCABLE_BIN or skill/scripts/bin/<target>/,
via tests/lib/engine-bin.mjs) and skips cleanly without one; the framework
fixture sweep drives live-inject, live-wrap, and detect-csp through the
binary the same way. record.mjs learns --bin. The function-level vectors
under tests/oracle/vectors/calls are committed as the frozen snapshot they
can no longer be regenerated from. Suites: core trimmed to build and
transformer tests, oracle added to the default run, detector/live reduced to
packaging and reference checks, the live-e2e helper tests move to the opt-in
live-e2e lane pending its retarget, cli-remote-e2e is an empty placeholder.

Prepared with AI assistance (Claude Code).
2026-08-31 19:59:20 -07:00

138 lines
4.8 KiB
JavaScript

import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { spawnSync } from 'node:child_process';
import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
const SCRIPT = 'scripts/ci-test-plan.mjs';
describe('ci-test-plan', () => {
it('keeps docs-only pull requests on the core suite', () => {
const outputs = runPlan({
GITHUB_EVENT_NAME: 'pull_request',
CI_CHANGED_FILES: 'README.md',
});
assert.equal(outputs.core, 'true');
assert.equal(outputs.detector, 'false');
assert.equal(outputs.live, 'false');
assert.equal(outputs.framework, 'false');
assert.equal(outputs.live_e2e, 'false');
assert.equal(outputs.live_e2e_accept_cleanup, 'false');
assert.equal(outputs.live_svelte_adapter_deepseek, 'false');
});
it('routes extension changes to detector tests only', () => {
const outputs = runPlan({
GITHUB_EVENT_NAME: 'pull_request',
CI_CHANGED_FILES: 'extension/manifest.json',
});
assert.equal(outputs.detector, 'true');
assert.equal(outputs.live, 'false');
assert.equal(outputs.framework, 'false');
});
it('routes an engine version bump to every binary-driven lane', () => {
const outputs = runPlan({
GITHUB_EVENT_NAME: 'pull_request',
CI_CHANGED_FILES: 'ENGINE_VERSION',
});
assert.equal(outputs.framework, 'true');
assert.equal(outputs.live_e2e, 'true');
assert.equal(outputs.live_e2e_accept_cleanup, 'true');
assert.equal(outputs.live_svelte_adapter_deepseek, 'true');
assert.equal(outputs.detector, 'false');
});
it('routes skill setup changes to the skill behavior lane', () => {
const outputs = runPlan({
GITHUB_EVENT_NAME: 'pull_request',
CI_CHANGED_FILES: 'skill/SKILL.src.md',
});
assert.equal(outputs.skill_behavior, 'true');
assert.equal(outputs.detector, 'false');
assert.equal(outputs.live, 'false');
});
it('forces deterministic suites on push without forcing opt-in E2E suites', () => {
const outputs = runPlan({
GITHUB_EVENT_NAME: 'push',
CI_CHANGED_FILES: 'README.md',
});
assert.equal(outputs.core, 'true');
assert.equal(outputs.detector, 'true');
assert.equal(outputs.live, 'true');
assert.equal(outputs.framework, 'true');
assert.equal(outputs.cli_remote_e2e, 'false');
assert.equal(outputs.live_e2e, 'false');
assert.equal(outputs.live_e2e_accept_cleanup, 'false');
assert.equal(outputs.live_svelte_adapter_deepseek, 'false');
});
it('enables remote smoke suites on manual dispatch', () => {
const outputs = runPlan({
GITHUB_EVENT_NAME: 'workflow_dispatch',
CI_CHANGED_FILES: 'README.md',
});
assert.equal(outputs.cli_remote_e2e, 'true');
assert.equal(outputs.live_e2e, 'true');
assert.equal(outputs.live_e2e_accept_cleanup, 'true');
assert.equal(outputs.skill_behavior, 'true');
assert.equal(outputs.live_svelte_adapter_deepseek, 'true');
});
it('exposes planned opt-in suite outputs to workflow jobs', () => {
const workflow = readFileSync('.github/workflows/ci.yml', 'utf-8');
assert.match(workflow, /live_e2e_accept_cleanup:\s*\$\{\{\s*steps\.plan\.outputs\.live_e2e_accept_cleanup\s*\}\}/);
assert.match(workflow, /live_svelte_adapter_deepseek:\s*\$\{\{\s*steps\.plan\.outputs\.live_svelte_adapter_deepseek\s*\}\}/);
assert.match(workflow, /live-e2e-accept-cleanup:/);
assert.match(workflow, /live-svelte-adapter-deepseek:/);
});
it('schedule events run only the deterministic suites plus the full live-e2e matrix', () => {
const outputs = runPlan({ GITHUB_EVENT_NAME: 'schedule' });
assert.equal(outputs.live_e2e, 'true');
assert.equal(outputs.live_e2e_accept_cleanup, 'false');
assert.equal(outputs.skill_behavior, 'false');
assert.equal(outputs.live_svelte_adapter_deepseek, 'false');
assert.equal(outputs.cli_remote_e2e, 'false');
assert.equal(outputs.core, 'true');
assert.equal(outputs.detector, 'true');
assert.equal(outputs.live, 'true');
assert.equal(outputs.framework, 'true');
});
});
function runPlan(env) {
const tmp = mkdtempSync(join(tmpdir(), 'impeccable-ci-plan-'));
const outputPath = join(tmp, 'github-output');
try {
const result = spawnSync(process.execPath, [SCRIPT], {
cwd: process.cwd(),
encoding: 'utf-8',
env: {
...process.env,
GITHUB_OUTPUT: outputPath,
...env,
},
});
assert.equal(result.status, 0, result.stderr || result.stdout);
return Object.fromEntries(
readFileSync(outputPath, 'utf-8')
.trim()
.split(/\r?\n/)
.filter(Boolean)
.map((line) => line.split('=')),
);
} finally {
rmSync(tmp, { recursive: true, force: true });
}
}