mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
66 lines
2.7 KiB
JavaScript
66 lines
2.7 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
placeResizeAreaLabel, resizeInwardNormal, resizeMeasuredEdges,
|
|
} from '../test-build/resize-labels.js';
|
|
|
|
const VIEW = { x: 0, y: 0, w: 1000, h: 1000, stageWidth: 1000, stageHeight: 1000 };
|
|
const ROOM = [[100, 100], [500, 100], [500, 500], [100, 500]];
|
|
|
|
test('#300 keeps only the two side-wall measurements', () => {
|
|
assert.deepEqual(resizeMeasuredEdges(ROOM, 1), [0, 2]);
|
|
assert.deepEqual(resizeMeasuredEdges(ROOM, 0), [3, 1]);
|
|
});
|
|
|
|
test('#300 inward side is stable for both polygon windings', () => {
|
|
const clean = (normal) => normal.map((value) => Math.abs(value) < 1e-9 ? 0 : value);
|
|
assert.deepEqual(clean(resizeInwardNormal(ROOM, 1)), [-1, 0]);
|
|
const reversed = [...ROOM].reverse();
|
|
const edge = reversed.findIndex((a, index) => {
|
|
const b = reversed[(index + 1) % reversed.length];
|
|
return a[0] === 500 && a[1] === 500 && b[0] === 500 && b[1] === 100;
|
|
});
|
|
assert.deepEqual(clean(resizeInwardNormal(reversed, edge)), [-1, 0]);
|
|
});
|
|
|
|
test('#300 shared-wall areas land on opposite sides', () => {
|
|
const left = placeResizeAreaLabel({
|
|
poly: ROOM, edge: 1, text: '16.0 m²', view: VIEW,
|
|
gearCenter: [300, 300], gearWidthPx: 20, gearHeightPx: 20,
|
|
});
|
|
const rightRoom = [[500, 100], [900, 100], [900, 500], [500, 500]];
|
|
const right = placeResizeAreaLabel({
|
|
poly: rightRoom, edge: 3, text: '16.0 m²', view: VIEW,
|
|
gearCenter: [700, 300], gearWidthPx: 20, gearHeightPx: 20,
|
|
});
|
|
assert.equal(left.side, 'left');
|
|
assert.equal(right.side, 'right');
|
|
assert.ok(left.offsetXPx < 0);
|
|
assert.ok(right.offsetXPx > 0);
|
|
});
|
|
|
|
test('#300 room gear collision shifts area along the wall without hiding it', () => {
|
|
const placed = placeResizeAreaLabel({
|
|
poly: ROOM, edge: 1, text: '16.0 m²', view: VIEW,
|
|
// Nominal label centre is x=472,y=300; put a wide zoomed gear there.
|
|
gearCenter: [472, 300], gearWidthPx: 120, gearHeightPx: 28,
|
|
});
|
|
assert.notEqual(placed.tangentOffsetPx, 0);
|
|
assert.equal(placed.anchor[0], 500);
|
|
assert.equal(placed.anchor[1], 300);
|
|
const dxPx = (placed.leader.b[0] - placed.leader.a[0]) * VIEW.stageWidth / VIEW.w;
|
|
const dyPx = (placed.leader.b[1] - placed.leader.a[1]) * VIEW.stageHeight / VIEW.h;
|
|
assert.ok(Math.abs(Math.hypot(dxPx, dyPx) - 12) < 1e-9);
|
|
});
|
|
|
|
test('#300 non-default zoom keeps gear avoidance in current screen pixels', () => {
|
|
const zoomedView = { ...VIEW, x: 250, y: 250, w: 500, h: 500 };
|
|
const placed = placeResizeAreaLabel({
|
|
poly: ROOM, edge: 1, text: '16.0 m²', view: zoomedView,
|
|
gearCenter: [486, 300], gearWidthPx: 160, gearHeightPx: 36,
|
|
});
|
|
assert.notEqual(placed.tangentOffsetPx, 0);
|
|
assert.ok(Number.isFinite(placed.offsetXPx));
|
|
assert.ok(Number.isFinite(placed.offsetYPx));
|
|
});
|