task(B5): seat counting by row and block

This commit is contained in:
Agent Zero
2026-08-26 20:53:42 +02:00
parent d93ee5308c
commit 7f4768c205
2 changed files with 96 additions and 2 deletions
+12 -2
View File
@@ -352,8 +352,18 @@ export class SeatingService {
return []; return [];
} }
/** Count seats in a list of elements */ /**
countSeats(elements: CADElement[]): { total: number; byRow: Record<string, number>; byBlock: Record<string, number> } { * Zählt Sitzplätze gruppiert nach Reihe und Block.
* byRow enthält Reihen aus freien Reihen UND Block-Reihen (seit BUG-1-Fix
* tragen Block-Stühle pro Reihe eine eigene rowId).
*/
countSeats(elements: CADElement[]): {
total: number;
byRow: Record<string, number>;
byBlock: Record<string, number>;
/** Platzhalter für künftige Zonen-Gruppierung (aktuell immer leer). */
byZone?: Record<string, number>;
} {
let total = 0; let total = 0;
const byRow: Record<string, number> = {}; const byRow: Record<string, number> = {};
const byBlock: Record<string, number> = {}; const byBlock: Record<string, number> = {};
+84
View File
@@ -0,0 +1,84 @@
/**
* Seating-Tests — countSeats: Zählung nach Reihe/Block/Gesamt.
* Ergänzt Task B5; Grundlage ist der BUG-1-Fix (rowId pro Block-Reihe).
*/
import { describe, it, expect } from 'vitest';
import { SeatingService } from '../src/services/seatingService';
import type { CADElement } from '../src/types/cad.types';
function makeChair(id: string, props: Record<string, unknown> = {}): CADElement {
return {
id,
type: 'chair',
layerId: 'layer-1',
x: 0,
y: 0,
width: 50,
height: 50,
properties: props,
} as unknown as CADElement;
}
function makeNonChair(id: string): CADElement {
return {
id,
type: 'rect',
layerId: 'layer-1',
x: 0,
y: 0,
width: 10,
height: 10,
properties: {},
} as unknown as CADElement;
}
describe('countSeats', () => {
const svc = new SeatingService();
it('zählt eine freie Reihe korrekt (5 Stühle, 1 rowId)', () => {
const els = svc.createSeatingRow(0, 0, 'layer-1', { count: 5 });
const result = svc.countSeats(els);
expect(result.total).toBe(5);
expect(Object.keys(result.byRow).length).toBe(1);
expect(Object.values(result.byRow)[0]).toBe(5);
expect(Object.keys(result.byBlock).length).toBe(0);
});
it('zählt einen Block korrekt (3 Reihen × 4 Stühle = 12)', () => {
const els = svc.createSeatingBlock(0, 0, 'layer-1', { rows: 3, cols: 4 });
const result = svc.countSeats(els);
expect(result.total).toBe(12);
expect(Object.keys(result.byBlock).length).toBe(1); // 1 Block
expect(Object.values(result.byBlock)[0]).toBe(12);
expect(Object.keys(result.byRow).length).toBe(3); // 3 Reihen (BUG-1-Fix!)
for (const count of Object.values(result.byRow)) {
expect(count).toBe(4); // je Reihe 4 Stühle
}
});
it('summiert gemischte Zeichnung korrekt (Reihe + Block + Fremdelemente)', () => {
const rows = svc.createSeatingRow(0, 0, 'layer-1', { count: 3 });
const block = svc.createSeatingBlock(100, 100, 'layer-1', { rows: 2, cols: 2 });
const others = [makeNonChair('x1'), makeNonChair('x2')];
const all: CADElement[] = [...rows, ...block, ...others];
const result = svc.countSeats(all);
expect(result.total).toBe(7); // 3 + 4, Nicht-Stühle ignorieren
expect(Object.keys(result.byRow).length).toBe(3); // 1 freie Reihe + 2 Block-Reihen
expect(Object.keys(result.byBlock).length).toBe(1);
});
it('liefert leere Summen bei leerer Eingabe', () => {
const result = svc.countSeats([]);
expect(result.total).toBe(0);
expect(result.byRow).toEqual({});
expect(result.byBlock).toEqual({});
});
it('zählt handgebaute Stühle ohne rowId nur im Gesamt', () => {
const els = [makeChair('h1'), makeChair('h2'), makeChair('h3', { rowId: 'row_manual' })];
const result = svc.countSeats(els);
expect(result.total).toBe(3);
expect(result.byRow['row_manual']).toBe(1);
expect(Object.keys(result.byRow).length).toBe(1);
});
});