lsa-planer

LSA-Planer Professional – Planungssoftware für Lichtsignalanlagen nach RiLSA 2015 und § 45 StVO. EUPL-1.2.

/ tests domain freigabezeitrest.test.ts

5,1 KB Rohdatei
tests/domain/freigabezeitrest.test.ts — 126 Zeilen
1 import { describe, expect, it } from 'vitest';
2 import { distributeGreenTimes } from '@/domain/rilsa/greenSplit';
3 import { validateProject } from '@/domain/validation/engine';
4 import { buildSignalPlan, type PlanNote, type SignalPlan } from '@/domain/plan/signalPlan';
5 import { createStandardIntersectionProject } from '@/domain/model/factory';
6
7 /*
8 * Zwei Restmaengel der Freigabezeitverteilung (Fassung 5.9.0).
9 *
10 * Die erste Behebung hat in die Freigabezeitverteilung einen Zweig eingezogen, der die
11 * nicht nach Verkehrsstaerken vergebene Zeit an die Phasen mit Spielraum
12 * umlegt. Er benutzte dafuer die vorhandene Kennung `freigabezeit-rest` - und
13 * erbte damit im Pruefbericht deren Ueberschrift "Freigabezeit konnte nicht
14 * vollständig verteilt werden" und deren Rat "Prüfen Sie die vorgegebenen
15 * Freigabezeiten und die Umlaufzeit".
16 *
17 * Beides ist in diesem Zweig falsch: Die Zeit IST vollstaendig vergeben, und im
18 * Regelfall - eine Fussgaengerphase ohne Verkehrsstaerke - ist nichts zu
19 * pruefen. Der Zweig bekommt deshalb eine eigene Kennung.
20 */
21
22 const DATUM = new Date('2026-01-01T00:00:00Z');
23 const UMGELEGT = 'freigabezeit-rest-umgelegt';
24 const REST = 'freigabezeit-rest';
25
26 /**
27 * Knotenpunkt mit fester Freigabezeit in Phase 1 und einer Fussgaengerphase
28 * ohne Verkehrsstaerke in Phase 2 - der Regelfall des neuen Zweigs.
29 * Feste Umlaufzeit 95 s, zwei Phasenuebergaenge zu je 10 s: 75 s verfuegbar.
30 */
31 function mitUmlegung(): ReturnType<typeof distributeGreenTimes> {
32 return distributeGreenTimes(
33 95,
34 [
35 { id: 'p1', weight: 0.35, minGreen: 40, maxGreen: 40 },
36 { id: 'p2', weight: 0, minGreen: 20, maxGreen: 120 },
37 ],
38 [10, 10],
39 );
40 }
41
42 describe('Die Umlegung traegt eine eigene Kennung', () => {
43 it('meldet die Umlegung unter eigener Kennung', () => {
44 const ergebnis = mitUmlegung();
45
46 const notiz = ergebnis.notes.find((n) => n.code === UMGELEGT);
47 expect(notiz).toBeDefined();
48 expect(notiz?.severity).toBe('hinweis');
49 expect(notiz?.message).toContain('Phase 2');
50 });
51
52 it('benutzt dafuer nicht mehr die Kennung des nicht verteilbaren Rests', () => {
53 // Bis hierher stand ueber diesem Hinweis "Freigabezeit konnte nicht
54 // vollständig verteilt werden" - waehrend die Zeit vollstaendig vergeben
55 // ist.
56 const ergebnis = mitUmlegung();
57
58 expect(ergebnis.notes.some((n) => n.code === REST)).toBe(false);
59 });
60
61 it('laesst dem wirklich nicht verteilbaren Rest seine Kennung', () => {
62 // Einstreifige Verkehrsfuehrung, feste Umlaufzeit 300 s, zwei Uebergaenge
63 // zu je 10 s; Hoechstfreigabezeit 120 s je Phase. Hier liegt am Ende jede
64 // Phase an ihrer Obergrenze - die Warnung ist am Platz.
65 const ergebnis = distributeGreenTimes(
66 300,
67 [
68 { id: 'p1', weight: 0.35, minGreen: 5, maxGreen: 120 },
69 { id: 'p2', weight: 0, minGreen: 20, maxGreen: 120 },
70 ],
71 [10, 10],
72 );
73
74 const warnung = ergebnis.notes.find((n) => n.code === REST);
75 expect(warnung?.severity).toBe('warnung');
76 expect(ergebnis.notes.some((n) => n.code === UMGELEGT)).toBe(false);
77 });
78 });
79
80 describe('Ueberschrift, naechster Schritt und Sachgebiet der Umlegung', () => {
81 const project = createStandardIntersectionProject('Umlegung', DATUM);
82 const plan = buildSignalPlan(project);
83
84 function befundZu(note: PlanNote) {
85 const mitNotiz: SignalPlan = { ...plan, notes: [note] };
86 return validateProject(project, mitNotiz, DATUM).findings.find(
87 (f) => f.rule === `signalplan.${note.code}`,
88 );
89 }
90
91 it('behauptet nicht, die Freigabezeit sei nicht vollstaendig verteilt worden', () => {
92 const befund = befundZu({ severity: 'hinweis', code: UMGELEGT, message: 'Prüftext' });
93
94 expect(befund).toBeDefined();
95 expect(befund?.title).not.toBe('Freigabezeit konnte nicht vollständig verteilt werden');
96 expect(befund?.title).not.toBe('Hinweis aus dem Planaufbau');
97 });
98
99 it('verlangt im Regelfall keine Pruefung von Freigabezeiten und Umlaufzeit', () => {
100 const befund = befundZu({ severity: 'hinweis', code: UMGELEGT, message: 'Prüftext' });
101
102 expect(befund?.suggestion).not.toBe(
103 'Prüfen Sie die vorgegebenen Freigabezeiten und die Umlaufzeit; der Rest entsteht, wo ' +
104 'beides nicht zusammenpasst.',
105 );
106 expect(befund?.suggestion).not.toBe('Prüfen Sie die zugrunde liegenden Eingaben.');
107 });
108
109 it('fuehrt die Umlegung unter dem Signalzeitenplan', () => {
110 // Sie ist eine Aussage ueber die Verteilung im Plan, keine ueber die
111 // Leistungsfaehigkeit und keine ueber die Zwischenzeiten.
112 const befund = befundZu({ severity: 'hinweis', code: UMGELEGT, message: 'Prüftext' });
113
114 expect(befund?.category).toBe('signalplan');
115 });
116
117 it('laesst Ueberschrift und Rat des nicht verteilbaren Rests unveraendert', () => {
118 const befund = befundZu({ severity: 'warnung', code: REST, message: 'Prüftext' });
119
120 expect(befund?.title).toBe('Freigabezeit konnte nicht vollständig verteilt werden');
121 expect(befund?.suggestion).toBe(
122 'Prüfen Sie die vorgegebenen Freigabezeiten und die Umlaufzeit; der Rest entsteht, wo ' +
123 'beides nicht zusammenpasst.',
124 );
125 });
126 });