lsa-planer

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

/ tests domain zwischenzeitfall2.test.ts

8,3 KB Rohdatei
tests/domain/zwischenzeitfall2.test.ts — 186 Zeilen
1 import { readFileSync } from 'node:fs';
2 import { describe, expect, it } from 'vitest';
3 import { computeIntergreen } from '@/domain/rilsa/intergreen';
4 import { RILSA_DEFAULTS } from '@/domain/rilsa/constants';
5 import { QUELLEN } from '@/domain/rilsa/quellen';
6 import { HILFE } from '@/ui/help/texte';
7 import { createConflict } from '@/domain/model/factory';
8 import { aendereKonflikt, hatHandvorgaben } from '@/domain/model/project';
9 import type { ClearingStream, EnteringStream } from '@/domain/rilsa/types';
10
11 /*
12 * Fassung 5.4.0, Fragen E1 und E2 (Zwischenzeitfall 2, "abbiegendes
13 * Kraftfahrzeug raeumt").
14 *
15 * KEINE RECHENAENDERUNG - dieser Test sichert eine BELEGLAGE.
16 *
17 * Der A2-Vermerk vom 14.08.2026 (Fassung 5.4.0) behauptete als Beifang, das
18 * FGSV-Aenderungsblatt vom 29.07.2015 belege "auch Fall 2 woertlich (tue 2 s
19 * abbiegend; 5 m/s bei Innenradius < 10 m)". Die erneute vollstaendige
20 * Auswertung des Blattes am 15.08.2026 hat das widerlegt: Fall 2 kommt darin
21 * ausschliesslich als Bildunterschrift vor ("Bild 11: Beispiel fuer den
22 * Konfliktfall ..."); weder die Ueberfahrzeit 2 s noch die 5 m/s stehen dort.
23 *
24 * Was oeffentlich belegbar ist, stuetzt den Programmstand nur zum Teil:
25 * - 7,0 m/s fuer Abbieger bestaetigt der Leitfaden fuer Lichtsignalanlagen der
26 * Freien und Hansestadt Hamburg (Anlage A: "Kfz Abbieger 7,0 m/s").
27 * - Die Ueberfahrzeit koppelt dieses Programm an die Gelbzeit (3/4/5 s),
28 * waehrend die Sekundaerliteratur feste 3 s geradeaus und 2 s abbiegend
29 * nennt. Die Kopplung rechnet LAENGER - konservativ, aber abweichend.
30 * - Ein Sonderwert bei sehr engem Innenradius ist aus keiner oeffentlichen
31 * Quelle belegbar und deshalb nicht als Regel abgebildet; oertlich laesst er
32 * sich je Konfliktbeziehung eintragen.
33 *
34 * Deshalb bleibt gerechnet, was gerechnet wurde - und dieser Test haelt fest,
35 * dass die Unterlagen das auch so sagen.
36 */
37
38 function kfzRaeumend(extra: Partial<ClearingStream> = {}): ClearingStream {
39 return {
40 mode: 'kfz',
41 movement: 'rechts',
42 clearingDistance: 20,
43 vehicleClass: 'pkw',
44 vZul: 50,
45 ...extra,
46 };
47 }
48
49 function kfzEinfahrend(): EnteringStream {
50 return { mode: 'kfz', movement: 'geradeaus', enteringDistance: 10 };
51 }
52
53 describe('Zwischenzeitfall 2: Programmstand der Abbieger (Fassung 5.4.0, Fragen E1 und E2)', () => {
54 it('raeumt abbiegend mit 7,0 m/s und geradeaus mit 10,0 m/s', () => {
55 // 20 m Raeumweg + 6 m Pkw = 26 m. Abbiegend 26/7 = 3,714 s,
56 // geradeaus 26/10 = 2,6 s.
57 const abbiegend = computeIntergreen(kfzRaeumend(), kfzEinfahrend());
58 const geradeaus = computeIntergreen(kfzRaeumend({ movement: 'geradeaus' }), kfzEinfahrend());
59
60 expect(abbiegend.clearingSpeed).toBe(7.0);
61 expect(abbiegend.clearingSpeed).toBe(RILSA_DEFAULTS.clearingSpeed.kfzTurning);
62 expect(abbiegend.clearingTime).toBe(3.714);
63 expect(geradeaus.clearingSpeed).toBe(10.0);
64 });
65
66 it('setzt die Ueberfahrzeit auch beim Abbiegen gleich der Gelbzeit (3/4/5 s)', () => {
67 // Der Kern der Frage E2 (Fassung 5.4.0): Die Sekundaerliteratur nennt fuer Abbieger
68 // 2 s. Dieses Programm zeigt hier 3, 4 und 5 s - jede Stufe laenger.
69 for (const [vZul, gelb] of [
70 [50, 3],
71 [60, 4],
72 [70, 5],
73 ] as const) {
74 const result = computeIntergreen(kfzRaeumend({ vZul }), kfzEinfahrend());
75 expect(result.crossingTime, `vZul ${vZul}`).toBe(gelb);
76 }
77 });
78
79 it('rechnet die Kopplung damit laenger als die Literatur - nicht kuerzer', () => {
80 // 50 km/h, 20 m Raeumweg, 10 m Einfahrweg:
81 // Programm 3 + 26/7 - 10/11,1 = 3 + 3,714 - 0,901 = 5,813 -> 6 s
82 // Literatur 2 + 26/7 - 10/11,1 = 4,813 -> 5 s
83 // Die Abweichung liegt auf der sicheren Seite; ein Umbau auf 2 s wuerde
84 // die Zwischenzeit VERKUERZEN und ist ohne Druckwerk nicht zu vertreten.
85 const result = computeIntergreen(kfzRaeumend(), kfzEinfahrend());
86
87 expect(result.raw).toBe(5.813);
88 expect(result.intergreen).toBe(6);
89 });
90 });
91
92 describe('Enger Innenradius: Ueberschreibung je Beziehung (Fassung 5.4.0, Frage E1)', () => {
93 it('wirkt mit 5,0 m/s und verlaengert die Zwischenzeit', () => {
94 // Die 5 m/s bei Innenradius < 10 m sind oeffentlich nicht belegbar und
95 // deshalb keine Regel des Programms. Wer sie oertlich braucht, traegt sie
96 // an der Beziehung ein: 2 + 26/5 - 0,901 -> 3 + 5,2 - 0,901 = 7,299 -> 8 s.
97 const result = computeIntergreen(kfzRaeumend({ clearingSpeedOverride: 5.0 }), kfzEinfahrend());
98
99 expect(result.clearingSpeed).toBe(5.0);
100 expect(result.intergreen).toBe(8);
101 // Eine Verschaerfung ist zulaessig: kein Fehler, keine Kappung.
102 expect(result.notes.some((n) => n.severity === 'fehler')).toBe(false);
103 });
104
105 it('erscheint als Abweichung: Handvorgabe und entwerteter Wegnachweis', () => {
106 const vorher = createConflict('sg-1', 'sg-2');
107 expect(hatHandvorgaben(vorher)).toBe(false);
108
109 const nachher = aendereKonflikt(vorher, { clearingSpeedOverride: 5.0 });
110
111 expect(hatHandvorgaben(nachher)).toBe(true);
112 expect(nachher.wegnachweis.herkunft).toBe('handeingabe');
113 });
114 });
115
116 describe('Beleglage in Quelltext und Unterlagen', () => {
117 it('nennt das Fundstellenverzeichnis den Fall 2 samt beider Raeumgeschwindigkeiten', () => {
118 /*
119 * UMGESTELLT MIT 5.27.0. Bis dahin verlangte dieser Fall den Nachweis der
120 * LUECKE: die Hamburger Stuetze fuer die 7,0 m/s, die Abweichung bei der
121 * Ueberfahrzeit und den Vermerk, Fall 2 stehe im FGSV-Aenderungsblatt nur
122 * als Bildunterschrift. Alles drei war richtig, solange das Druckwerk
123 * fehlte. Es liegt vor; die Luecke gibt es nicht mehr, und ein Verzeichnis,
124 * das sie weiter behauptete, waere falsch.
125 */
126 const quelle = QUELLEN['rilsa-zwischenzeiten'];
127 const hinweis = quelle.hinweis ?? '';
128
129 expect(quelle.fundstelle).toContain('2.5.2');
130 // (a) Beide Raeumgeschwindigkeiten des Falles 2 mit ihrer Bedingung.
131 expect(hinweis).toContain('7 m/s');
132 expect(hinweis).toContain('5 m/s bei einem Radius des Fahrstreifeninnenrands unter 10 m');
133 // (b) Die feste Ueberfahrzeit des Falles 2.
134 expect(hinweis).toContain('tü = 2 s abbiegend');
135 // (c) Kein Rest der alten Luecke.
136 expect(hinweis).not.toContain('Bildunterschrift');
137 expect(hinweis).not.toContain('nicht belegbar');
138 });
139
140 it('traegt der Kennwert kfzTurning die Einordnung im Quelltext', () => {
141 const quelltext = readFileSync('src/domain/rilsa/constants.ts', 'utf8');
142
143 expect(quelltext).toContain('Abschnitt 2.5.2, Fall 2');
144 expect(quelltext).toContain('Innenradius');
145 });
146
147 it('nennt die Hilfe den engen Innenradius als oertliche Verschaerfung', () => {
148 const hilfe = readFileSync('src/ui/help/texte.ts', 'utf8');
149
150 expect(hilfe).toContain('Innenradius');
151 expect(hilfe).toContain('örtliche Verschärfung');
152 });
153
154 /*
155 * BEFUND (Fassung 5.4.0): Die Hilfe gab die 5 m/s ohne jeden Vorbehalt als
156 * Praxiswert aus - "(in der Praxis 5 m/s)" -, waehrend quellen.ts und die
157 * Unterlagen im selben Arbeitsstand sagen, die Zahl sei aus keiner
158 * oeffentlichen Quelle belegbar. Genau diese Art Behauptung sollte
159 * abgeschafft sein.
160 */
161 it('gibt die Hilfe die 5 m/s nicht als belegten Praxiswert aus', () => {
162 const raeumgeschwindigkeit = HILFE.raeumgeschwindigkeit.woher;
163
164 expect(raeumgeschwindigkeit).not.toContain('in der Praxis 5 m/s');
165 // Steht die Zahl da, steht der Vorbehalt daneben.
166 if (raeumgeschwindigkeit.includes('5 m/s')) {
167 expect(raeumgeschwindigkeit).toContain('nicht belegbar');
168 expect(raeumgeschwindigkeit).toContain('Fundstellenverzeichnis');
169 }
170 });
171
172 it('sagt die Hilfe dasselbe wie das Fundstellenverzeichnis', () => {
173 /*
174 * Beide Texte gehen an denselben Anwender; widersprechen sie sich, ist der
175 * vorsichtigere wertlos. Bis 5.26.0 war der gemeinsame Nenner "nicht
176 * belegbar"; seit 5.27.0 ist es die Fundstelle - und keiner der beiden darf
177 * die alte Aussage noch fuehren.
178 */
179 const hinweis = QUELLEN['rilsa-zwischenzeiten'].hinweis!;
180 expect(hinweis).not.toContain('nicht belegbar');
181 expect(HILFE.engerRadius.wasIstDas).toContain('Abschnitt 2.5.2');
182 expect(HILFE.engerRadius.wasIstDas).not.toContain('PRAXISANSATZ, KEIN REGELWERKSWERT');
183 expect(HILFE.raeumgeschwindigkeit.woher).not.toMatch(/\(in der Praxis [\d,]+ m\/s\)/);
184 expect(HILFE.raeumgeschwindigkeit.woher).not.toContain('nicht nachweisbar');
185 });
186 });