mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
Путь чистого пола строят четыре места рендера, а площадь читают только подсказка комнаты и PDF. cleanFloorForRoom больше не вычитает лестницы при построении пути: площадь считается при первом чтении и хранится в том же закэшированном объекте. geometryMinusStairs передаёт в polyclip только контуры лестниц, чей габарит пересекает вычитаемую геометрию, — результат тот же, а комната на этаже с 250 лестницами больше не прогоняет все 250. Issue: #669 User-Visible: no Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
77 lines
3.1 KiB
JavaScript
77 lines
3.1 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
|
|
import { cleanFloorForRoom } from '../test-build/clean-floor.js';
|
|
import { geometryAreaMinusStairs } from '../test-build/stairs.js';
|
|
|
|
// #669: the four render paths read only `path`; the room tooltip and the PDF
|
|
// read `area`. The stair subtraction behind `area` must wait for that read.
|
|
const floor = [[100, 100], [500, 100], [500, 500], [100, 500]];
|
|
const room = { id: 'room-a' };
|
|
const stair = {
|
|
id: 'stair-a', kind: 'straight', x: 0.3, y: 0.3, angle: 0,
|
|
direction: 'forward', length: 0.1, width: 0.05, target_space_id: 'upper',
|
|
};
|
|
const column = [[400, 400], [440, 400], [440, 440], [400, 440]];
|
|
const space = { id: 'space-a', rooms: [room], stairs: [stair] };
|
|
|
|
const counting = () => {
|
|
const calls = { count: 0 };
|
|
const areaMinusStairs = (source, stairs) => {
|
|
calls.count += 1;
|
|
return geometryAreaMinusStairs(source, stairs);
|
|
};
|
|
return { calls, areaMinusStairs };
|
|
};
|
|
|
|
const build = (overrides = {}) => cleanFloorForRoom({
|
|
room, floor, space, configEpoch: 3, resizePreview: false, cache: new Map(),
|
|
physicalBodies: () => [column], ...overrides,
|
|
});
|
|
|
|
test('#669 AC1 a floor path does not subtract stairs until the area is read', () => {
|
|
const { calls, areaMinusStairs } = counting();
|
|
const cache = new Map();
|
|
const result = build({ cache, areaMinusStairs });
|
|
assert.ok(result.path.length > 0, 'the path is built from the floor minus the column');
|
|
assert.equal(calls.count, 0, 'building the path must not run the stair subtraction');
|
|
|
|
const area = result.area;
|
|
assert.equal(calls.count, 1, 'the first read subtracts once');
|
|
assert.equal(result.area, area);
|
|
assert.equal(calls.count, 1, 'a second read reuses the value');
|
|
|
|
const again = build({ cache, areaMinusStairs });
|
|
assert.equal(again, result, 'the cached result is returned');
|
|
assert.equal(again.area, area);
|
|
assert.equal(calls.count, 1, 'a cache hit does not subtract again');
|
|
});
|
|
|
|
test('#669 AC1 the lazy area equals the eager subtraction and still removes stairs', () => {
|
|
const result = build();
|
|
const expected = geometryAreaMinusStairs(result.geom, space.stairs);
|
|
assert.ok(Math.abs(result.area - expected) <= expected * 1e-9);
|
|
const withoutStairs = build({ space: { ...space, stairs: [] } }).area;
|
|
assert.ok(result.area < withoutStairs - 1, 'the stair footprint is subtracted');
|
|
});
|
|
|
|
test('#669 AC1 the resize preview is not cached and stays lazy', () => {
|
|
const { calls, areaMinusStairs } = counting();
|
|
const cache = new Map();
|
|
const preview = build({ cache, resizePreview: true, areaMinusStairs });
|
|
assert.equal(cache.size, 0);
|
|
assert.equal(calls.count, 0);
|
|
assert.ok(preview.area > 0);
|
|
assert.equal(calls.count, 1);
|
|
});
|
|
|
|
test('#669 AC1 a room without independent bodies subtracts stairs from the plain floor', () => {
|
|
const { calls, areaMinusStairs } = counting();
|
|
const result = build({ physicalBodies: () => [], areaMinusStairs });
|
|
assert.equal(result.geom, null);
|
|
assert.equal(calls.count, 0);
|
|
const plain = geometryAreaMinusStairs([[[...floor, floor[0]]]], space.stairs);
|
|
assert.ok(Math.abs(result.area - plain) <= plain * 1e-9);
|
|
assert.equal(calls.count, 1);
|
|
});
|