import { describe, expect, it } from 'vitest'; import { distributeGreenTimes } from '@/domain/rilsa/greenSplit'; import { validateProject } from '@/domain/validation/engine'; import { buildSignalPlan, type PlanNote, type SignalPlan } from '@/domain/plan/signalPlan'; import { createStandardIntersectionProject } from '@/domain/model/factory'; /* * Zwei Restmaengel der Freigabezeitverteilung (Fassung 5.9.0). * * Die erste Behebung hat in die Freigabezeitverteilung einen Zweig eingezogen, der die * nicht nach Verkehrsstaerken vergebene Zeit an die Phasen mit Spielraum * umlegt. Er benutzte dafuer die vorhandene Kennung `freigabezeit-rest` - und * erbte damit im Pruefbericht deren Ueberschrift "Freigabezeit konnte nicht * vollständig verteilt werden" und deren Rat "Prüfen Sie die vorgegebenen * Freigabezeiten und die Umlaufzeit". * * Beides ist in diesem Zweig falsch: Die Zeit IST vollstaendig vergeben, und im * Regelfall - eine Fussgaengerphase ohne Verkehrsstaerke - ist nichts zu * pruefen. Der Zweig bekommt deshalb eine eigene Kennung. */ const DATUM = new Date('2026-01-01T00:00:00Z'); const UMGELEGT = 'freigabezeit-rest-umgelegt'; const REST = 'freigabezeit-rest'; /** * Knotenpunkt mit fester Freigabezeit in Phase 1 und einer Fussgaengerphase * ohne Verkehrsstaerke in Phase 2 - der Regelfall des neuen Zweigs. * Feste Umlaufzeit 95 s, zwei Phasenuebergaenge zu je 10 s: 75 s verfuegbar. */ function mitUmlegung(): ReturnType { return distributeGreenTimes( 95, [ { id: 'p1', weight: 0.35, minGreen: 40, maxGreen: 40 }, { id: 'p2', weight: 0, minGreen: 20, maxGreen: 120 }, ], [10, 10], ); } describe('Die Umlegung traegt eine eigene Kennung', () => { it('meldet die Umlegung unter eigener Kennung', () => { const ergebnis = mitUmlegung(); const notiz = ergebnis.notes.find((n) => n.code === UMGELEGT); expect(notiz).toBeDefined(); expect(notiz?.severity).toBe('hinweis'); expect(notiz?.message).toContain('Phase 2'); }); it('benutzt dafuer nicht mehr die Kennung des nicht verteilbaren Rests', () => { // Bis hierher stand ueber diesem Hinweis "Freigabezeit konnte nicht // vollständig verteilt werden" - waehrend die Zeit vollstaendig vergeben // ist. const ergebnis = mitUmlegung(); expect(ergebnis.notes.some((n) => n.code === REST)).toBe(false); }); it('laesst dem wirklich nicht verteilbaren Rest seine Kennung', () => { // Einstreifige Verkehrsfuehrung, feste Umlaufzeit 300 s, zwei Uebergaenge // zu je 10 s; Hoechstfreigabezeit 120 s je Phase. Hier liegt am Ende jede // Phase an ihrer Obergrenze - die Warnung ist am Platz. const ergebnis = distributeGreenTimes( 300, [ { id: 'p1', weight: 0.35, minGreen: 5, maxGreen: 120 }, { id: 'p2', weight: 0, minGreen: 20, maxGreen: 120 }, ], [10, 10], ); const warnung = ergebnis.notes.find((n) => n.code === REST); expect(warnung?.severity).toBe('warnung'); expect(ergebnis.notes.some((n) => n.code === UMGELEGT)).toBe(false); }); }); describe('Ueberschrift, naechster Schritt und Sachgebiet der Umlegung', () => { const project = createStandardIntersectionProject('Umlegung', DATUM); const plan = buildSignalPlan(project); function befundZu(note: PlanNote) { const mitNotiz: SignalPlan = { ...plan, notes: [note] }; return validateProject(project, mitNotiz, DATUM).findings.find( (f) => f.rule === `signalplan.${note.code}`, ); } it('behauptet nicht, die Freigabezeit sei nicht vollstaendig verteilt worden', () => { const befund = befundZu({ severity: 'hinweis', code: UMGELEGT, message: 'Prüftext' }); expect(befund).toBeDefined(); expect(befund?.title).not.toBe('Freigabezeit konnte nicht vollständig verteilt werden'); expect(befund?.title).not.toBe('Hinweis aus dem Planaufbau'); }); it('verlangt im Regelfall keine Pruefung von Freigabezeiten und Umlaufzeit', () => { const befund = befundZu({ severity: 'hinweis', code: UMGELEGT, message: 'Prüftext' }); expect(befund?.suggestion).not.toBe( 'Prüfen Sie die vorgegebenen Freigabezeiten und die Umlaufzeit; der Rest entsteht, wo ' + 'beides nicht zusammenpasst.', ); expect(befund?.suggestion).not.toBe('Prüfen Sie die zugrunde liegenden Eingaben.'); }); it('fuehrt die Umlegung unter dem Signalzeitenplan', () => { // Sie ist eine Aussage ueber die Verteilung im Plan, keine ueber die // Leistungsfaehigkeit und keine ueber die Zwischenzeiten. const befund = befundZu({ severity: 'hinweis', code: UMGELEGT, message: 'Prüftext' }); expect(befund?.category).toBe('signalplan'); }); it('laesst Ueberschrift und Rat des nicht verteilbaren Rests unveraendert', () => { const befund = befundZu({ severity: 'warnung', code: REST, message: 'Prüftext' }); expect(befund?.title).toBe('Freigabezeit konnte nicht vollständig verteilt werden'); expect(befund?.suggestion).toBe( 'Prüfen Sie die vorgegebenen Freigabezeiten und die Umlaufzeit; der Rest entsteht, wo ' + 'beides nicht zusammenpasst.', ); }); });