Skip to content

Commit cada990

Browse files
Prithvi-Webclaude
andcommitted
test(map): the History diff's wash is pinned to the diff - History played back without it, or a diff flag left on the live map, paints and exports exactly what the live map does, each label judged on its cushion alone (review F3.2)
Every node /api/snapshots/tree serves carries a prevSize, so a History view with Diff off holds folders that grew and shrank, and only the guard in tmDiffWashes keeps their 30% wash off the canvas, out of the SVG export and out of the ink and the cushion's ease. Every History paint the suite ran was {active, diff}, so dropping either half of the guard left it green. The two new tests paint and export the same prevSize'd maps under {active, no diff} and {no History, diff} and compare them with the live map as it holds them - the same tiles in the same colours with no prevSize - after checking that the History diff does wash them. The diff map and the export's tiles are shared helpers now; paint() also hands back the pxRects. Mutants (bqg1/mut4/results-f32.txt, all RED, restored by SHA-256): the guard without its diff half, without its History half, never washing; the label judged through a wash the guard did not lay; the cushion eased for one; the export laying unguarded washes; a paint that keeps no cushion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent a8b7aca commit cada990

1 file changed

Lines changed: 88 additions & 17 deletions

File tree

‎tests/mapColourPop.test.ts‎

Lines changed: 88 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ function paint(tiles: Tile[], colour: (n: Tile) => RGB = (n) => ramp.sizeRgb(n.s
238238
rec.texts.length = 0;
239239
rec.ops.length = 0;
240240
draw();
241-
return rec;
241+
return Object.assign(rec, { px: state.treemap.pxRects });
242242
}
243243

244244
/** A leaf `h` px tall at `depth`, coloured by `bytes`, in its own column of the map. */
@@ -707,17 +707,13 @@ const PREV: Record<string, (size: number) => number | null> = {
707707
unchanged: (s) => s, grew: (s) => s / 4, shrank: (s) => s * 4, new: () => null,
708708
};
709709

710-
test('G09: in the History diff, a label in a folder that grew, shrank or is new reaches 4.5:1 on its tile as the folder\'s wash leaves it — mid-folder, below the folder\'s tag, and under two washes', () => {
711-
// Pass 2.5 lays a 30% wash of the folder's own diff colour over every
712-
// expanded folder that changed, its leaves included, after pass 1 painted
713-
// them and before pass 4 writes their labels — so a label is read on its
714-
// cushion seen through that wash, not on the cushion alone. Chosen against
715-
// the cushion alone, the unchanged grey leaf in the corner of a folder
716-
// that grew took white at 4.64:1 and measured 3.67:1 under the teal wash
717-
// (review F2.1). What is measured here is the canvas itself: every fill
718-
// over the label's top and foot, replayed in the order it was drawn.
719-
// Two washes of one colour too: under red › red the grey leaf below the
720-
// tag reads at 4.5:1 only where its cushion eases for the washed colour.
710+
/**
711+
* A History map with every diff colour: folders that grew, shrank, are new
712+
* or are unchanged — alone and one inside another — each holding one leaf of
713+
* every kind, in the folder's corner below its tag and clear of it, at every
714+
* label height. Each node carries the prevSize the diff is drawn from.
715+
*/
716+
function diffMap() {
721717
const folderSets = [['grew'], ['shrank'], ['new'], ['unchanged'], ['grew', 'shrank'], ['shrank', 'grew'], ['shrank', 'shrank'], ['grew', 'grew']];
722718
const heights = [15, 18, 22, 27, 31, 36, 40, 44, 48, 53, 56, 60, 65, 68, 71, 74, 77, 87, 110, 126, 170];
723719
const nodes: Tile[] = [];
@@ -733,6 +729,21 @@ test('G09: in the History diff, a label in a folder that grew, shrank or is new
733729
x: ((x + 2) / MAP_W) * 100, y: ((y + off) / MAP_H) * 100, w: (96 / MAP_W) * 100, h: (h / MAP_H) * 100 } as Tile);
734730
slots.push({ what: `${folders.join(' › ')} folder, ${kind} leaf, ${corner ? 'below the tag' : 'mid-folder'}, ${h} px`, x: x + 2, y });
735731
}
732+
return { nodes, slots };
733+
}
734+
735+
test('G09: in the History diff, a label in a folder that grew, shrank or is new reaches 4.5:1 on its tile as the folder\'s wash leaves it — mid-folder, below the folder\'s tag, and under two washes', () => {
736+
// Pass 2.5 lays a 30% wash of the folder's own diff colour over every
737+
// expanded folder that changed, its leaves included, after pass 1 painted
738+
// them and before pass 4 writes their labels — so a label is read on its
739+
// cushion seen through that wash, not on the cushion alone. Chosen against
740+
// the cushion alone, the unchanged grey leaf in the corner of a folder
741+
// that grew took white at 4.64:1 and measured 3.67:1 under the teal wash
742+
// (review F2.1). What is measured here is the canvas itself: every fill
743+
// over the label's top and foot, replayed in the order it was drawn.
744+
// Two washes of one colour too: under red › red the grey leaf below the
745+
// tag reads at 4.5:1 only where its cushion eases for the washed colour.
746+
const { nodes, slots } = diffMap();
736747
const rec = paint(nodes, (n) => DIFF_PAGE.diffRgb(n), { active: true, diff: true });
737748
const whatAt = (t: Text) => slots.find((s) => Math.abs(t.x - (s.x + 5)) < 0.01 && t.y >= s.y && t.y < s.y + 210)!.what;
738749
const washed = [0, 0, 0];
@@ -749,6 +760,45 @@ test('G09: in the History diff, a label in a folder that grew, shrank or is new
749760
`labels were measured with no wash (${washed[0]}), one (${washed[1]}) and two (${washed[2]}) over them`);
750761
});
751762

763+
/** The flat fills laid over the map after its ground: the History diff's washes, and nothing else the painter fills flat. */
764+
const washesOn = (rec: ReturnType<typeof paint>) => rec.ops.slice(1)
765+
.filter((op): op is Extract<Op, { kind: 'rect' }> => op.kind === 'rect' && typeof op.style === 'string')
766+
.map((op) => `${op.rect.map((v) => v.toFixed(1)).join(' ')} ${String(op.style)}`);
767+
/** Outside the diff the map is drawn as the live map is: History played back without it, or a diff flag left on after it. */
768+
const NOT_THE_DIFF = [{ active: true, diff: false }, { active: false, diff: true }];
769+
/** `nodes` as the live map holds them: no earlier size, so nothing a wash could be drawn from. */
770+
const withoutPrev = (nodes: Tile[]) => nodes.map((n) => Object.fromEntries(Object.entries(n).filter(([k]) => k !== 'prevSize')) as Tile);
771+
/** Each node's History diff colour, fixed by its path so that it outlives withoutPrev. */
772+
function colourOf(nodes: Tile[]): (n: Tile) => RGB {
773+
const byPath = new Map(nodes.map((n) => [n.path, DIFF_PAGE.diffRgb(n)]));
774+
return (n) => byPath.get(n.path)!;
775+
}
776+
777+
test('G09: the History diff\'s wash is laid only while the diff is on — History played back without it, or a diff flag left over on the live map, paints what the live map paints, each label judged on its cushion alone', () => {
778+
// Every node /api/snapshots/tree serves carries a prevSize, so a History
779+
// view with Diff off holds folders that grew and shrank; only the guard in
780+
// tmDiffWashes keeps their wash off the map, out of the ink and out of the
781+
// cushion's ease. Every History paint the suite ran was {active, diff}, so
782+
// dropping either half of that guard left it green (review F3.2).
783+
// The reference is the same map as the live map holds it — no prevSize,
784+
// each tile in the same colour — so a wash drawn from prevSize anywhere,
785+
// in any mode, shows as a difference.
786+
const { nodes } = diffMap();
787+
const colour = colourOf(nodes);
788+
assert.ok(washesOn(paint(nodes, colour, { active: true, diff: true })).length > 100,
789+
'in the History diff these folders are washed — the map below is one a wash would land on');
790+
const live = JSON.stringify(paint(withoutPrev(nodes), colour, { active: false, diff: false }).ops);
791+
for (const history of NOT_THE_DIFF) {
792+
const where = `history ${JSON.stringify(history)}`;
793+
const rec = paint(nodes, colour, history);
794+
assert.deepEqual(washesOn(rec), [], `${where}: no wash is laid over any folder`);
795+
const leaves = rec.px.filter((r) => r.stops);
796+
assert.ok(leaves.length > 500, `${where}: the leaves were painted (${leaves.length})`);
797+
for (const r of leaves) assert.deepEqual(r.seen, r.stops, `${where}: ${r.n.name}'s label is judged on the cushion painted, through no wash`);
798+
assert.ok(JSON.stringify(rec.ops) === live, `${where}: every cushion, label and ink is the one the live map paints`);
799+
}
800+
});
801+
752802
/* ══════════════ G01/G09 — the SVG export is the map's own recipe ══════════════ */
753803

754804
/**
@@ -913,19 +963,24 @@ function svgLines(svg: string, ground: RGB) {
913963
return out;
914964
}
915965

916-
test('G09: the SVG export lays the History diff\'s wash over each folder that grew or shrank, as the canvas does, and its labels read 4.5:1 through it', () => {
917-
// The canvas picks a label's ink against the cushion seen through its
918-
// folder's wash (review F2.1); an export that left the wash out would
919-
// write that ink on a tile it was not chosen for, and lose the diff.
966+
/** Three folders — one grew, one shrank, one did not change — each holding leaves, with the prevSize the diff is drawn from. */
967+
function svgDiffTiles(): Tile[] {
920968
const leaf = (name: string, x: number, y: number, h: number, kind: string): Tile => ({ name, path: `/r/${name}`, size: 5e9, prevSize: PREV[kind](5e9),
921969
type: 'file', depth: 2, expanded: false, x, y, w: 9.6, h: h / 10 } as Tile);
922970
const folder = (name: string, x: number, y: number, kind: string): Tile => ({ name, path: `/r/${name}`, size: 2e10, prevSize: PREV[kind](2e10),
923971
type: 'dir', depth: 1, expanded: true, x, y, w: 40, h: 40 } as Tile);
924-
const tiles = [
972+
return [
925973
folder('Projects', 0, 0, 'grew'), leaf('keep.bin', 0.2, 0.2, 40, 'unchanged'), leaf('mid.bin', 0.2, 10, 68, 'unchanged'),
926974
folder('Old', 50, 0, 'shrank'), leaf('grew.bin', 50.2, 0.2, 60, 'grew'), leaf('same.bin', 50.2, 10, 68, 'unchanged'),
927975
folder('Same', 0, 50, 'unchanged'), leaf('here.bin', 0.2, 50.2, 60, 'unchanged'),
928976
];
977+
}
978+
979+
test('G09: the SVG export lays the History diff\'s wash over each folder that grew or shrank, as the canvas does, and its labels read 4.5:1 through it', () => {
980+
// The canvas picks a label's ink against the cushion seen through its
981+
// folder's wash (review F2.1); an export that left the wash out would
982+
// write that ink on a tile it was not chosen for, and lose the diff.
983+
const tiles = svgDiffTiles();
929984
const { svg, rec } = exportSvg(tiles, (n) => DIFF_PAGE.diffRgb(n), '#0e0e13', { active: true, diff: true });
930985
const box = (r: number[]) => r.map((v) => v.toFixed(1)).join(' ');
931986
const onCanvas = rec.ops.slice(1).filter((op): op is Extract<Op, { kind: 'rect' }> => op.kind === 'rect' && typeof op.style === 'string')
@@ -943,6 +998,22 @@ test('G09: the SVG export lays the History diff\'s wash over each folder that gr
943998
}
944999
});
9451000

1001+
test('G09: the SVG export lays the History diff\'s wash only while the diff is on — exported from History without it, or with a diff flag left over on the live map, it is the live map\'s own export', () => {
1002+
// The export lays each wash tmDiffWashes names (review F2.1), so the same
1003+
// guard keeps it out of an export made outside the diff (review F3.2).
1004+
const colour = colourOf(svgDiffTiles());
1005+
const washesIn = (svg: string) => [...svg.matchAll(/<rect ([^>]*)\/>/g)].map((m) => attrs(m[1])).filter((a) => 'fill-opacity' in a);
1006+
assert.equal(washesIn(exportSvg(svgDiffTiles(), colour, '#0e0e13', { active: true, diff: true }).svg).length, 2,
1007+
'in the History diff the export washes the two folders that changed');
1008+
const live = exportSvg(withoutPrev(svgDiffTiles()), colour, '#0e0e13', { active: false, diff: false }).svg;
1009+
for (const history of NOT_THE_DIFF) {
1010+
const where = `history ${JSON.stringify(history)}`;
1011+
const { svg } = exportSvg(svgDiffTiles(), colour, '#0e0e13', history);
1012+
assert.deepEqual(washesIn(svg), [], `${where}: the export lays no wash`);
1013+
assert.ok(svg === live, `${where}: the export is the live map's own, rectangle by rectangle and label by label`);
1014+
}
1015+
});
1016+
9461017
test('G09/G27: the SVG export draws a cloud placeholder hollow and a staged block as an amber dashed outline, as the map does — neither as a cushion — and labels the hollow tile at 4.5:1', () => {
9471018
// Every SVG test exported plain leaves, so the export's two other leaf
9481019
// branches ran under no test: an opaque cloud, a solid one, an undashed

0 commit comments

Comments
 (0)