lsa-planer
LSA-Planer Professional – Planungssoftware für Lichtsignalanlagen nach RiLSA 2015 und § 45 StVO. EUPL-1.2.
/ tests ui einmuendungPhasenname.test.ts
| 1 | import { describe, expect, it } from 'vitest'; |
| 2 | import { ASSISTENT_VORGABE, projektAusAngaben } from '@/ui/assistent'; |
| 3 | import type { AssistentAngaben } from '@/ui/assistent'; |
| 4 | import type { Project } from '@/domain/model/project'; |
| 5 | |
| 6 | /** |
| 7 | * Befund 53: Phasenname der dreiarmigen Einmuendung. |
| 8 | * |
| 9 | * Die Einmuendung uebernahm die Phasenliste der Kreuzung unveraendert und hiess |
| 10 | * damit "Phase 2 - Ost/West", obwohl die Anlage nur die Zufahrten Nord, Sued |
| 11 | * und Ost hat. Der Name ist kein Anzeigetext, sondern ein Datum: Er geht ueber |
| 12 | * createPhase in das Projekt, ueberlebt Speichern und Oeffnen und steht in |
| 13 | * Phasenansicht, Signalzeitenplan und gedruckter Planunterlage. Eine Unterlage |
| 14 | * nach Paragraph 45 StVO nennt dort einen Arm, den es nicht gibt. |
| 15 | * |
| 16 | * Die Benennung im selben Schalter ist armbezogen - der fuenfte Arm heisst |
| 17 | * "Phase 3 - Nordost". Nach derselben Regel heisst die zweite Phase der |
| 18 | * Einmuendung "Ost". |
| 19 | */ |
| 20 | |
| 21 | const FESTES_DATUM = new Date('2026-01-01T00:00:00Z'); |
| 22 | |
| 23 | function baue(teil: Partial<AssistentAngaben>): Project { |
| 24 | return projektAusAngaben({ ...ASSISTENT_VORGABE, ...teil }, 'Pruefung', FESTES_DATUM); |
| 25 | } |
| 26 | |
| 27 | /** Namen der Zufahrten, die eine Phase im Namen fuehrt - Nord, Süd, Ost, West. */ |
| 28 | function genannteArme(name: string): readonly string[] { |
| 29 | return ['Nord', 'Süd', 'Ost', 'West'].filter((arm) => |
| 30 | // "Nordost" darf nicht als "Nord" durchgehen. |
| 31 | new RegExp(`(^|[^A-Za-zÄÖÜäöüß])${arm}($|[^A-Za-zÄÖÜäöüß])`).test(name), |
| 32 | ); |
| 33 | } |
| 34 | |
| 35 | describe('Phasennamen des gefuehrten Einstiegs nennen nur vorhandene Zufahrten', () => { |
| 36 | it('nennt bei der Einmuendung keinen Westarm', () => { |
| 37 | const projekt = baue({ form: 'einmuendung' }); |
| 38 | expect(projekt.intersection.arms.map((a) => a.name)).toEqual(['Nord', 'Süd', 'Ost']); |
| 39 | expect(projekt.phases.map((p) => p.name)).toEqual(['Phase 1 – Nord/Süd', 'Phase 2 – Ost']); |
| 40 | }); |
| 41 | |
| 42 | it('nennt bei jeder Knotenform nur Arme, die die Anlage hat', () => { |
| 43 | for (const form of ['kreuzung', 'einmuendung', 'fuenfarmig'] as const) { |
| 44 | const projekt = baue({ form }); |
| 45 | const vorhanden = new Set(projekt.intersection.arms.map((a) => a.name)); |
| 46 | for (const phase of projekt.phases) { |
| 47 | for (const arm of genannteArme(phase.name)) { |
| 48 | expect(vorhanden.has(arm), `${form}: "${phase.name}" nennt "${arm}"`).toBe(true); |
| 49 | } |
| 50 | } |
| 51 | } |
| 52 | }); |
| 53 | |
| 54 | it('laesst Kreuzung und fuenfarmigen Knotenpunkt bei "Ost/West"', () => { |
| 55 | // Dort gibt es einen Westarm; die Namen bleiben, wie sie waren. |
| 56 | expect(baue({ form: 'kreuzung' }).phases.map((p) => p.name)).toEqual([ |
| 57 | 'Phase 1 – Nord/Süd', |
| 58 | 'Phase 2 – Ost/West', |
| 59 | ]); |
| 60 | expect(baue({ form: 'fuenfarmig' }).phases.map((p) => p.name)).toEqual([ |
| 61 | 'Phase 1 – Nord/Süd', |
| 62 | 'Phase 2 – Ost/West', |
| 63 | 'Phase 3 – Nordost', |
| 64 | ]); |
| 65 | }); |
| 66 | }); |