lsa-planer

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

/ tests domain wegherkunftAussagen.test.ts

4,0 KB Rohdatei
tests/domain/wegherkunftAussagen.test.ts — 101 Zeilen
1 import { describe, expect, it } from 'vitest';
2 import { validateProject } from '@/domain/validation/engine';
3 import { buildSignalPlan } from '@/domain/plan/signalPlan';
4 import { createStandardIntersectionProject } from '@/domain/model/factory';
5 import { REGELBREITE } from '@/domain/geometrie/vermessung';
6 import type { Lageplan } from '@/domain/geometrie/lageplan';
7 import type { Project } from '@/domain/model/project';
8
9 /*
10 * Zwei Dokumente desselben Vorgangs duerfen sich nicht widersprechen.
11 *
12 * Der Pruefbericht sagte "Ob ein einzelner eingetragener Weg wirklich von hier
13 * stammt, fuehrt das Projekt nicht mit." Der Ausdruck sagte in derselben
14 * Planunterlage das Gegenteil: "fuehrt das Projekt je Beziehung mit;
15 * ausgewiesen wird es in der Spalte 'Herkunft der Wege'".
16 *
17 * Beide Saetze stammen aus verschiedenen Zeiten: Der erste ist aelter als
18 * Schemastand 9, mit dem Conflict.wegnachweis eingefuehrt wurde. Er blieb
19 * stehen, weil ihn nichts festhielt. Ein Bearbeiter, der beide liest, kann
20 * nicht entscheiden, welchem er glauben soll - und die Frage ist nicht
21 * nebensaechlich: Es geht darum, ob die Herkunft eines sicherheitsrelevanten
22 * Masses nachgewiesen ist.
23 */
24
25 const STICHTAG = new Date('2026-01-01T12:00:00Z');
26
27 /** Lageplan mit einem Massstab, der zum Vermessen zu grob ist. */
28 function groberLageplan(meterJeBildpunkt: number): Lageplan {
29 const bildbreite = 1000;
30 return {
31 arbeitsbereiche: [],
32 signalgeber: [],
33 bild: null,
34 kalibrierung: {
35 von: { x: 0, y: 0 },
36 bis: { x: bildbreite, y: 0 },
37 laengeMeter: bildbreite * meterJeBildpunkt,
38 herkunft: 'georeferenziert',
39 },
40 haltlinien: [],
41 // Eine gezeichnete Fahrlinie bedeutet: Hier wird abgegriffen.
42 linien: [
43 {
44 id: 'lin-1',
45 name: 'K1 geradeaus',
46 mode: 'kfz',
47 movement: 'geradeaus',
48 haltlinieId: null,
49 startT: 0,
50 signalGroupId: null,
51 breiteMeter: REGELBREITE.kfz,
52 punkte: [
53 { x: 100, y: 100 },
54 { x: 400, y: 100 },
55 ],
56 },
57 ],
58 };
59 }
60
61 function berichtstexte(project: Project): string {
62 const bericht = validateProject(project, buildSignalPlan(project), STICHTAG);
63 return bericht.findings.map((f) => `${f.title} ${f.message} ${f.suggestion}`).join('\n');
64 }
65
66 describe('Pruefbericht und Ausdruck sagen dasselbe ueber die Wegherkunft', () => {
67 it('behauptet im Pruefbericht nicht, die Herkunft werde nicht mitgefuehrt', () => {
68 const roh = createStandardIntersectionProject('Wegherkunft', STICHTAG);
69 // 2 m je Bildpunkt: eindeutig zu grob, die Regel schlaegt an.
70 const projekt: Project = { ...roh, lageplan: groberLageplan(2) };
71 const text = berichtstexte(projekt);
72
73 expect(text, 'die Regel zur groben Unterlage muss anschlagen').toContain(
74 'zum Vermessen zu grob',
75 );
76
77 // Genau die Formulierungen, die dem Ausdruck widersprachen.
78 expect(text).not.toContain('führt das Projekt nicht mit');
79 expect(text).not.toMatch(/Herkunft[^.]*nicht mit(?:geführt)?/);
80 expect(text).not.toMatch(/stammt, führt das Projekt nicht/);
81 });
82
83 it('verweist stattdessen auf die Spalte, die es tatsaechlich gibt', () => {
84 const roh = createStandardIntersectionProject('Wegherkunft', STICHTAG);
85 const projekt: Project = { ...roh, lageplan: groberLageplan(2) };
86 // Der Ausdruck fuehrt diese Spalte in der Rechenwegtabelle; der Bericht
87 // soll dorthin zeigen, statt das Gegenteil zu behaupten.
88 expect(berichtstexte(projekt)).toContain('Herkunft der Wege');
89 });
90
91 it('das Modell fuehrt die Herkunft je Beziehung wirklich mit', () => {
92 // Die Grundlage der beiden Zusicherungen oben. Faellt das Feld weg, sind
93 // sie gegenstandslos - dann muss dieser Test zuerst umfallen.
94 const projekt = createStandardIntersectionProject('Wegherkunft', STICHTAG);
95 expect(projekt.conflicts.length).toBeGreaterThan(0);
96 for (const konflikt of projekt.conflicts) {
97 expect(konflikt.wegnachweis).toBeDefined();
98 expect(['lageplan', 'handeingabe', 'unbestimmt']).toContain(konflikt.wegnachweis.herkunft);
99 }
100 });
101 });