lsa-planer

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

/ tests domain projektUnberuehrt.test.ts

3,6 KB Rohdatei
tests/domain/projektUnberuehrt.test.ts — 108 Zeilen
1 import { describe, expect, it } from 'vitest';
2 import {
3 createEmptyProject,
4 createStandardIntersectionProject,
5 istUnberuehrt,
6 } from '@/domain/model/factory';
7 import { parseProject } from '@/domain/model/schema';
8
9 const DATUM = new Date('2026-01-01T00:00:00Z');
10
11 /*
12 * `istUnberuehrt` entscheidet, ob ein wiederhergestellter Sitzungsstand als
13 * ungespeicherte Arbeit gilt (Befund 20, siehe src/main.ts). Faellt die Antwort
14 * faelschlich auf "unberuehrt", verschwindet der Schutz vor dem Verwerfen; faellt
15 * sie faelschlich auf "beruehrt", kommt bei jedem zweiten Start eine Rueckfrage
16 * ueber eine Arbeit, die es nie gab.
17 *
18 * Der gefaehrliche der beiden Irrtuemer ist der erste. Die Faelle unten pruefen
19 * ihn deshalb Feld fuer Feld: Jede einzelne Eingabe muss reichen.
20 */
21
22 describe('Ist ein Projekt unberuehrt', () => {
23 it('sagt ja zu einem frisch angelegten Projekt', () => {
24 expect(istUnberuehrt(createEmptyProject())).toBe(true);
25 });
26
27 it('stoert sich nicht an Kennung und Zeitstempeln', () => {
28 // Sie fallen bei jedem Anlegen anders aus und sind keine Eingabe.
29 const frueher = createEmptyProject('Neues Projekt', DATUM);
30 const jetzt = createEmptyProject();
31 expect(frueher.id).not.toBe(jetzt.id);
32 expect(istUnberuehrt(frueher)).toBe(true);
33 });
34
35 it('sagt nein zu einem Projekt mit Signalgruppen', () => {
36 expect(istUnberuehrt(createStandardIntersectionProject('Knoten', DATUM))).toBe(false);
37 });
38
39 it.each([
40 [
41 'Projektbezeichnung',
42 (p: ReturnType<typeof createEmptyProject>) => ({
43 ...p,
44 meta: { ...p.meta, name: 'Bahnhofstrasse' },
45 }),
46 ],
47 [
48 'Auftraggeber',
49 (p: ReturnType<typeof createEmptyProject>) => ({
50 ...p,
51 meta: { ...p.meta, client: 'Stadt Musterhausen' },
52 }),
53 ],
54 [
55 'Knotenpunktbezeichnung',
56 (p: ReturnType<typeof createEmptyProject>) => ({
57 ...p,
58 intersection: { ...p.intersection, name: 'Hauptstrasse / Bahnhofstrasse' },
59 }),
60 ],
61 [
62 'zulaessige Hoechstgeschwindigkeit',
63 (p: ReturnType<typeof createEmptyProject>) => ({
64 ...p,
65 intersection: { ...p.intersection, vZul: 30 },
66 }),
67 ],
68 [
69 'Anlagenart',
70 (p: ReturnType<typeof createEmptyProject>) => ({
71 ...p,
72 anlagenart: 'fussgaengerschutzanlage' as const,
73 }),
74 ],
75 [
76 'Umlaufzeit von Hand',
77 (p: ReturnType<typeof createEmptyProject>) => ({
78 ...p,
79 program: { ...p.program, manualCycleTime: 60 },
80 }),
81 ],
82 [
83 'Bewertungsverfahren',
84 (p: ReturnType<typeof createEmptyProject>) => ({
85 ...p,
86 settings: { ...p.settings, serviceLevelScale: 'HCM' as const },
87 }),
88 ],
89 ])('sagt nein, sobald nur die %s eingetragen ist', (_was, aendere) => {
90 expect(istUnberuehrt(aendere(createEmptyProject()))).toBe(false);
91 });
92
93 it('sagt ja zu einem leeren Projekt, das durch das Einlesen gegangen ist', () => {
94 /*
95 * Der eigentliche Weg: Der Sitzungsspeicher gibt das Projekt nicht als
96 * dasselbe Objekt zurueck, sondern als eingelesene Fassung. Baut
97 * `parseProject` die Felder in anderer Reihenfolge auf als
98 * `createEmptyProject`, muss der Vergleich das aushalten - sonst gaelte
99 * jeder Wiederanlauf als beruehrt, und die Antwort waere zufaellig richtig.
100 */
101 const eingelesen = parseProject(
102 JSON.parse(JSON.stringify(createEmptyProject('Neues Projekt', DATUM))),
103 DATUM,
104 );
105 expect(eingelesen.issues.filter((i) => i.severity === 'fehler')).toEqual([]);
106 expect(istUnberuehrt(eingelesen.project)).toBe(true);
107 });
108 });