import { describe, expect, it } from 'vitest'; import { loadProject } from '@/domain/model/migrate'; import { buildSignalPlan, intergreenBetween } from '@/domain/plan/signalPlan'; /* * Befund 4, behoben in Fassung 5.10.0. * * Die Auswahlliste der Fassung 4.3.3 kennt vier Verkehrsarten: kfz, fuss, rad * und `opnv`. Die Uebernahme prueft auf 'oepnv', 'öpnv', 'bus' und 'bahn' - * `opnv` (ohne e) enthaelt keine davon und fiel stumm auf 'kfz'. Aus jeder * OePNV-Gruppe wurde damit ein Kraftfahrzeugstrom: geraeumt mit 10,0 m/s statt * mit Vmax/3,6, ueberfahren mit der Gelbzeit statt mit der OePNV-Staffel. Die * Zwischenzeit fiel je Beziehung eine Sekunde zu kurz aus - die gefaehrliche * Richtung -, und `issues` blieb dazu leer. */ const DATUM = new Date('2026-09-05T08:00:00Z'); /** * Ein Altprojekt mit zwei einander widersprechenden Stroemen. Ohne * `zwischenzeiten.parameter` gelten die Rueckfallwege der Uebernahme: * Raeumweg 20 m, Einfahrweg 10 m. */ function altprojekt(typ: string): Record { return { metadata: { version: '4.3.3' }, projektdaten: { projektBezeichnung: 'Übernahme' }, signalgruppen: [ { id: 'SG-1', nummer: 'B1', typ, richtung: 'geradeaus', geschwindigkeit: 50 }, { id: 'SG-2', nummer: 'K1', typ: 'kfz', richtung: 'geradeaus', geschwindigkeit: 50 }, ], sperrmatrix: { matrix: [ [false, true], [true, false], ], }, zwischenzeiten: { matrix: [] }, phasen: [ { id: 'PH-1', bezeichnung: 'Phase 1', signalgruppen: ['SG-1'] }, { id: 'PH-2', bezeichnung: 'Phase 2', signalgruppen: ['SG-2'] }, ], }; } function zwischenzeitVonB1(typ: string): number { const { project } = loadProject(altprojekt(typ), DATUM); const b1 = project.signalGroups.find((g) => g.name === 'B1')!; const k1 = project.signalGroups.find((g) => g.name === 'K1')!; return intergreenBetween(buildSignalPlan(project).intergreens, b1.id, k1.id); } describe('Befund 4: OePNV-Verkehrsart der Fassung 4.3.3', () => { it('erkennt den gespeicherten Wert "opnv" als OePNV-Strom', () => { const { project } = loadProject(altprojekt('opnv'), DATUM); const b1 = project.signalGroups.find((g) => g.name === 'B1')!; expect(b1.mode).toBe('oepnv'); expect(b1.vehicleClass).toBe('bus'); }); it('raeumt danach nach der OePNV-Regel und nicht mehr mit dem Kfz-Regelwert', () => { // Raeumweg 20 m + Fahrzeuglaenge 6 m; vZul 50 km/h. // OePNV: tr = 26 / 13,89 = 1,87 s, tue = 5 s (Staffel), te = 10 / 11,1 = 0,90 s -> 6 s. // Kfz geradeaus: tr = 26 / 10,0 = 2,60 s, tue = 3 s (Gelbzeit) -> 5 s. expect(zwischenzeitVonB1('opnv')).toBe(6); expect(zwischenzeitVonB1('öpnv')).toBe(6); expect(zwischenzeitVonB1('kfz')).toBe(5); }); it('meldet eine unbekannte Verkehrsart, statt sie stumm zum Kfz-Strom zu machen', () => { const { project, issues } = loadProject(altprojekt('MIV'), DATUM); const meldung = issues.find((i) => i.path === 'signalgruppen[0]'); expect(meldung).toBeDefined(); expect(meldung!.severity).toBe('warnung'); expect(meldung!.message).toContain('MIV'); expect(project.signalGroups[0]!.mode).toBe('kfz'); }); it('schweigt zu den vier Werten der Auswahlliste und zum fehlenden Eintrag', () => { for (const typ of ['kfz', 'fuss', 'rad', 'opnv', '']) { const { issues } = loadProject(altprojekt(typ), DATUM); expect(issues.filter((i) => i.path.startsWith('signalgruppen['))).toEqual([]); } }); });