Files
leggenda-del-regolo/tests/verify.test.mjs
T

73 lines
4.8 KiB
JavaScript

// Le prove nel browser a sezioni (scripts/verify.mjs): ogni file del gioco finisce negli ingressi delle prove giuste,
// e l'impronta cambia solo se cambia un ingresso.
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { readdirSync } from 'node:fs';
import { SUITES, ENGINE, inputsOf, ignored, fingerprint, plan } from '../scripts/verify.mjs';
const FILES = ['index.html', 'style.css', 'src/main.js', 'src/version.js', 'package.json', 'package-lock.json', 'Makefile', 'README.md',
'src/engine/game.js', 'src/engine/render.js', 'src/engine/ambient.js', 'src/engine/bocce.js', 'src/engine/nuovo.js',
'src/engine/briscola.js', 'src/engine/briscola-render.js', 'src/engine/flipper.js', 'src/engine/corsa.js', 'src/story/piloti.js',
'src/story/story.js', 'src/story/solution.js', 'assets/scenes/piazza.png', 'assets/closeups/micro-parcheggio.png',
'assets/closeups/gp/boccino.png', 'assets/muro/index.html', 'assets/video/briscola.mp4', 'docs/BRISCOLA.md', 'docs/STATO.md',
'tests/helpers.mjs', 'tests/browser.mjs', 'tests/briscola.browser.mjs', 'tests/briscola.test.mjs', 'tests/story.test.mjs',
'scripts/verify.mjs', 'scripts/bump.sh', 'tools/slice_sprites.py', '.verify-ok.json'];
const suitesWith = path => Object.keys(SUITES).filter(n => inputsOf(n, FILES).includes(path));
const islands = Object.keys(SUITES).filter(n => !SUITES[n].core), cores = Object.keys(SUITES).filter(n => SUITES[n].core);
test('ogni prova nel browser di tests/ ha la sua voce, e una sola', () => {
const runs = Object.values(SUITES).map(s => s.run[0]);
for (const f of readdirSync('tests').filter(f => f.endsWith('.browser.mjs'))) {
if (f === 'multimedia.browser.mjs') continue; // la chiama la parte «telefoni» di browser.mjs
const n = runs.filter(r => r === `tests/${f}`).length;
assert.equal(n, f === 'browser.mjs' ? 3 : 1, `tests/${f} è in ${n} prove`);
}
});
test('la briscola si riprova solo se cambia la briscola o il motore', () => {
assert.deepEqual(suitesWith('src/engine/briscola.js'), ['briscola']);
assert.deepEqual(suitesWith('src/engine/briscola-render.js'), ['briscola']);
assert.deepEqual(suitesWith('assets/video/briscola.mp4'), ['briscola']);
assert.deepEqual(suitesWith('tests/briscola.browser.mjs'), ['briscola']);
assert.deepEqual(suitesWith('docs/BRISCOLA.md'), [], 'i documenti non fanno rifare niente');
assert.ok(!inputsOf('briscola', FILES).includes('src/story/story.js'), 'la storia non fa riprovare la briscola');
assert.deepEqual(suitesWith('src/engine/corsa.js'), ['gara']);
assert.deepEqual(suitesWith('src/story/piloti.js'), ['gara']);
assert.deepEqual(suitesWith('assets/closeups/gp/boccino.png'), ['gara']);
assert.deepEqual(suitesWith('assets/muro/index.html'), ['telefono']);
assert.deepEqual(suitesWith('assets/closeups/micro-parcheggio.png'), ['micro']);
});
test('la storia, le scene, i minigiochi dentro la partita e un modulo nuovo fanno rifare la partita intera, non i minigiochi a sé', () => {
for (const path of ['src/story/story.js', 'src/story/solution.js', 'assets/scenes/piazza.png', 'src/engine/bocce.js', 'src/engine/ambient.js', 'src/engine/nuovo.js', 'tests/browser.mjs']) {
assert.deepEqual(suitesWith(path), cores, path);
}
});
test('il motore comune fa rifare tutto', () => {
for (const path of ENGINE) assert.deepEqual(suitesWith(path), Object.keys(SUITES), path);
assert.ok(islands.length >= 10 && cores.length >= 3);
});
test('versione, package.json, Makefile, documenti, strumenti e test unitari non fanno rifare niente', () => {
for (const path of ['src/version.js', 'package.json', 'Makefile', 'README.md', 'docs/STATO.md', 'scripts/bump.sh', 'tools/slice_sprites.py', 'tests/briscola.test.mjs', 'tests/story.test.mjs', '.verify-ok.json']) {
assert.ok(ignored(path), `${path} dovrebbe essere ignorato`);
assert.deepEqual(suitesWith(path), [], path);
}
});
test("l'impronta cambia solo se cambia un ingresso, e il piano dice quali", () => {
const hashes = new Map(FILES.map(p => [p, 'h-' + p]));
const before = plan(hashes, {});
assert.ok(before.every(p => !p.green), 'mai provate: tutte da rifare');
const ok = Object.fromEntries(before.map(p => [p.name, { fingerprint: p.fp, hashes: Object.fromEntries(p.inputs.map(f => [f, hashes.get(f)])) }]));
assert.ok(plan(hashes, ok).every(p => p.green), 'niente cambiato: tutte verdi');
hashes.set('docs/STATO.md', 'altro');
assert.ok(plan(hashes, ok).every(p => p.green), 'un documento non cambia niente');
hashes.set('src/engine/briscola.js', 'altro');
const after = plan(hashes, ok);
assert.deepEqual(after.filter(p => !p.green).map(p => p.name), ['briscola']);
assert.deepEqual(after.find(p => p.name === 'briscola').changed, ['src/engine/briscola.js']);
assert.notEqual(fingerprint(['a'], () => '1'), fingerprint(['a'], () => '2'));
});