lsa-planer

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

/ tests ui verkehrsstaerkeNull.test.ts

6,2 KB Rohdatei
tests/ui/verkehrsstaerkeNull.test.ts — 144 Zeilen
1 import { describe, expect, it } from 'vitest';
2 import * as actions from '@/app/actions';
3 import type { AppState } from '@/app/store';
4 import type { Project } from '@/domain/model/project';
5 import { buildSignalPlan } from '@/domain/plan/signalPlan';
6 import { validateProject } from '@/domain/validation';
7 import { ASSISTENT_VORGABE, projektAusAngaben } from '@/ui/assistent';
8 import { naechsterSchritt } from '@/ui/naechsterSchritt';
9
10 /**
11 * Befund 48 zur Fassung 5.8.0.
12 *
13 * Der Fuehrungshinweis ueber jeder Ansicht zaehlte fuer den Arbeitsschritt
14 * "Verkehrsstaerken eintragen" die EINTRAEGE in `project.demands`, nicht die
15 * Eintraege mit einer wirksamen Zahl. `setDemand` legt bei fehlendem Eintrag
16 * aber `volume: 0` an - wer nur den SV-Anteil oder den Lastzuganteil ausfuellt
17 * oder in das Verkehrsstaerkefeld ausdruecklich 0 tippt, hat danach einen
18 * Eintrag ohne Verkehrsstaerke. Der Schritt galt damit als erledigt, waehrend
19 * derselbe Programmlauf im Pruefbericht "Es liegen keine Verkehrsstaerken vor"
20 * meldet und die Freigabezeiten gleichmaessig verteilt.
21 *
22 * Der Fachkern behandelt `volume <= 0` durchgaengig als "keine Angabe"
23 * (rules.ts, greenSplit.ts); die Fuehrung tut es jetzt auch.
24 */
25
26 const FESTES_DATUM = new Date('2026-01-01T00:00:00Z');
27
28 function grundprojekt(name: string): Project {
29 const p = projektAusAngaben(
30 { ...ASSISTENT_VORGABE, fussgaenger: true, rad: true },
31 name,
32 FESTES_DATUM,
33 );
34 return {
35 ...p,
36 meta: { ...p.meta, name: 'x', projectNumber: '1', client: 'c', planner: 'p', location: 'l' },
37 };
38 }
39
40 function zustand(project: Project): AppState {
41 const plan = buildSignalPlan(project);
42 return {
43 project,
44 plan,
45 report: validateProject(project, plan, FESTES_DATUM),
46 dirty: false,
47 filePath: null,
48 canUndo: false,
49 canRedo: false,
50 undoLabel: null,
51 redoLabel: null,
52 };
53 }
54
55 function ersteKfzGruppe(project: Project): string {
56 const gruppe = project.signalGroups.find((g) => g.mode === 'kfz');
57 expect(gruppe, 'Vorbedingung: das Vorgabeprojekt hat eine Kfz-Gruppe').toBeDefined();
58 return gruppe!.id;
59 }
60
61 describe('Fuehrungshinweis: Verkehrsstaerke 0 ist keine Verkehrsstaerke', () => {
62 it('Vorbedingung: das Vorgabeprojekt des Assistenten hat keine Verkehrsstaerken und verlangt sie', () => {
63 const p = grundprojekt('Ohne Zaehlung');
64 expect(p.demands).toEqual([]);
65 const state = zustand(p);
66 expect(state.report.errorCount, 'Vorbedingung: kein Fehler im Pruefbericht').toBe(0);
67 expect(naechsterSchritt(state).text).toContain(
68 'Verkehrsstärken der Kfz- und ÖPNV-Signalgruppen',
69 );
70 });
71
72 /*
73 * Ausloeser 1: Spalte "SV-Anteil" in der Ansicht "Signalgruppen". Sie ruft
74 * `setDemand` mit nur `heavyVehicleShare`; der dabei angelegte Eintrag traegt
75 * `volume: 0`.
76 */
77 it('verlangt weiterhin Verkehrsstaerken, wenn nur der SV-Anteil einer Kfz-Gruppe ausgefuellt ist', () => {
78 const p = grundprojekt('Nur SV-Anteil');
79 const kfz = ersteKfzGruppe(p);
80 const mitAnteil = actions.setDemand(p, kfz, { heavyVehicleShare: 0.05 });
81 expect(mitAnteil.demands.length, 'Vorbedingung: setDemand hat einen Eintrag angelegt').toBe(1);
82 expect(mitAnteil.demands[0]?.volume, 'Vorbedingung: der Eintrag traegt volume 0').toBe(0);
83 const state = zustand(mitAnteil);
84 expect(state.report.errorCount, 'Vorbedingung: kein Fehler im Pruefbericht').toBe(0);
85 const schritt = naechsterSchritt(state);
86 expect(schritt.text).toContain('Verkehrsstärken der Kfz- und ÖPNV-Signalgruppen');
87 expect(schritt.ansicht).toBe('signalgruppen');
88 });
89
90 /*
91 * Ausloeser 2: eine ausdruecklich getippte 0 im Feld "Verkehrsstaerke". Das
92 * Feld gibt sie unveraendert weiter.
93 *
94 * Ein LEERES Feld entfernt den Eintrag seit der Behebung von Befund 58 nur
95 * noch dann, wenn ausser der Verkehrsstaerke nichts an dem Strom erfasst ist;
96 * steht daneben ein Schwerverkehrs- oder Lastzuganteil, bleibt der Datensatz
97 * mit `volume: 0` stehen - also in genau dem Zustand, den dieser Fall prueft
98 * (tests/ui/verkehrsstaerkeLeeren.test.ts). Der Assistent nennt
99 * beide Wege "noch unbekannt".
100 */
101 it('verlangt weiterhin Verkehrsstaerken, wenn in das Verkehrsstaerkefeld einer Kfz-Gruppe 0 eingetragen ist', () => {
102 const p = grundprojekt('Getippte Null');
103 const kfz = ersteKfzGruppe(p);
104 const mitNull = actions.setDemand(p, kfz, { volume: 0 });
105 expect(mitNull.demands.length).toBe(1);
106 expect(mitNull.demands[0]?.volume).toBe(0);
107 const state = zustand(mitNull);
108 expect(state.report.errorCount, 'Vorbedingung: kein Fehler im Pruefbericht').toBe(0);
109 const schritt = naechsterSchritt(state);
110 expect(schritt.text).toContain('Verkehrsstärken der Kfz- und ÖPNV-Signalgruppen');
111 expect(schritt.ansicht).toBe('signalgruppen');
112 });
113
114 /*
115 * Ausloeser 3: Spalte "Lastzuege am SV". `setLastzugAnteil` legt bei
116 * fehlendem Eintrag ebenfalls einen mit `volume: 0` an.
117 */
118 it('verlangt weiterhin Verkehrsstaerken, wenn nur der Lastzuganteil einer Kfz-Gruppe eingetragen ist', () => {
119 const p = grundprojekt('Nur Lastzuege');
120 const kfz = ersteKfzGruppe(p);
121 const mitLastzug = actions.setLastzugAnteil(p, kfz, 0.2);
122 expect(mitLastzug.demands.length).toBe(1);
123 expect(mitLastzug.demands[0]?.volume).toBe(0);
124 const state = zustand(mitLastzug);
125 expect(state.report.errorCount, 'Vorbedingung: kein Fehler im Pruefbericht').toBe(0);
126 const schritt = naechsterSchritt(state);
127 expect(schritt.text).toContain('Verkehrsstärken der Kfz- und ÖPNV-Signalgruppen');
128 expect(schritt.ansicht).toBe('signalgruppen');
129 });
130
131 /*
132 * Gegenprobe: Eine wirksame Zahl an EINER Kfz-Gruppe erledigt den Schritt
133 * weiterhin - die Behebung darf ihn nicht dauerhaft stehen lassen.
134 */
135 it('erledigt den Schritt, sobald eine Kfz-Gruppe eine Verkehrsstaerke groesser 0 hat', () => {
136 const p = grundprojekt('Eine Zahl');
137 const kfz = ersteKfzGruppe(p);
138 const mitZahl = actions.setDemand(p, kfz, { volume: 400, heavyVehicleShare: 0.05 });
139 const state = zustand(mitZahl);
140 expect(state.report.errorCount, 'Vorbedingung: kein Fehler im Pruefbericht').toBe(0);
141 const schritt = naechsterSchritt(state);
142 expect(schritt.text).not.toContain('Verkehrsstärken der Kfz- und ÖPNV-Signalgruppen');
143 });
144 });