43 lines
1.9 KiB
JavaScript
43 lines
1.9 KiB
JavaScript
// The prepare step must be a cache, never a parallel pipeline: a song rebuilt
|
|
// from a prepared artifact has to produce a world bit-identical to one analysed
|
|
// from the WAV, for every frame.
|
|
|
|
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync } from 'node:fs';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { resolve, dirname } from 'node:path';
|
|
import { loadSong } from '../tools/load.js';
|
|
import { serializeSong, deserializeSong } from '../src/song/serialize.js';
|
|
import { Run } from '../src/film.js';
|
|
|
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
const BANK = resolve(HERE, '../..', 'flow-state/test/songs');
|
|
|
|
test('prepared song is bit-identical to the live WAV path', () => {
|
|
for (const name of ['drone', 'runner', 'dusk']) {
|
|
const { song, analysis } = loadSong(resolve(BANK, `${name}.wav`), { fps: 30, seed: 12345 });
|
|
const artifact = serializeSong(song);
|
|
const rebuilt = deserializeSong(artifact);
|
|
|
|
assert.equal(rebuilt.seed, song.seed);
|
|
assert.equal(rebuilt.name, song.name);
|
|
assert.deepEqual(rebuilt.summary, song.summary);
|
|
assert.equal(rebuilt.events.length, song.events.length);
|
|
assert.equal(rebuilt.laws.length, song.laws.length);
|
|
|
|
const frames = [0, 31, 217, 1200, 3599];
|
|
const a = new Run(song, { fps: 30, width: 480, height: 270, seed: 12345, field: 64, genesis: 0 }).renderAt(frames);
|
|
const b = new Run(rebuilt, { fps: 30, width: 480, height: 270, seed: 12345, field: 64, genesis: 0 }).renderAt(frames);
|
|
|
|
for (const f of frames) {
|
|
const pa = a.get(f).data;
|
|
const pb = b.get(f).data;
|
|
assert.equal(pa.length, pb.length, `${name} frame ${f} size`);
|
|
for (let i = 0; i < pa.length; i++) {
|
|
assert.equal(pa[i], pb[i], `${name} frame ${f} pixel ${i}: live=${pa[i]} prepared=${pb[i]}`);
|
|
}
|
|
}
|
|
}
|
|
});
|