This commit is contained in:
Andras Schmelczer 2026-09-11 17:57:03 +01:00
commit 7959fe85cc
29 changed files with 1679 additions and 498 deletions

View file

@ -3,6 +3,8 @@ import { renderToStaticMarkup } from 'react-dom/server';
import { describe, expect, it } from 'vitest';
import { FlooringPreview, SkirtingPreview } from '../src/components/CutPreview';
import { CutDialog } from '../src/components/CutDialog';
import { planSkirting } from '../src/lib/skirting';
import { skirtingEndLabel } from '../src/lib/cut-list';
import { defaultProject } from '../src/lib/defaults';
import { dimensionedOutline, flooringTemplate, skirtingEndBoxes } from '../src/lib/cut-preview';
import { cutMm, degree } from '../src/lib/format';
@ -64,6 +66,23 @@ describe('cut shape previews', () => {
expect(cutMm(600.001)).toBe('600.5');
});
it('preserves exact preparation dimensions in previews of fractional stock and remnants', () => {
const piece = {
...floor,
length: 597.2,
width: 190.1,
blankLength: 597.2,
blankWidth: 190.2,
reused: true,
};
const markup = renderToStaticMarkup(createElement(FlooringPreview, { piece }));
expect(markup).toContain('597.2 × 190.2 mm');
expect(markup).toContain('>597.2</text>');
expect(markup).toContain('>190.2</text>');
expect(markup).not.toContain('597.5');
expect(markup).not.toContain('190.5');
});
it('keeps skirting endpoints in original coordinates and gives both ends equal square windows', () => {
const original = structuredClone(template);
const boxes = skirtingEndBoxes(template, 18);
@ -208,7 +227,7 @@ describe('cut shape previews', () => {
expect(markup).toContain('Living room · Wall 1');
expect(markup).toContain('>1,164</text>');
expect(markup).toContain('>1,200</text>');
expect(markup).toContain('45° external');
expect(markup).toContain('Mitre 45°');
expect(markup).not.toContain('Source');
expect(markup).not.toContain('coordinates');
expect(markup).not.toContain('<dl');
@ -250,4 +269,60 @@ describe('cut shape previews', () => {
expect(floorMarkup).not.toContain('<figure');
expect(skirtMarkup).not.toContain('<figure');
});
it('shows cope preparation and its full-thickness body without inventing a decorative profile', () => {
const project = defaultProject();
const plan = planSkirting(project.rooms, project.skirting, project.tolerance);
const piece = plan.pieces.find((piece) => piece.leftType === 'cope')!;
expect(piece).toBeDefined();
const markup = renderToStaticMarkup(
createElement(CutDialog, { skirt: piece, project, close: () => {} }),
);
expect(markup).toContain(`Left cope preparation close-up ${piece.id}`);
expect(markup).toContain('Cope · prepare 45°');
expect(markup).toContain('preparation before coping');
expect(markup).toContain('class="skirting-cope-body"');
expect(markup).toContain('mark your moulding’s exposed profile');
expect(markup).toContain('Exposed front length:');
expect(skirtingEndLabel({ ...piece, rightType: 'internal', rightMitre: 0 }, 'right')).toBe(
'Receive cope · square',
);
expect(skirtingEndLabel({ ...piece, rightType: 'internal', rightMitre: 30 }, 'right')).toBe(
'Receive cope · wall-fit 30°',
);
const prepared = piece.template!;
const installed = piece.installedTemplate!;
expect(prepared[0].x).toBeLessThan(installed[0].x);
expect(prepared[3].x).toBeCloseTo(installed[3].x);
const compact = renderToStaticMarkup(
createElement(SkirtingPreview, {
piece,
thickness: project.skirting.thickness,
compact: true,
}),
);
expect(compact).toContain('class="skirting-cope-body"');
});
it('keeps an oblique coped body inside the uniformly scaled end close-up', () => {
const prepared = [
{ x: 0, y: 0 },
{ x: 1000, y: 0 },
{ x: 1000, y: 18 },
{ x: 2, y: 18 },
];
const installed = [
{ x: 100, y: 0 },
{ x: 1000, y: 0 },
{ x: 1000, y: 18 },
{ x: 2, y: 18 },
];
const boxes = skirtingEndBoxes(prepared, 18, installed);
expect(boxes.left.width).toBe(boxes.left.height);
for (const point of [prepared[0], prepared[3], installed[0], installed[3]]) {
expect(point.x).toBeGreaterThan(boxes.left.x);
expect(point.x).toBeLessThan(boxes.left.x + boxes.left.width);
expect(point.y).toBeGreaterThan(boxes.left.y);
expect(point.y).toBeLessThan(boxes.left.y + boxes.left.height);
}
});
});