task(A4.3): migrate circle/arc/polyline/polygon tools to v2
This commit is contained in:
@@ -80,46 +80,125 @@ describe('A3 pilot: line tool', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('A4.2 pilot: rect tool', () => {
|
||||
it('erzeugt Rechteck mit BBox-Konvention; ein undo entfernt es', () => {
|
||||
describe('A4.3 pilot: circle tool', () => {
|
||||
it('erzeugt Kreis Zentrum+Radius; ein undo entfernt ihn', () => {
|
||||
const { ydoc } = createInMemoryDoc();
|
||||
const doc = new CADDocument(ydoc);
|
||||
const ctx = makeCtx({ doc });
|
||||
const rect = coreDrawingPlugin.tools?.find((t) => t.manifest.id === 'rect');
|
||||
expect(rect).toBeDefined();
|
||||
const circle = coreDrawingPlugin.tools!.find((t) => t.manifest.id === 'circle')!;
|
||||
|
||||
rect!.handlers.down!(pe(10, 10), ctx);
|
||||
rect!.handlers.move!(pe(110, 60), ctx);
|
||||
expect(ctx.previews.length).toBe(1); // Live-Vorschau
|
||||
rect!.handlers.up!(pe(110, 60), ctx);
|
||||
circle.handlers.down!(pe(100, 100), ctx);
|
||||
circle.handlers.move!(pe(200, 100), ctx);
|
||||
expect(ctx.previews.length).toBe(1);
|
||||
circle.handlers.up!(pe(200, 100), ctx);
|
||||
|
||||
const all = doc.getAllElements();
|
||||
expect(all.length).toBe(1);
|
||||
expect(all[0].type).toBe('rect');
|
||||
// Legacy-BBox-Konvention: Zentrum zwischen beiden Ecken
|
||||
expect(all[0].x).toBe(60);
|
||||
expect(all[0].y).toBe(35);
|
||||
expect(all[0].width).toBe(100);
|
||||
expect(all[0].height).toBe(50);
|
||||
expect(all[0].type).toBe('circle');
|
||||
expect(all[0].x).toBe(100);
|
||||
expect(all[0].properties.radius).toBe(100); // Distanz wie Legacy
|
||||
|
||||
expect(doc.undo()).toBe(true);
|
||||
expect(doc.getAllElements().length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A4.3 pilot: arc tool', () => {
|
||||
it('klick-progressiv: Zentrum→Start→Ende committet beim 3. Klick mit Grad-Winkeln', () => {
|
||||
const { ydoc } = createInMemoryDoc();
|
||||
const doc = new CADDocument(ydoc);
|
||||
const ctx = makeCtx({ doc });
|
||||
const arc = coreDrawingPlugin.tools!.find((t) => t.manifest.id === 'arc')!;
|
||||
|
||||
// Klick 1: Zentrum (up gehört zum Klick, committet NICHT — klick-progressiv)
|
||||
arc.handlers.down!(pe(0, 0), ctx);
|
||||
expect(doc.getAllElements().length).toBe(0); // Phase 1/2 committet nie
|
||||
|
||||
// Klick 2: Startpunkt auf Radius 50 nach Osten (0°)
|
||||
arc.handlers.down!(pe(50, 0), ctx);
|
||||
expect(doc.getAllElements().length).toBe(0);
|
||||
|
||||
// Klick 3: Endpunkt oben (90°) → JETZT committet der dritte down
|
||||
arc.handlers.down!(pe(0, 50), ctx);
|
||||
|
||||
const all = doc.getAllElements();
|
||||
expect(all.length).toBe(1);
|
||||
expect(all[0].type).toBe('arc');
|
||||
expect(all[0].x).toBe(0);
|
||||
expect(all[0].y).toBe(0);
|
||||
expect(all[0].properties.radius).toBe(50);
|
||||
expect(all[0].properties.startAngle).toBeCloseTo(0);
|
||||
expect(all[0].properties.endAngle).toBeCloseTo(90);
|
||||
|
||||
expect(doc.undo()).toBe(true);
|
||||
expect(doc.getAllElements().length).toBe(0);
|
||||
});
|
||||
|
||||
it('cancel verwirft das laufende Rechteck', () => {
|
||||
it('cancel bricht mehrphasige Sitzung vollstaendig ab', () => {
|
||||
const { ydoc } = createInMemoryDoc();
|
||||
const doc = new CADDocument(ydoc);
|
||||
const ctx = makeCtx({ doc });
|
||||
const rect = coreDrawingPlugin.tools!.find((t) => t.manifest.id === 'rect')!;
|
||||
const arc = coreDrawingPlugin.tools!.find((t) => t.manifest.id === 'arc')!;
|
||||
|
||||
rect.handlers.down!(pe(5, 5), ctx);
|
||||
rect.handlers.cancel!(ctx);
|
||||
rect.handlers.up!(pe(50, 50), ctx);
|
||||
arc.handlers.down!(pe(0, 0), ctx); // phase 1
|
||||
arc.handlers.down!(pe(30, 0), ctx); // phase 2
|
||||
arc.handlers.cancel!(ctx); // reset
|
||||
arc.handlers.down!(pe(99, 99), ctx); // startet neu bei phase 1
|
||||
|
||||
// Kein Commit erfolgt (nur phase 1), nichts im Doc:
|
||||
expect(doc.getAllElements().length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A4.3 pilot: polyline/polygon tools', () => {
|
||||
it('polyline sammelt Punkte und committet per ENTER ab 2', () => {
|
||||
const { ydoc } = createInMemoryDoc();
|
||||
const doc = new CADDocument(ydoc);
|
||||
const ctx = makeCtx({ doc });
|
||||
const pl = coreDrawingPlugin.tools!.find((t) => t.manifest.id === 'polyline')!;
|
||||
|
||||
pl.handlers.down!(pe(0, 0), ctx);
|
||||
pl.handlers.move!(pe(10, 10), ctx);
|
||||
expect(ctx.previews.length).toBeGreaterThan(0);
|
||||
pl.handlers.down!(pe(20, 0), ctx);
|
||||
pl.handlers.down!(pe(30, 30), ctx);
|
||||
|
||||
const kev = { key: 'Enter', preventDefault: () => {} } as unknown as KeyboardEvent;
|
||||
const consumed = pl.handlers.key!(kev, ctx);
|
||||
expect(consumed).toBe(true);
|
||||
|
||||
const all = doc.getAllElements();
|
||||
expect(all.length).toBe(1);
|
||||
expect(all[0].type).toBe('polyline');
|
||||
expect((all[0].properties.points as Pt[]).length).toBe(3);
|
||||
expect(all[0].x).toBe(15); // BBox-Zentrum min0 max30
|
||||
|
||||
expect(doc.undo()).toBe(true);
|
||||
expect(doc.getAllElements().length).toBe(0);
|
||||
});
|
||||
|
||||
it('polygon braucht mind. 3 Punkte; ENTER davor meldet Hinweis', () => {
|
||||
const { ydoc } = createInMemoryDoc();
|
||||
const doc = new CADDocument(ydoc);
|
||||
const pg = coreDrawingPlugin.tools!.find((t) => t.manifest.id === 'polygon')!;
|
||||
const ctx = makeCtx({ doc });
|
||||
|
||||
pg.handlers.down!(pe(0, 0), ctx);
|
||||
pg.handlers.down!(pe(10, 10), ctx);
|
||||
const kev = { key: 'Enter', preventDefault: () => {} } as unknown as KeyboardEvent;
|
||||
pg.handlers.key!(kev, ctx); // nur 2 Punkte → abgelehnt
|
||||
expect(doc.getAllElements().length).toBe(0);
|
||||
expect(ctx.statuses.some((s) => s.includes('mindestens 3'))).toBe(true);
|
||||
|
||||
pg.handlers.down!(pe(20, -5), ctx);
|
||||
pg.handlers.key!(kev, ctx); // jetzt 3 Punkte → ok
|
||||
const all = doc.getAllElements();
|
||||
expect(all.length).toBe(1);
|
||||
expect(all[0].type).toBe('polygon');
|
||||
expect((all[0].properties.points as Pt[]).length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A3 pilot: select tool', () => {
|
||||
function makeBridge(elements: CADElement[]) {
|
||||
let ids: string[] = [];
|
||||
|
||||
Reference in New Issue
Block a user