lsa-planer

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

/ tests ui anlagenartLeiste.test.ts

3,1 KB Rohdatei
tests/ui/anlagenartLeiste.test.ts — 84 Zeilen
1 import { afterEach, describe, expect, it } from 'vitest';
2 import { Shell } from '@/ui/shell';
3 import { ProjectStore } from '@/app/store';
4 import { createEmptyProject } from '@/domain/model/factory';
5 import { ANLAGENART_KURZ, ANLAGENART_LABELS } from '@/domain/rilsa/constants';
6 import type { Anlagenart } from '@/domain/model/project';
7
8 /**
9 * Die Anlagenart in der Statusleiste.
10 *
11 * Die Leiste fuehrt Umlaufzeit, Signalgruppen und Phasen. Ohne die Anlagenart
12 * daneben laesst sich keine dieser Zahlen einordnen: Eine Umlaufzeit von 240 s
13 * ist am Knotenpunkt weit ueber der Sicherheitsgrenze von 120 s, an einer
14 * Arbeitsstelle mit langer Engstelle dagegen zwangslaeufig. Und wer die
15 * Anlagenart versehentlich falsch gesetzt hat, merkt es sonst nirgends im
16 * laufenden Betrieb.
17 */
18
19 const FIXED_DATE = new Date('2026-01-01T00:00:00Z');
20
21 let laufend: Shell | null = null;
22
23 afterEach(() => {
24 laufend?.stop();
25 laufend = null;
26 document.body.replaceChildren();
27 });
28
29 function baueShell(anlagenart: Anlagenart): HTMLElement {
30 const wurzel = document.createElement('div');
31 document.body.append(wurzel);
32
33 const store = new ProjectStore(createEmptyProject('Baustelle', FIXED_DATE, anlagenart));
34 const shell = new Shell(wurzel, store, '5.1.0');
35 shell.addView({
36 id: 'test',
37 label: 'Test',
38 group: 'Test',
39 description: 'Nur zum Aufbau der Shell',
40 render: () => () => {},
41 });
42 shell.start('test');
43 laufend = shell;
44 return wurzel;
45 }
46
47 function leistentext(anlagenart: Anlagenart): string {
48 const leiste = baueShell(anlagenart).querySelector('footer.leiste');
49 return leiste?.textContent ?? '';
50 }
51
52 describe('Anlagenart in der Statusleiste', () => {
53 it('fuehrt die Anlagenart neben Umlaufzeit, Signalgruppen und Phasen', () => {
54 for (const art of ['knotenpunkt', 'fussgaengerschutzanlage', 'einstreifig'] as const) {
55 const text = leistentext(art);
56 expect(text, art).toContain(`Anlagenart: ${ANLAGENART_KURZ[art]}`);
57 expect(text, art).toContain('Umlaufzeit');
58 laufend?.stop();
59 laufend = null;
60 document.body.replaceChildren();
61 }
62 });
63
64 it('benennt sie mit derselben Kurzform wie der Ausdruck', () => {
65 // Eine eigene Formulierung fuer den Bildschirm liefe beim naechsten
66 // Wortwechsel gegenueber der Planunterlage auseinander. Die Statusleiste
67 // nimmt die Kurzform, der Ausdruck die lange Beschriftung - beide muessen
68 // mit demselben Wortlaut anfangen, sonst benennt das Programm dieselbe
69 // Anlage auf dem Bildschirm anders als in der Unterlage.
70 for (const art of ['knotenpunkt', 'fussgaengerschutzanlage', 'einstreifig'] as const) {
71 expect(ANLAGENART_LABELS[art], art).toMatch(
72 new RegExp(`^${ANLAGENART_KURZ[art].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`),
73 );
74 }
75 });
76
77 it('sagt die Anlagenart im Ansageraum mit an', () => {
78 // Die Sprachausgabe liest nur diesen Bereich. Stuende dort allein die
79 // Umlaufzeit, waere die Zahl fuer einen blinden Bearbeiter nicht
80 // einzuordnen.
81 const ansage = baueShell('einstreifig').querySelector('[role="status"]');
82 expect(ansage?.textContent ?? '').toContain(`Anlagenart ${ANLAGENART_KURZ.einstreifig}`);
83 });
84 });