lsa-planer

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

/ tests domain handvorgaben.test.ts

6,3 KB Rohdatei
tests/domain/handvorgaben.test.ts — 168 Zeilen
1 import { describe, expect, it } from 'vitest';
2 import { parseProject } from '@/domain/model/schema';
3
4 /*
5 * Befund 10, behoben in Fassung 5.9.0.
6 *
7 * `optionalNum` gibt bei jedem unlesbaren Eintrag `null` zurueck und meldet
8 * nichts. Betroffen sind genau die Felder, an denen eine Zwischenzeit oder eine
9 * Freigabezeit haengt. Eine von Hand abgestimmte Zwischenzeit "9 s" faellt damit
10 * still auf den gerechneten - hier kuerzeren - Wert zurueck, und beim naechsten
11 * Speichern ist sie endgueltig weg.
12 *
13 * Die Regel der unmittelbaren Nachbarn `boolGemeldet` und `anteilGemeldet` gilt
14 * auch hier: Ein FEHLENDER Eintrag schweigt, ein dastehender und unlesbarer
15 * wird gemeldet.
16 */
17 describe('Unlesbare Handvorgaben beim Einlesen', () => {
18 const zweiGruppen = [
19 { id: 'a', name: 'K1', mode: 'kfz' },
20 { id: 'b', name: 'K2', mode: 'kfz' },
21 ];
22
23 function mitKonfliktfeld(feld: string, wert: unknown): ReturnType<typeof parseProject> {
24 return parseProject({
25 signalGroups: zweiGruppen,
26 conflicts: [
27 {
28 fromId: 'a',
29 toId: 'b',
30 clearingDistance: 12,
31 enteringDistance: 10,
32 [feld]: wert,
33 },
34 ],
35 });
36 }
37
38 it('meldet eine unlesbare abgestimmte Zwischenzeit, statt sie stumm zu verwerfen', () => {
39 const { project, issues } = mitKonfliktfeld('manualIntergreen', '9 s');
40
41 expect(project.conflicts[0]!.manualIntergreen).toBeNull();
42 expect(
43 issues.some((i) => i.path === 'conflicts[0].manualIntergreen' && i.severity === 'warnung'),
44 ).toBe(true);
45 });
46
47 it('meldet eine unlesbare Raeumgeschwindigkeit, statt auf die schnellere Regelgeschwindigkeit zurueckzufallen', () => {
48 const { project, issues } = mitKonfliktfeld('clearingSpeedOverride', '1,0 m/s');
49
50 expect(project.conflicts[0]!.clearingSpeedOverride).toBeNull();
51 expect(
52 issues.some(
53 (i) => i.path === 'conflicts[0].clearingSpeedOverride' && i.severity === 'warnung',
54 ),
55 ).toBe(true);
56 });
57
58 it('meldet eine unlesbare Einfahrgeschwindigkeit', () => {
59 const { project, issues } = mitKonfliktfeld('enteringSpeedOverride', 'schnell');
60
61 expect(project.conflicts[0]!.enteringSpeedOverride).toBeNull();
62 expect(
63 issues.some(
64 (i) => i.path === 'conflicts[0].enteringSpeedOverride' && i.severity === 'warnung',
65 ),
66 ).toBe(true);
67 });
68
69 it('meldet eine unlesbare Ueberfahrzeit', () => {
70 const { project, issues } = mitKonfliktfeld('crossingTimeOverride', '3 s');
71
72 expect(project.conflicts[0]!.crossingTimeOverride).toBeNull();
73 expect(
74 issues.some(
75 (i) => i.path === 'conflicts[0].crossingTimeOverride' && i.severity === 'warnung',
76 ),
77 ).toBe(true);
78 });
79
80 it('meldet eine unlesbare Mindest- und Hoechstfreigabezeit der Signalgruppe', () => {
81 const { project, issues } = parseProject({
82 signalGroups: [
83 { id: 'a', name: 'K1', mode: 'kfz', minGreenOverride: '12 s', maxGreenOverride: 'lang' },
84 ],
85 });
86
87 expect(project.signalGroups[0]!.minGreenOverride).toBeNull();
88 expect(project.signalGroups[0]!.maxGreenOverride).toBeNull();
89 expect(
90 issues.some((i) => i.path === 'signalGroups[0].minGreenOverride' && i.severity === 'warnung'),
91 ).toBe(true);
92 expect(
93 issues.some((i) => i.path === 'signalGroups[0].maxGreenOverride' && i.severity === 'warnung'),
94 ).toBe(true);
95 });
96
97 it('meldet eine unlesbare vorgegebene Umlaufzeit des Programms', () => {
98 const { project, issues } = parseProject({
99 signalGroups: zweiGruppen,
100 program: { method: 'manuell', manualCycleTime: '80 s' },
101 });
102
103 expect(project.program.manualCycleTime).toBeNull();
104 expect(
105 issues.some((i) => i.path === 'program.manualCycleTime' && i.severity === 'warnung'),
106 ).toBe(true);
107 });
108
109 it('meldet eine unlesbare vorgegebene Freigabezeit einer Phase', () => {
110 // Eine Handvorgabe gilt im Signalzeitenplan als FESTE Freigabezeit
111 // (minGreen = maxGreen). Faellt sie stumm weg, verteilt der Plan nach dem
112 // Verhaeltnis der Saettigungsgrade - die Phase kann dabei kuerzer werden.
113 const { project, issues } = parseProject({
114 signalGroups: zweiGruppen,
115 phases: [{ id: 'p1', name: 'Phase 1', signalGroupIds: ['a'], manualGreen: '25 s' }],
116 });
117
118 expect(project.phases[0]!.manualGreen).toBeNull();
119 expect(issues.some((i) => i.path === 'phases[0].manualGreen' && i.severity === 'warnung')).toBe(
120 true,
121 );
122 });
123
124 it('behaelt eine lesbare Umlauf- und Freigabezeit und schweigt bei fehlenden Eintraegen', () => {
125 const mitZahlen = parseProject({
126 signalGroups: zweiGruppen,
127 program: { method: 'manuell', manualCycleTime: 80 },
128 phases: [{ id: 'p1', name: 'Phase 1', signalGroupIds: ['a'], manualGreen: 25 }],
129 });
130 expect(mitZahlen.project.program.manualCycleTime).toBe(80);
131 expect(mitZahlen.project.phases[0]!.manualGreen).toBe(25);
132 expect(
133 mitZahlen.issues.filter(
134 (i) => i.path === 'program.manualCycleTime' || i.path === 'phases[0].manualGreen',
135 ),
136 ).toEqual([]);
137
138 const ohneFelder = parseProject({
139 signalGroups: zweiGruppen,
140 program: { method: 'webster' },
141 phases: [{ id: 'p1', name: 'Phase 1', signalGroupIds: ['a'] }],
142 });
143 expect(ohneFelder.project.program.manualCycleTime).toBeNull();
144 expect(ohneFelder.project.phases[0]!.manualGreen).toBeNull();
145 expect(ohneFelder.repaired).toBe(false);
146 });
147
148 it('behaelt eine lesbare Handvorgabe und schweigt bei einem fehlenden Eintrag', () => {
149 const mitZahl = mitKonfliktfeld('manualIntergreen', 9);
150 expect(mitZahl.project.conflicts[0]!.manualIntergreen).toBe(9);
151 expect(mitZahl.issues.filter((i) => i.path.includes('manualIntergreen'))).toEqual([]);
152
153 const ohneFeld = parseProject({
154 signalGroups: zweiGruppen,
155 conflicts: [{ fromId: 'a', toId: 'b', clearingDistance: 12, enteringDistance: 10 }],
156 });
157 expect(ohneFeld.project.conflicts[0]!.manualIntergreen).toBeNull();
158 expect(ohneFeld.issues.filter((i) => i.path.startsWith('conflicts'))).toEqual([]);
159 expect(ohneFeld.repaired).toBe(false);
160 });
161
162 it('nimmt das deutsche Dezimalkomma weiterhin an', () => {
163 const { project, issues } = mitKonfliktfeld('clearingSpeedOverride', '1,5');
164
165 expect(project.conflicts[0]!.clearingSpeedOverride).toBeCloseTo(1.5, 6);
166 expect(issues.filter((i) => i.path.includes('clearingSpeedOverride'))).toEqual([]);
167 });
168 });