import test from 'node:test'; import assert from 'node:assert/strict'; import { visualChallenges, visualExhibits } from '../tools/visual-challenge-fixtures.mjs'; import { validateExhibit } from '../src/runtime/validator.js'; import { VisualEngine } from '../src/runtime/visual-engine.js'; import { ResolutionEngine } from '../src/runtime/resolution.js'; import { SeededRNG } from '../src/runtime/rng.js'; import { Script } from 'node:vm'; import { readFileSync } from 'node:fs'; import { buildVisualAcceptance } from '../tools/build-visual-acceptance.mjs'; for (const fixture of [...visualChallenges, ...visualExhibits]) test(`4g ${fixture.id}: validates, executes, draws, and reproduces across frame rates`, () => { assert.deepEqual(validateExhibit(fixture.document).errors, []); const run = cadence => { const rng = new SeededRNG(fixture.document.runtime.seed); const resolution = new ResolutionEngine(fixture.document, rng); const engine = new VisualEngine(fixture.document, { rng, resolution }); if (fixture.id === 'transient-impact') engine.spawn('burst'); let plan; for (let i = 0; i < 120; i++) { resolution.signals.set('signals.audio.energy', (Math.sin(i / 20) + 1) / 2); resolution.signals.set('signals.audio.low', (Math.cos(i / 30) + 1) / 2); resolution.advance(1000 / 60); engine.advance(1000 / 60); if (i % cadence === 0 || i === 119) plan = engine.planFrame({ width: 960, height: 540 }); } assert.equal(plan.deferred.length, 0); assert.ok(plan.layers.some(layer => layer.nodes.length > 0)); const finite = object => { if (typeof object === 'number') assert.ok(Number.isFinite(object)); else if (object && typeof object === 'object') for (const value of Object.values(object)) finite(value); }; finite(plan.layers); engine.dispose(); assert.equal(engine.instances.size, 0); assert.equal(resolution.automation.size, 0); return plan.layers; }; assert.deepEqual(run(1), run(4)); }); test('4g standalone acceptance build is deterministic, contains every fixture and parses as JavaScript', () => { const first = buildVisualAcceptance(), second = buildVisualAcceptance(); assert.equal(first.html, second.html); assert.equal(first.count, 18); const script = /