#!/usr/bin/env node /** * PR-1 Freeze Architecture Test * * Run: node --test test/architecture/freeze.test.mjs * * Tests: * 1. architecture-freeze-v2.md exists * 2. Document contains core/adapter/legacy/experimental sections * 3. Document contains 90-day legacy policy * 4. check-deprecations output includes replacement info * 5. check-deprecations output includes migration window * 6. production-check still passes * 7. guard still passes * 8. baseline still passes */ import { describe, it } from "node:test"; import assert from "node:assert"; import { existsSync, readFileSync, statSync } from "node:fs"; import { join } from "node:path"; import { execSync, spawnSync } from "node:child_process"; import { fileURLToPath } from "node:url"; const __dirname = join(fileURLToPath(import.meta.url), "..", "..", ".."); const ROOT = __dirname; const SCRIPTS = join(ROOT, "scripts"); const DOCS = join(ROOT, "docs"); // ─── Helpers ────────────────────────────────────────── function getFileSize(path) { try { return statSync(path).size; } catch { return 0; } } describe("PR-1: Freeze Architecture", () => { // ─── Test 1 ────────────────────────────────────────── it("architecture-freeze-v2.md exists and is non-empty", () => { const path = join(DOCS, "architecture-freeze-v2.md"); assert.ok(existsSync(path), `Missing: ${path}`); const size = getFileSize(path); assert.ok(size > 1000, `File too small: ${size} bytes (expected >1000)`); }); // ─── Test 2 ────────────────────────────────────────── it("document contains core / adapter / legacy / experimental sections", () => { const content = readFileSync(join(DOCS, "architecture-freeze-v2.md"), "utf8"); const required = [ "Core Module", "Adapter Module", "Legacy Module", "Experimental Module", ]; for (const section of required) { assert.ok(content.includes(section), `Missing section: "${section}"`); } }); // ─── Test 3 ────────────────────────────────────────── it("document contains 90-day legacy migration policy", () => { const content = readFileSync(join(DOCS, "architecture-freeze-v2.md"), "utf8"); assert.ok(content.includes("90-day") || content.includes("90-Day") || content.includes("90 day") || content.includes("Migration Window"), "Missing 90-day migration policy reference"); assert.ok(content.includes("2026-09-04"), "Missing removal target date 2026-09-04"); }); // ─── Test 4 ────────────────────────────────────────── it("check-deprecations output includes replacement info", { timeout: 30000 }, () => { const result = spawnSync("node", [join(SCRIPTS, "check-deprecations.mjs")], { cwd: ROOT, encoding: "utf8", timeout: 25000, maxBuffer: 1024 * 1024, }); const output = result.stdout + result.stderr; console.log(output.slice(-1000)); // Deprecation check always exits 0 (never blocks on deprecation count) assert.equal(result.status, 0, `Script crashed (exit ${result.status})`); // Must contain replacement info in enhanced output assert.ok( output.includes("Replacement:") || output.includes("replacement"), "Missing replacement info in deprecation output" ); }); // ─── Test 5 ────────────────────────────────────────── it("check-deprecations output includes migration window", { timeout: 30000 }, () => { const result = spawnSync("node", [join(SCRIPTS, "check-deprecations.mjs")], { cwd: ROOT, encoding: "utf8", timeout: 25000, maxBuffer: 1024 * 1024, }); const output = result.stdout + result.stderr; // Must contain migration window assert.ok( output.includes("Migration Window") || output.includes("migrationWindow") || output.includes("Migration Timeline") || output.includes("Removal Target"), "Missing migration window info in deprecation output" ); }); // ─── Test 6 ────────────────────────────────────────── it("production-check still passes after freeze", { timeout: 120000 }, () => { const result = spawnSync("bash", [join(SCRIPTS, "production-check.sh")], { cwd: ROOT, encoding: "utf8", timeout: 110000, maxBuffer: 2 * 1024 * 1024, }); const output = result.stdout + result.stderr; console.log(output.slice(-800)); assert.equal(result.status, 0, `Production check failed after freeze (exit ${result.status}):\n${output.slice(-500)}`); assert.ok(output.includes("PRODUCTION CHECK PASSED") || output.includes("Overall:"), "Production check summary not found"); }); // ─── Test 7 ────────────────────────────────────────── it("architecture guard still passes after freeze", { timeout: 60000 }, () => { const result = spawnSync("bash", [join(SCRIPTS, "guard-all.sh")], { cwd: ROOT, encoding: "utf8", timeout: 55000, maxBuffer: 1024 * 1024, }); const output = result.stdout + result.stderr; console.log(output.slice(-500)); assert.equal(result.status, 0, `Guard failed after freeze (exit ${result.status}):\n${output.slice(-300)}`); }); // ─── Test 8 ────────────────────────────────────────── it("baseline tests still pass after freeze", { timeout: 60000 }, () => { const result = spawnSync("node", ["--test", "test/baseline/test-*.test.mjs"], { cwd: ROOT, encoding: "utf8", timeout: 55000, maxBuffer: 2 * 1024 * 1024, shell: true, }); const output = result.stdout + result.stderr; assert.equal(result.status, 0, `Baseline tests failed after freeze (exit ${result.status})`); assert.ok(output.includes("fail 0") || !output.includes("fail"), "Baseline tests have failures"); }); });