/** * Task E7 – Event-Elemente-Polish: curtain, spotlight, barrier, * stage-height-Attribut. * * Prüft die Tool-Platzierung (Element-Form + Options), die * Pixi-Drawer-Primitives und die height-Durchreichung für stage. */ import { describe, it, expect } from 'vitest'; import { curtainTool, spotlightTool, barrierTool, } from '../src/plugins/builtin/event-tools'; import { createInMemoryDoc } from './helpers/inMemoryDoc'; import { CADDocument } from '../src/kernel/document/CADDocument'; import { elementToPrimitives } from '../src/render/pixi/elementDrawers'; import { SeatingService } from '../src/services/seatingService'; import type { CADElement, Pt } from '../src/types/cad.types'; function fireDown(tool: any, world: Pt, options: Record = {}) { const { ydoc } = createInMemoryDoc(); const doc = new CADDocument(ydoc); const ctx = { doc, options, setStatus: () => {}, setPreview: () => {}, } as any; tool.handlers.down({ world } as any, ctx); return { added: doc.getAllElements(), doc }; } describe('E7: curtain', () => { it('curtainTool platziert curtain-Element mit Wellen-Polyline und stageHeight', () => { const { added } = fireDown(curtainTool, { x: 100, y: 50 }, { stageHeight: 120 }); expect(added.length).toBe(1); const el = added[0]; expect(el.type).toBe('curtain'); expect(el.width).toBe(400); // Standard-Breite expect(el.properties.stageHeight).toBe(120); const pts = el.properties.points as Pt[]; expect(Array.isArray(pts)).toBe(true); expect(pts.length).toBeGreaterThan(20); // Wellenpunkte }); it('Drawer: curtain → polyline-Primitive (geschlossen=false)', () => { const { added } = fireDown(curtainTool, { x: 100, y: 50 }, { stageHeight: 120 }); const prims = elementToPrimitives(added[0]); expect(prims.length).toBe(1); expect(prims[0].kind).toBe('polyline'); expect((prims[0] as any).close).toBe(false); }); }); describe('E7: spotlight', () => { it('spotlightTool platziert Lichtkegel-Polygon mit angle und color', () => { const { added } = fireDown(spotlightTool, { x: 0, y: 0 }, { angle: 45, color: '#ffcc00' }); expect(added.length).toBe(1); const el = added[0]; expect(el.type).toBe('spotlight'); expect(el.properties.angle).toBe(45); expect(el.properties.color).toBe('#ffcc00'); const pts = el.properties.points as Pt[]; expect(pts.length).toBe(4); // Kegel: Ursprung + zwei Basis-Ecken + zurück }); it('Drawer: spotlight → Polygon mit Füllung aus color', () => { const { added } = fireDown(spotlightTool, { x: 0, y: 0 }, { angle: 45, color: '#ffcc00' }); const prims = elementToPrimitives(added[0]); expect(prims.length).toBe(1); expect(prims[0].kind).toBe('polyline'); expect((prims[0] as any).close).toBe(true); expect((prims[0] as any).stroke.toLowerCase()).toContain('#ffcc00'); }); it('Kegel-Ausrichtung: angle=0 zeigt nach rechts (Richtung +x)', () => { const { added } = fireDown(spotlightTool, { x: 0, y: 0 }, { angle: 0, color: '#fff' }); const pts = added[0].properties.points as Pt[]; expect(pts[1].x).toBeGreaterThan(100); // Basis-Ecke weiter rechts als Ursprung expect(pts[2].x).toBeGreaterThan(100); }); }); describe('E7: barrier', () => { it('barrierTool platziert Kette aus Kreis-Paaren entlang Standardlänge', () => { const { added } = fireDown(barrierTool, { x: 0, y: 0 }, {}); expect(added.length).toBe(1); const el = added[0]; expect(el.type).toBe('barrier'); expect(el.width).toBe(200); // Standard-Länge }); it('Drawer: barrier → mehrere circle-Primitives (Kettenglieder)', () => { const { added } = fireDown(barrierTool, { x: 0, y: 0 }, {}); const prims = elementToPrimitives(added[0]); expect(prims.length).toBeGreaterThan(4); expect(prims.every((p) => p.kind === 'circle')).toBe(true); }); }); describe('E7: stage height', () => { it('createStage nimmt height-Option auf (properties.height)', () => { const stage = new SeatingService().createStage(100, 100, 'layer-0', { width: 400, height: 60 }); expect(stage.type).toBe('stage'); expect(stage.properties.height).toBe(60); expect(stage.width).toBe(400); }); });