lsa-planer

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

/ tests domain fahrzeugartEinlesen.test.ts

4,5 KB Rohdatei
tests/domain/fahrzeugartEinlesen.test.ts — 109 Zeilen
1 import { describe, expect, it } from 'vitest';
2 import { parseProject } from '@/domain/model/schema';
3 import { defaultVehicleClass } from '@/domain/model/factory';
4 import { SAFETY_FLOORS } from '@/domain/rilsa/constants';
5 import type { TrafficMode } from '@/domain/rilsa/types';
6
7 /*
8 * Fahrzeugart gegen die VERKEHRSART pruefen (Fassung 5.9.0).
9 *
10 * Das Schema prueft die Fahrzeugart bislang nur gegen die Werteliste. Eine
11 * Datei mit `mode` 'kfz' und `vehicleClass` 'keine' kam ohne eine einzige
12 * Meldung durch, der Raeumweg blieb ohne Fahrzeuglaenge, und die Zwischenzeit
13 * fiel um rund eine Sekunde kuerzer aus - die gefaehrliche Richtung.
14 *
15 * `oneOf` ersetzt eine UNBEKANNTE Art bereits durch die Standardart und meldet
16 * es. Eine bekannte, an dieser Verkehrsart aber unzulaessige Art ist derselbe
17 * Mangel desselben Feldes und bekommt dieselbe Behandlung; zwei verschiedene
18 * Wege fuer ein Feld waeren der Widerspruch, der behoben werden soll.
19 */
20
21 /** Ein eingelesenes Projekt mit genau einer Signalgruppe. */
22 function einlesen(mode: TrafficMode, vehicleClass: unknown) {
23 const roh = {
24 schemaVersion: 13,
25 signalGroups: [
26 {
27 id: 'sg-1',
28 name: 'K1',
29 mode,
30 movement: mode === 'fuss' ? 'querung' : 'geradeaus',
31 armId: null,
32 vZul: 50,
33 lanes: 1,
34 vehicleClass,
35 minGreenOverride: null,
36 maxGreenOverride: null,
37 reducedMobility: false,
38 color: '#2f6fd0',
39 },
40 ],
41 };
42 const { project, issues, repaired } = parseProject(roh);
43 const meldungen = issues.filter((i) => i.path === 'signalGroups[0].vehicleClass');
44 return {
45 art: project.signalGroups[0]?.vehicleClass,
46 meldung: meldungen[0],
47 meldungen,
48 repaired,
49 };
50 }
51
52 describe('Unzulaessige Fahrzeugart wird beim Einlesen ersetzt und gemeldet', () => {
53 it('ersetzt "keine" am Kfz-Strom durch die Standardart und meldet es', () => {
54 const { art, meldung, repaired } = einlesen('kfz', 'keine');
55 expect(art).toBe(defaultVehicleClass('kfz'));
56 expect(art).toBe('pkw');
57 expect(meldung).toBeDefined();
58 expect(meldung!.severity).toBe('warnung');
59 expect(meldung!.message).toContain('keine');
60 expect(meldung!.message).toContain(String(SAFETY_FLOORS.minVehicleLengthKfz));
61 // Die Ersetzung ist eine Reparatur: Der Einlesedialog muss erscheinen.
62 expect(repaired).toBe(true);
63 });
64
65 it('ersetzt "rad" am OePNV-Strom durch die Standardart dieser Verkehrsart', () => {
66 const { art, meldung } = einlesen('oepnv', 'rad');
67 expect(art).toBe(defaultVehicleClass('oepnv'));
68 expect(art).toBe('bus');
69 expect(meldung).toBeDefined();
70 });
71
72 it('laesst zulaessige Arten am Kfz-Strom unangetastet und schweigt', () => {
73 for (const art of ['pkw', 'lkw', 'bus', 'lastzug', 'strassenbahn'] as const) {
74 const ergebnis = einlesen('kfz', art);
75 expect(ergebnis.art, art).toBe(art);
76 expect(ergebnis.meldung, art).toBeUndefined();
77 }
78 });
79
80 it('laesst Fussgaenger- und Radgruppen jede Art behalten', () => {
81 // Nach oben ist derselbe Widerspruch nur unwirtschaftlich, nicht unsicher.
82 expect(einlesen('fuss', 'keine').art).toBe('keine');
83 expect(einlesen('fuss', 'lastzug').art).toBe('lastzug');
84 expect(einlesen('rad', 'keine').art).toBe('keine');
85 expect(einlesen('fuss', 'keine').meldung).toBeUndefined();
86 expect(einlesen('rad', 'keine').meldung).toBeUndefined();
87 });
88
89 it('meldet eine unbekannte Art weiterhin genau einmal', () => {
90 // GEZAEHLT, nicht nur gefunden: Der Name sagt "genau einmal", und genau das
91 // ist die Zusicherung. Sie haengt daran, dass der zweite Zweig den von
92 // `oneOf` bereits ERSETZTEN Wert prueft und nicht den rohen aus der Datei:
93 // Der Rueckfall `defaultVehicleClass(mode)` genuegt der Schranke immer, der
94 // Zweig greift deshalb nicht nach. Prueft er stattdessen den rohen Wert,
95 // stehen zwei Meldungen zu einem Feld im Einlesedialog.
96 const { art, meldung, meldungen } = einlesen('kfz', 'traktor');
97 expect(art).toBe('pkw');
98 expect(meldungen).toHaveLength(1);
99 expect(meldung!.message).toContain('traktor');
100 });
101
102 it('nimmt die Standardart aus dem Fachkern - keine zweite Fassung derselben Zuordnung', () => {
103 // Vor der Fassung 5.9.0 stand die Zuordnung hier ein zweites Mal als
104 // Bedingungskette; fuer den OePNV wich sie von defaultVehicleClass ab.
105 for (const mode of ['kfz', 'rad', 'fuss', 'oepnv'] as const) {
106 expect(einlesen(mode, 'traktor').art, mode).toBe(defaultVehicleClass(mode));
107 }
108 });
109 });