fix: preserve wall thickness across partial resize

Issue: #253
User-Visible: yes
This commit is contained in:
Sergey Matyunin
2026-08-23 11:42:43 +03:00
parent 9d6a4e34fd
commit bfdeb493cb
16 changed files with 656 additions and 236 deletions
+28
View File
@@ -177,6 +177,34 @@ export const MUTANTS = [
replace: ' const span = centre;',
}],
},
{
id: 'resize-wall-partial-overlap-not-split',
guard: 'npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs '
+ '&& node --test --test-name-pattern="issue 253 splits a longer exact wall" '
+ 'test/wall-thickness.test.mjs',
because: 'a room edge may cover only part of a longer thickness record; omitting the overlap '
+ 'boundaries recreates #253 by leaving the entire record behind instead of moving one atom',
patches: [{
file: 'src/wall-thickness.ts',
find: ' const bounds = [0, 1, ...overlaps.flatMap(({ lo, hi }) => [lo, hi])]',
replace: ' const bounds = [0, 1]',
}],
},
{
id: 'resize-wall-key-collision-drops-record',
guard: 'npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs '
+ '&& node --test --test-name-pattern="key collisions never erase" '
+ 'test/wall-thickness.test.mjs',
because: 'compatibility keys identify a quantised midpoint, not an exact interval; treating '
+ 'them as unique silently deletes different thickness records, the second half of #253',
patches: [{
file: 'src/wall-thickness.ts',
find: ' const duplicate = exactOut.some((candidate) => candidate.entry.cm === value\n'
+ ' && closePoint(candidate.span[0], ca) && closePoint(candidate.span[1], cb));',
replace: ' const duplicate = exactOut.some((candidate) =>\n'
+ ' candidate.entry.key === keyOf(ca, cb, pitch, scale));',
}],
},
{
id: 'unit-formatting-escapes-the-formatter',
guard: 'node --test --test-name-pattern="детектор действительно ловит" '
+12
View File
@@ -27,6 +27,18 @@
/** @type {SmokeLink[]} */
export const SMOKE_LINKS = [
{
// #253: the pure interval transformer is invoked inside the resize preview;
// the smoke can observe only the resulting wall records and rendered body.
symbols: [
'rekeyWallsAfterMove', 'WallEntry', 'angleClose', 'clampWallCm',
'closePoint', 'distToSeg', 'keyOf', 'pointAt', 'segAngle', 'wallDir', 'wallEntry',
],
smokes: ['smoke_resize_wall_thickness.mjs'],
because: 'the real pointer-handler smoke proves that a partial overlap is split losslessly '
+ 'through live preview, commit, opening movement and Undo, but the browser bundle does '
+ 'not expose the pure transformer name to the scenario',
},
{
// #244: pure repair/validation helpers are bundled behind editor actions;
// the smoke observes their persisted candidate and rendered explanations.