lsa-planer

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

/ tests domain beispielprojekt.test.ts

3,7 KB Rohdatei
tests/domain/beispielprojekt.test.ts — 77 Zeilen
1 import { readFileSync } from 'node:fs';
2 import { describe, expect, it } from 'vitest';
3 import { buildSignalPlan } from '@/domain/plan/signalPlan';
4 import { parseProject } from '@/domain/model/schema';
5 import { RILSA_DEFAULTS } from '@/domain/rilsa/constants';
6
7 /*
8 * Die Beispieldatei beispiele/vierarmiger-knotenpunkt.lsap unter der Furtregel
9 * (Befund C1).
10 *
11 * Die VORLAGE (createStandardIntersectionProject, Furten 12 m) bleibt bei 5 s
12 * - das prueft fehlendePruefungen.test.ts. Die BEISPIELDATEI ist eine andere
13 * Planung: Ihre Fussgaengergruppen raeumen bis zu 14,39 m (F Nord gegen K Ost),
14 * die halbe Furt braucht 7,20 m / 1,2 m/s = 5,996 s, und daraus werden 6 s
15 * statt der bisherigen 5 s. Wer die Datei oeffnet, sieht also eine
16 * Verhaltensaenderung, und die steht in den Unterlagen der Fassung ("Achtung
17 * bei bestehenden Projekten") - dieser Test haelt fest, dass die dort
18 * genannten Zahlen die der Datei sind. Gegen den Altstand schlaegt er fehl
19 * (dort 5 s, kein Hinweis).
20 */
21
22 const DATEI = 'beispiele/vierarmiger-knotenpunkt.lsap';
23 const DATUM = new Date('2026-01-01T00:00:00Z');
24
25 function beispiel(): ReturnType<typeof parseProject> {
26 return parseProject(JSON.parse(readFileSync(DATEI, 'utf8')), DATUM);
27 }
28
29 describe('Beispieldatei vierarmiger-knotenpunkt.lsap unter der Furtregel', () => {
30 it('liest sich ohne Fehler ein - Schema 7, ohne das Feld blindenzusatz', () => {
31 const ergebnis = beispiel();
32 expect(ergebnis.issues.filter((i) => i.severity === 'fehler')).toEqual([]);
33 for (const gruppe of ergebnis.project.signalGroups.filter((g) => g.mode === 'fuss')) {
34 // Altdatei: kein Zusatz erfasst, gerechnet wird die halbe Furt.
35 expect(gruppe.blindenzusatz).toBeUndefined();
36 }
37 });
38
39 it('gibt allen vier Fussgaengergruppen 6 s statt 5 s: laengster Raeumweg 14,39 m, halbe Furt 7,20 m / 1,2 m/s = 5,996 s', () => {
40 const { project } = beispiel();
41 const plan = buildSignalPlan(project);
42 const fussgruppen = plan.groups.filter((g) => g.mode === 'fuss');
43 expect(fussgruppen).toHaveLength(4);
44 for (const gruppe of fussgruppen) {
45 const mfz = gruppe.mindestfreigabezeit;
46 expect(mfz.regelwert).toBe(RILSA_DEFAULTS.minGreen.fuss);
47 expect(mfz.furt).not.toBeNull();
48 expect(mfz.furt!.furtlaenge).toBeCloseTo(14.39, 6);
49 expect(mfz.furt!.ganzeFurt).toBe(false);
50 expect(mfz.furt!.vr).toBe(1.2);
51 expect(mfz.furt!.zeitbedarf).toBeCloseTo(5.996, 3);
52 expect(mfz.furt!.zeitbedarfGerundet).toBe(6);
53 expect(mfz.massgebend).toBe('furt');
54 expect(mfz.wert).toBe(6);
55 expect(gruppe.times.minGreen).toBe(6);
56 // Der Plan haelt die neue Untergrenze ein - kein "unterschritten".
57 expect(gruppe.totalGreen).toBeGreaterThanOrEqual(6);
58 }
59 expect(plan.notes.some((n) => n.code === 'mindestfreigabezeit-unterschritten')).toBe(false);
60 });
61
62 it('nennt zu jeder Fussgaengergruppe den Rechenweg als Hinweis', () => {
63 const { project } = beispiel();
64 const plan = buildSignalPlan(project);
65 const hinweise = plan.notes.filter((n) => n.code === 'mindestfreigabezeit-aus-furtlaenge');
66 expect(hinweise).toHaveLength(4);
67 for (const hinweis of hinweise) {
68 expect(hinweis.severity).toBe('hinweis');
69 expect(hinweis.message).toContain('Furt von 14,39 m');
70 expect(hinweis.message).toContain('die halbe Furt');
71 expect(hinweis.message).toContain('7,20 m / 1,2 m/s = 5,996 s, aufgerundet 6 s');
72 expect(hinweis.message).toContain('beträgt deshalb 6 s statt des Regelwerts von 5 s');
73 }
74 // Keine Gruppe mit unbekannter Furtlaenge: Jede raeumt gegen Kfz-Stroeme.
75 expect(plan.notes.some((n) => n.code === 'mindestfreigabezeit-ohne-furtlaenge')).toBe(false);
76 });
77 });