Files
web-cad/frontend/tests/bugs.regress.test.ts
T
2026-08-26 13:51:02 +02:00

103 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Regressions-Tests für bekannte Bugs BUG-1, BUG-1b, BUG-2.
* Diese Tests sind VOR dem jeweiligen Fix ROT (dokumentiertes Fehlverhalten)
* und müssen danach GRÜN sein.
*/
import { describe, it, expect } from 'vitest';
import { SeatingService } from '../src/services/seatingService';
import { trimElement, offsetElement } from '../src/tools/modification/geometry';
import type { CADElement } from '../src/types/cad.types';
// ── Helfer (Muster aus tests/geometry.test.ts) ─────────────
function makeLine(id: string, x1: number, y1: number, x2: number, y2: number): CADElement {
return {
id,
type: 'line',
layerId: 'layer-1',
x: (x1 + x2) / 2,
y: (y1 + y2) / 2,
width: Math.abs(x2 - x1),
height: Math.abs(y2 - y1),
properties: { x1, y1, x2, y2 },
} as unknown as CADElement;
}
function makeCircle(id: string, cx: number, cy: number, r: number): CADElement {
return {
id,
type: 'circle',
layerId: 'layer-1',
x: cx,
y: cy,
width: r * 2,
height: r * 2,
properties: { radius: r },
} as unknown as CADElement;
}
// ── BUG-1: rowId-Kollision bei schnellem Erzeugen ───────────
describe('BUG-1: seating row ids', () => {
it('zwei direkt hintereinander erzeugte Reihen haben unterschiedliche rowIds', () => {
const svc = new SeatingService();
const a = svc.createSeatingRow(0, 0, 'layer-1');
const b = svc.createSeatingRow(0, 100, 'layer-1');
const ids = new Set([a[0].properties.rowId, b[0].properties.rowId]);
expect(ids.size).toBe(2);
});
});
// ── BUG-1b: Block-Reihen ohne eigene rowId ──────────────────
describe('BUG-1b: seating block row ids', () => {
it('jede Reihe eines Blocks hat eine eigene, definierte rowId', () => {
const svc = new SeatingService();
const els = svc.createSeatingBlock(0, 0, 'layer-1', { rows: 3, cols: 2 });
expect(els.length).toBe(6);
const rowIds = new Set(els.map((e) => e.properties.rowId));
expect(rowIds.size).toBe(3);
for (const rid of rowIds) expect(rid).toBeDefined();
});
});
// ── BUG-2: Trim an Kreis scheitert (findIntersection nur Gerade×Gerade) ──
describe('BUG-2: trim line at circle', () => {
it('trimElement(Linie, Kreis) liefert ein Ergebnis statt null', () => {
// Linie von (0,0) nach (200,0) schneidet Kreis (Zentrum 100,0, Radius 40)
// an x=60 und x=140 → Schnitt existiert eindeutig.
const line = makeLine('l1', 0, 0, 200, 0);
const circle = makeCircle('c1', 100, 0, 40);
const result = trimElement(line, circle);
expect(result).not.toBeNull();
});
});
// ── BUG-3: Offset ignorierte die Klickseite ─────────────────
describe('BUG-3: offset respects click side', () => {
it('side=-1 versetzt Linie entgegen der Normalenrichtung', () => {
// Linie (100,100)→(300,100): Laufrichtung +x.
// Normale (-dy,dx)=(0,1) zeigt in Canvas-Koordinaten nach UNTEN (+y).
const line = makeLine('l1', 100, 100, 300, 100);
const result = offsetElement(line, 20, -1);
expect(result.properties.y1).toBeCloseTo(80); // nach OBEN versetzt
expect(result.properties.y2).toBeCloseTo(80);
});
it('side=+1 versetzt Linie in Normalenrichtung (Default wie vorher)', () => {
const line = makeLine('l1', 100, 100, 300, 100);
const result = offsetElement(line, 20, 1);
expect(result.properties.y1).toBeCloseTo(120); // nach UNTEN versetzt
expect(result.properties.y2).toBeCloseTo(120);
});
it('ohne side bleibt Verhalten identisch zur alten API (Rueckwaertskompatibilitaet)', () => {
const line = makeLine('l1', 100, 100, 300, 100);
const result = offsetElement(line, 20);
expect(result.properties.y1).toBeCloseTo(120);
});
it('Kreis: side=-1 verkleinert Radius, side=+1 vergroessert', () => {
const circle = makeCircle('c1', 0, 0, 50);
expect(offsetElement(circle, 10, -1).properties.radius).toBeCloseTo(40);
expect(offsetElement(circle, 10, 1).properties.radius).toBeCloseTo(60);
});
});