lsa-planer

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

/ tests ui legendeGegenRegel.test.ts

2,8 KB Rohdatei
tests/ui/legendeGegenRegel.test.ts — 76 Zeilen
1 import { afterEach, describe, expect, it } from 'vitest';
2 import { ProjectStore } from '@/app/store';
3 import { validateProject } from '@/domain/validation/engine';
4 import { buildSignalPlan } from '@/domain/plan/signalPlan';
5 import { createStandardIntersectionProject } from '@/domain/model/factory';
6 import { conflictsView } from '@/ui/views/conflictsView';
7 import type { Project } from '@/domain/model/project';
8
9 /*
10 * Die Legende der Zwischenzeitenansicht erklaerte die rot unterstrichene 0 s
11 * fuer "nicht zulaessig". Die Pruefregel zwischenzeiten.null meldet denselben
12 * Wert als WARNUNG und haelt fest, unter welcher Bedingung er zulaessig ist.
13 * Zwei Ansichten desselben Programms sagten damit Gegenteiliges ueber dieselbe
14 * Zahl. (Bis 5.42.1 nannte die Regel den Wert "bei langen Furten" den
15 * Regelfall; seit 5.43.0 nennt sie die Bedingung - Gruppe Furt.)
16 */
17
18 const STICHTAG = new Date('2026-01-01T00:00:00Z');
19
20 let aufraeumen: (() => void) | null = null;
21 afterEach(() => {
22 aufraeumen?.();
23 aufraeumen = null;
24 document.body.replaceChildren();
25 });
26
27 function legendentext(project: Project): string {
28 const wurzel = document.createElement('div');
29 document.body.append(wurzel);
30 const schliesse = conflictsView.render(wurzel, {
31 store: new ProjectStore(project),
32 refresh: () => {},
33 navigate: () => {},
34 target: null,
35 });
36 aufraeumen = () => {
37 schliesse();
38 wurzel.remove();
39 };
40 return wurzel.querySelector('.plan-legende')?.textContent ?? '';
41 }
42
43 /** Projekt, in dem jede Beziehung rechnerisch 0 s ergibt. */
44 function nullzwischenzeiten(): Project {
45 const roh = createStandardIntersectionProject('Legende', STICHTAG);
46 return {
47 ...roh,
48 conflicts: roh.conflicts.map((c) => ({ ...c, clearingDistance: 3, enteringDistance: 60 })),
49 };
50 }
51
52 describe('Legende und Pruefregel sagen dasselbe ueber eine Zwischenzeit von 0 s', () => {
53 it('erklaert den Wert nicht fuer unzulaessig', () => {
54 const text = legendentext(createStandardIntersectionProject('Legende', STICHTAG));
55
56 expect(text).toContain('Zwischenzeit 0 s');
57 expect(text, 'die Regel nennt den Wert unter einer Bedingung zulässig').not.toContain(
58 'nicht zulässig',
59 );
60 });
61
62 it('die Regel dazu ist eine Warnung und sperrt den Export nicht', () => {
63 const projekt = nullzwischenzeiten();
64 const bericht = validateProject(projekt, buildSignalPlan(projekt), STICHTAG);
65
66 const befunde = bericht.findings.filter((f) => f.rule === 'zwischenzeiten.null');
67 expect(befunde.length, 'Der Aufbau muss die Regel auslösen').toBeGreaterThan(0);
68 expect(befunde.every((f) => f.severity === 'warnung')).toBe(true);
69 expect(befunde[0]!.message).toContain('zulässig');
70
71 // Gegenprobe: Die 0 s allein darf den Export nicht sperren.
72 expect(
73 bericht.findings.some((f) => f.severity === 'fehler' && f.category === 'zwischenzeiten'),
74 ).toBe(false);
75 });
76 });