import { describe, expect, it } from 'vitest'; import { intergreenDetailCsv } from '@/services/export/csv'; import { buildSignalPlan } from '@/domain/plan/signalPlan'; import { createStandardIntersectionProject } from '@/domain/model/factory'; import type { Project } from '@/domain/model/project'; /** * Befund 58 - zweite Aufrufstelle. * * Im Fachkern entscheidet `ueberfahrzeitHerkunft` seit Befund 58 an * `vorgabewert` und `angesetzt`, ob eine Handeingabe uebernommen oder * verworfen wurde. `conflictsView.ts` gibt beide Angaben mit, die * Tabellenausgabe rief bis hierher nur mit `haltVorKnoten` und `vorgegeben` * auf - und wies eine VERWORFENE Handeingabe weiter als "an dieser Beziehung * von Hand eingetragen" aus, obwohl daneben die Gelbzeit stand. */ const STICHTAG = new Date('2026-01-01T12:00:00Z'); /** Zeilen der Zwischenzeit-Tabellenausgabe als Spaltenfelder. */ function tabelle(project: Project): { kopf: string[]; zeilen: string[][] } { const csv = intergreenDetailCsv(project, buildSignalPlan(project)); const [kopfzeile, ...rest] = csv.split('\r\n'); const zerlege = (zeile: string): string[] => (zeile.match(/("([^"]|"")*"|[^;]*)(;|$)/g) ?? []).map((feld) => feld.replace(/;$/, '').replace(/^"|"$/g, '').replace(/""/g, '"'), ); return { kopf: zerlege((kopfzeile ?? '').replace(/^/, '')), zeilen: rest.filter((z) => z.length > 0).map(zerlege), }; } /** Vorlage mit einer Ueberfahrzeit-Handeingabe an der ersten Beziehung. */ function mitHandeingabe(wert: number): Project { const basis = createStandardIntersectionProject('Handeingabe', STICHTAG); return { ...basis, conflicts: basis.conflicts.map((c, i) => (i === 0 ? { ...c, crossingTimeOverride: wert } : c)), }; } /** Die Zelle "Überfahrzeit-Herkunft" der ersten Beziehung. */ function herkunftsZelle(project: Project): string { const { kopf, zeilen } = tabelle(project); const spalte = kopf.indexOf('Überfahrzeit-Herkunft'); expect(spalte, 'Die Spalte fehlt').toBeGreaterThanOrEqual(0); const erste = project.conflicts[0]!; const von = project.signalGroups.find((g) => g.id === erste.fromId)!; const nach = project.signalGroups.find((g) => g.id === erste.toId)!; const zeile = zeilen.find((z) => z[0] === von.name && z[1] === nach.name)!; return zeile[spalte] ?? ''; } describe('Die Tabellenausgabe weist eine verworfene Ueberfahrzeit als verworfen aus', () => { it('nennt bei crossingTimeOverride 0 und vZul 50 km/h die Eingabe verworfen', () => { // 0 s liegt unter der Gelbzeit von 3 s bei 50 km/h; resolveCrossingTime // verwirft die Eingabe und rechnet mit 3 s weiter. const project = mitHandeingabe(0); const zelle = herkunftsZelle(project); expect(zelle).toContain('verworfen'); expect(zelle).not.toContain('von Hand eingetragen'); }); it('nennt eine uebernommene Handeingabe weiterhin als Handeingabe', () => { // 4 s liegt ueber der Gelbzeit von 3 s und wird angesetzt. const zelle = herkunftsZelle(mitHandeingabe(4)); expect(zelle).toBe('an dieser Beziehung von Hand eingetragen'); }); });