39bfcd2032
Task 3 of Plan 02-03: ship the PIPE-02 structural assertion that Season-1
content reaches the build output. Three structural checks (any one
sufficient): chunk filename slug match (fragments / season1 / 01-soil),
chunk-contents reference to /content/seasons/01-soil/ source path or to
known fragment ids, and a future-extension hook for index.html manifest
inspection.
Phase 2 ships eager-corpus loading alongside the lazy
loadSeasonFragments surface, so currently chunkContentMatch=true via
inlined ?raw content. When Plan 02-04+ switches consumers to lazy-only
and Vite emits a separate Season-1 chunk, chunkNameMatch will also
start passing — at which point either path satisfies the assertion. The
plumbing is structurally proven now; the chunk-naming side is documented
as the path of least resistance for the Phase-4 Season-2 onboarding.
scripts/check-bundle-split.mjs:
- Refactored body into export function runCheck() returning a structured
result; the CLI invocation guard wraps process.exit so Vitest can
import the module without termination (verified by the test file).
scripts/check-bundle-split.test.mjs:
- 3 cases: file exists, parses + imports without process.exit firing,
runCheck() returns the documented {ok, message, chunkNameMatch,
chunkContentMatch, files} shape. The on-disk dist/-required happy path
fires via the package.json scripts.ci chain (`npm run build &&
npm run check:bundle-split`).
package.json:
- New `check:bundle-split` script.
- `ci` chain extended: lint → test → validate:assets → build →
check:bundle-split. dist/ is populated by build before the bundle-split
assertion runs.
`npm run ci` exits 0 end-to-end. 217/217 tests green (was 214; +3 new
this task). The PIPE-02 verification step now refuses any future change
that breaks the lazy-content plumbing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
51 lines
2.1 KiB
JavaScript
51 lines
2.1 KiB
JavaScript
// scripts/check-bundle-split.test.mjs
|
|
//
|
|
// Phase 2 Plan 02-03 Task 3 — Vitest cover for the PIPE-02 verifier.
|
|
//
|
|
// The exhaustive structural assertion fires during `npm run ci` AFTER
|
|
// `npm run build` populates dist/. This Vitest file proves three smaller
|
|
// things that don't require the dist/ to exist:
|
|
//
|
|
// 1. The script file is present and non-empty.
|
|
// 2. The script parses + imports cleanly under Node ESM (no
|
|
// module-eval-time process.exit; the CLI guard is correctly
|
|
// wrapped so Vitest can import without termination).
|
|
// 3. The exported runCheck() returns a structured result with the
|
|
// documented shape — ok / message / chunkNameMatch /
|
|
// chunkContentMatch / files.
|
|
//
|
|
// The dev / CI happy-path (build → script exits 0) is exercised via the
|
|
// package.json scripts.ci chain: `npm run build && npm run check:bundle-split`.
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import { existsSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
|
|
const scriptPath = resolve(process.cwd(), 'scripts/check-bundle-split.mjs');
|
|
|
|
describe('scripts/check-bundle-split.mjs', () => {
|
|
it('exists and is non-empty', () => {
|
|
expect(existsSync(scriptPath)).toBe(true);
|
|
});
|
|
|
|
it('parses + imports without triggering process.exit (CLI guard works)', async () => {
|
|
// If the CLI guard is broken, this `await import` would call process.exit
|
|
// and Vitest's worker would terminate — the test would fail to report.
|
|
const mod = await import(scriptPath);
|
|
expect(typeof mod.runCheck).toBe('function');
|
|
});
|
|
|
|
it('runCheck() returns a structured result with the documented shape', async () => {
|
|
const { runCheck } = await import(scriptPath);
|
|
const result = runCheck();
|
|
expect(result).toHaveProperty('ok');
|
|
expect(result).toHaveProperty('message');
|
|
expect(result).toHaveProperty('chunkNameMatch');
|
|
expect(result).toHaveProperty('chunkContentMatch');
|
|
expect(result).toHaveProperty('files');
|
|
expect(typeof result.ok).toBe('boolean');
|
|
expect(typeof result.message).toBe('string');
|
|
expect(Array.isArray(result.files)).toBe(true);
|
|
});
|
|
});
|