mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
test: prove the drift gate itself can fail (#422)
User-Visible: no Issue: #422
This commit is contained in:
@@ -956,6 +956,30 @@ const MUTANT_DEFINITIONS = [
|
||||
replace: '',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'capture-gate-forgives-a-missing-frame',
|
||||
guard: 'node --test test/capture-determinism-gate.test.mjs',
|
||||
because: 'comparing only the frames both runs happen to have lets a run that '
|
||||
+ 'produced nine frames pass against a run that produced ten — «совпало» then '
|
||||
+ 'means nothing, which is the opposite of what the gate is for (#422)',
|
||||
patches: [{
|
||||
file: 'scripts/capture-determinism.mjs',
|
||||
find: ' const names = [...new Set([...Object.keys(first), ...Object.keys(second)])].sort();',
|
||||
replace: ' const names = Object.keys(first).filter((name) => name in second).sort();',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'capture-gate-hashes-everything-in-the-folder',
|
||||
guard: 'node --test test/capture-determinism-gate.test.mjs',
|
||||
because: 'hashing every file in docs/images drags the manifest into the comparison, '
|
||||
+ 'and the manifest legitimately changes between runs — the gate would then cry '
|
||||
+ 'wolf on every capture and be switched off within a week (#422)',
|
||||
patches: [{
|
||||
file: 'scripts/capture-determinism.mjs',
|
||||
find: " if (!name.endsWith('.png')) continue;\n",
|
||||
replace: '',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'capture-drifts-between-runs',
|
||||
guard: 'node --test test/capture-clip.test.mjs',
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
import { driftBetweenRuns, frameHashes } from '../scripts/capture-determinism.mjs';
|
||||
|
||||
// #422. Гейт сравнивает два прогона съёмки. Его собственная логика должна
|
||||
// уметь падать не меньше, чем то, что он охраняет: разошедшийся кадр, кадр
|
||||
// пропавший и кадр появившийся — всё это расхождения, потому что набор обязан
|
||||
// быть одним и тем же, иначе «совпало» ничего не значит.
|
||||
|
||||
const files = { 'a.png': 'AAA', 'b.png': 'BBB', 'notes.txt': 'ignore me' };
|
||||
const fakeList = () => Object.keys(files);
|
||||
const fakeRead = (path) => Buffer.from(files[path.split('/').pop()]);
|
||||
|
||||
test('хешируются только кадры, посторонние файлы не участвуют', () => {
|
||||
const hashes = frameHashes('/nowhere', fakeRead, fakeList);
|
||||
assert.deepEqual(Object.keys(hashes), ['a.png', 'b.png']);
|
||||
assert.match(hashes['a.png'], /^[0-9a-f]{64}$/);
|
||||
assert.notEqual(hashes['a.png'], hashes['b.png']);
|
||||
});
|
||||
|
||||
test('одинаковые прогоны расхождений не дают', () => {
|
||||
const first = frameHashes('/nowhere', fakeRead, fakeList);
|
||||
assert.deepEqual(driftBetweenRuns(first, { ...first }), []);
|
||||
});
|
||||
|
||||
test('разошедшийся кадр назван по имени', () => {
|
||||
const drift = driftBetweenRuns({ 'a.png': '1', 'b.png': '2' }, { 'a.png': '1', 'b.png': '9' });
|
||||
assert.deepEqual(drift.map((item) => item.name), ['b.png']);
|
||||
assert.equal(drift[0].first, '2');
|
||||
assert.equal(drift[0].second, '9');
|
||||
});
|
||||
|
||||
test('пропавший и появившийся кадр — тоже расхождение', () => {
|
||||
const lost = driftBetweenRuns({ 'a.png': '1', 'b.png': '2' }, { 'a.png': '1' });
|
||||
assert.deepEqual(lost.map((item) => item.name), ['b.png']);
|
||||
assert.equal(lost[0].second, '(нет кадра)');
|
||||
|
||||
const appeared = driftBetweenRuns({ 'a.png': '1' }, { 'a.png': '1', 'c.png': '3' });
|
||||
assert.deepEqual(appeared.map((item) => item.name), ['c.png']);
|
||||
assert.equal(appeared[0].first, '(нет кадра)');
|
||||
});
|
||||
|
||||
test('расхождения перечисляются в устойчивом порядке', () => {
|
||||
const drift = driftBetweenRuns(
|
||||
{ 'c.png': '1', 'a.png': '1', 'b.png': '1' },
|
||||
{ 'c.png': '9', 'a.png': '9', 'b.png': '9' },
|
||||
);
|
||||
assert.deepEqual(drift.map((item) => item.name), ['a.png', 'b.png', 'c.png']);
|
||||
});
|
||||
Reference in New Issue
Block a user