mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-06 22:49:16 +00:00
committed by
claude[bot]
parent
b860ef4c43
commit
087f7cf381
@@ -66,6 +66,12 @@ test('golden matrix has stable unique ids and bounded comparison thresholds', ()
|
||||
assert.equal(scenario.mode, 'plan', scenario.id);
|
||||
assert.equal(scenario.capture, 'page', scenario.id);
|
||||
}
|
||||
if (scenario.wallJunctionPreview) {
|
||||
assert.equal(scenario.wallJunctions, true, scenario.id);
|
||||
assert.equal(scenario.mode, 'plan', scenario.id);
|
||||
assert.equal(scenario.capture, 'page', scenario.id);
|
||||
assert.ok(scenario.wallJunctionPreview.path.length >= 1, scenario.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -78,7 +84,7 @@ test('golden matrix covers required geometry, rendering and adaptive surfaces',
|
||||
'backup-full', 'backup-space', 'value-badge-positions', 'isometric-geometry',
|
||||
'isometric-live-layers', 'isometric-no-borders', 'isometric-touch-kiosk',
|
||||
'isometric-large-warm-remount', 'split-corner-wall', 'plan-snap-endpoint',
|
||||
'plan-snap-line-gaps'])
|
||||
'plan-snap-line-gaps', 'wall-junctions', 'isometric-wall-junctions'])
|
||||
assert.equal(ids.includes(token), true, token);
|
||||
assert.equal(new Set(GOLDEN_SCENARIOS.map((scenario) => scenario.mode)).has('plan'), true);
|
||||
assert.equal(new Set(GOLDEN_SCENARIOS.map((scenario) => scenario.mode)).has('devices'), true);
|
||||
@@ -87,6 +93,23 @@ test('golden matrix covers required geometry, rendering and adaptive surfaces',
|
||||
assert.equal(new Set(GOLDEN_SCENARIOS.map((scenario) => scenario.theme)).has('dark'), true);
|
||||
});
|
||||
|
||||
test('wall junction goldens cover live L/T previews plus saved flat and isometric bodies', () => {
|
||||
const scenarios = GOLDEN_SCENARIOS.filter((scenario) => scenario.wallJunctions);
|
||||
assert.deepEqual(scenarios.map((scenario) => scenario.id), [
|
||||
'wall-junctions-plan-preview-light',
|
||||
'wall-junctions-plan-t-dark',
|
||||
'wall-junctions-view-dark',
|
||||
'isometric-wall-junctions-dark',
|
||||
]);
|
||||
for (const scenario of scenarios) {
|
||||
const fixture = prepareGoldenFixture(scenario);
|
||||
const space = fixture.config.spaces.find((item) => item.id === scenario.space);
|
||||
assert.equal(space.partitions.length, 7);
|
||||
assert.equal(space.room_drafts[0].segments.length, 2);
|
||||
assert.ok(space.partitions.some((item) => item.b[1] === 0.94), 'room-wall T fixture');
|
||||
}
|
||||
});
|
||||
|
||||
test('corner Split golden captures before, thin and thick facade states', () => {
|
||||
const scenarios = GOLDEN_SCENARIOS.filter((scenario) => scenario.cornerSplitWall);
|
||||
assert.deepEqual(scenarios.map((scenario) => scenario.cornerSplitWall), ['before', 'thin', 'thick']);
|
||||
|
||||
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
||||
import {
|
||||
canonicalColumnAngle, columnBody, floorMinusBodies, geometryArea,
|
||||
directionalOccluders, intersectionPaths, partitionBody, pointInPhysicalBody,
|
||||
pointInOpaquePlanBody, pointInPhysicalGeometry,
|
||||
physicalBodySet, pointInOpaquePlanBody, pointInPhysicalGeometry,
|
||||
sameColumnPlacement,
|
||||
} from '../test-build/physical-geometry.js';
|
||||
import {
|
||||
@@ -21,6 +21,51 @@ test('partition body keeps the centreline and requested physical width', () => {
|
||||
closeTo(geometryArea([[[...body, body[0]]]]), 0.5);
|
||||
});
|
||||
|
||||
test('joined partitions fill straight and oblique endpoint teeth without changing flat free caps', () => {
|
||||
const base = {
|
||||
room_drafts: [], wall_columns: [],
|
||||
partitions: [
|
||||
{ id: 'horizontal', a: [-2, 0], b: [0, 0], cm: 10 },
|
||||
{ id: 'vertical', a: [0, 0], b: [0, 2], cm: 10 },
|
||||
{ id: 'oblique', a: [4, 2], b: [3, 0], cm: 20 },
|
||||
{ id: 'oblique-arm', a: [3, 0], b: [5, -1], cm: 10 },
|
||||
],
|
||||
};
|
||||
const frame = physicalBodySet(base, 5, 0.25);
|
||||
assert.ok(frame.patches.length >= 2, 'each non-collinear endpoint node gains a bounded patch');
|
||||
assert.equal(pointInPhysicalGeometry([0.2, -0.2], frame.geometry), true,
|
||||
'the missing outer quadrant at the right angle is solid');
|
||||
assert.equal(pointInPhysicalGeometry([5.3, -1.15], frame.geometry), false,
|
||||
'an unrelated flat free cap is not extended');
|
||||
|
||||
const reversed = physicalBodySet({
|
||||
...base,
|
||||
partitions: [...base.partitions].reverse().map((segment) => ({
|
||||
...segment, a: segment.b, b: segment.a,
|
||||
})),
|
||||
}, 5, 0.25);
|
||||
closeTo(geometryArea(frame.geometry), geometryArea(reversed.geometry), 1e-8);
|
||||
});
|
||||
|
||||
test('endpoint-on-line T join is computed without splitting or mutating source records', () => {
|
||||
const space = {
|
||||
room_drafts: [{
|
||||
id: 'draft-branch', points: [[1, -2], [1, 0]], segments: [{ cm: 15 }],
|
||||
}],
|
||||
wall_columns: [],
|
||||
partitions: [
|
||||
{ id: 'through', a: [-2, 0], b: [2, 0], cm: 20 },
|
||||
{ id: 'branch', a: [0, -2], b: [0, 0], cm: 10 },
|
||||
],
|
||||
};
|
||||
const before = JSON.stringify(space);
|
||||
const frame = physicalBodySet(space, 5, 0.25);
|
||||
assert.ok(frame.patches.length >= 2, 'partition and saved-draft branches share the T primitive');
|
||||
assert.equal(pointInPhysicalGeometry([0.2, -0.1], frame.geometry), true);
|
||||
assert.equal(pointInPhysicalGeometry([1.2, -0.1], frame.geometry), true);
|
||||
assert.equal(JSON.stringify(space), before, 'computed node topology is render-only');
|
||||
});
|
||||
|
||||
test('column size means square side or circle diameter', () => {
|
||||
const square = columnBody(
|
||||
{ id: 'sq', shape: 'square', center: [1, 1], cm: 20, angle: 45 }, 5, 0.25,
|
||||
|
||||
@@ -4,7 +4,8 @@ import assert from 'node:assert/strict';
|
||||
import {
|
||||
wallKey, lookupWall, thicknessCmAt, degradeWalls, rekeyWallsAfterMove,
|
||||
setWallThickness, setWallThicknessForRoom, applyWallThicknessToNewRoom,
|
||||
drawWallPreviewD, DRAW_WALL_DEFAULT_CM, clampWallCm, cmToField, fieldToCm,
|
||||
drawWallPreviewD, linearWallBody, linearWallJoinPatches,
|
||||
DRAW_WALL_DEFAULT_CM, clampWallCm, cmToField, fieldToCm,
|
||||
wallCmToUnits, insetContour, inwardNormal, edgeKinds, wallEdgeBodies,
|
||||
wallBodyRings, wallBodiesGeometry, wallBodiesUnionPath, floorFootprintGeometry,
|
||||
innerContourForRoom,
|
||||
@@ -970,7 +971,35 @@ test('split materialisation cuts a partial shared interval at the new divider',
|
||||
test('drawWallPreviewD returns a path for open and closed outlines', () => {
|
||||
const open = drawWallPreviewD([[0, 0], [10, 0], [10, 6]], 1, false);
|
||||
assert.ok(open.includes('M'));
|
||||
assert.match(open, /11 -1(?:\D|$)/, 'open preview already contains the 90-degree mitre');
|
||||
const stepped = drawWallPreviewD(
|
||||
[[0, 0], [10, 0], [10, 6]], 1, false, [1, 2],
|
||||
);
|
||||
assert.match(stepped, /12 -1(?:\D|$)/,
|
||||
'the joined preview respects the second segment own half-depth');
|
||||
const closed = drawWallPreviewD([[0, 0], [10, 0], [10, 6], [0, 6]], 1, true);
|
||||
assert.ok(closed.includes('M'));
|
||||
assert.equal(drawWallPreviewD([[0, 0]], 1, false), '');
|
||||
});
|
||||
|
||||
test('linear wall joins bevel an excessive mitre and ignore malformed or near-miss inputs', () => {
|
||||
const acute = linearWallJoinPatches([
|
||||
{ a: [0, 0], b: [10, 0], halfDepth: 1 },
|
||||
{ a: [0, 0], b: [10, 0.1], halfDepth: 1 },
|
||||
], 1e-6);
|
||||
assert.equal(acute.length, 1);
|
||||
assert.equal(acute[0].length, 3, 'a mitre beyond the limit becomes a bevel triangle');
|
||||
assert.ok(acute[0].every((point) => Math.hypot(point[0], point[1]) <= MITRE_LIMIT));
|
||||
|
||||
const separate = linearWallJoinPatches([
|
||||
{ a: [-2, 0], b: [0, 0], halfDepth: 1 },
|
||||
{ a: [0.001, 0], b: [0.001, 2], halfDepth: 1 },
|
||||
], 1e-6);
|
||||
assert.deepEqual(separate, [], 'a point outside geometry epsilon remains disconnected');
|
||||
assert.equal(linearWallBody({ a: [0, 0], b: [Infinity, 1], halfDepth: 1 }), null);
|
||||
assert.deepEqual(linearWallJoinPatches([
|
||||
{ a: [-2, 0], b: [0, 0], halfDepth: 1 },
|
||||
{ a: [0, 0], b: [0, 0], halfDepth: 1 },
|
||||
{ a: [0, 0], b: [Infinity, 1], halfDepth: 1 },
|
||||
]), [], 'invalid neighbours do not alter a valid flat-capped segment');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user