import { describe, expect, it } from 'vitest'; import { computeIntergreen } from '@/domain/rilsa/intergreen'; import { ceilSeconds, roundTo } from '@/domain/units'; import type { ClearingStream, EnteringStream } from '@/domain/rilsa/types'; /* * Befund 60, behoben in Fassung 5.10.0. * * Math.ceil liefert fuer jeden Wert zwischen -1 und 0 die NEGATIVE Null. * Sie rechnet sich wie 0, druckt sich aber nicht wie 0: Intl gibt "-0" aus, * und damit stand in der Zwischenzeitenmatrix der Planunterlage, im * Rechenweg und in der CSV-Ausgabe "-0" bzw. "-0 s" - eine Angabe, die vor * der Anordnungsbehoerde wie eine negative Zwischenzeit aussieht. */ const deutsch = new Intl.NumberFormat('de-DE', { maximumFractionDigits: 0 }); describe('Befund 60 - ceilSeconds liefert keine negative Null', () => { it('rundet Werte zwischen -1 und 0 auf die positive Null auf', () => { for (const wert of [-0.0001, -0.0937, -0.4505, -0.5, -0.999]) { expect(Object.is(ceilSeconds(wert), 0), String(wert)).toBe(true); } }); it('druckt die aufgerundete Null als "0" und nicht als "-0"', () => { expect(deutsch.format(ceilSeconds(-0.4505))).toBe('0'); }); it('laesst Vorzeichen und Betrag jedes anderen Wertes unberuehrt', () => { expect(ceilSeconds(-2.7)).toBe(-2); expect(ceilSeconds(0)).toBe(0); expect(ceilSeconds(3.0000000000000004)).toBe(3); expect(ceilSeconds(5.079)).toBe(6); }); it('belegt, dass roundTo die negative Null nicht abstreift - nur den Vorzeichenfall', () => { /* * NACHTRAG (Fassung 5.10.0): Der Docblock von ceilSeconds sagte, die * Nachbarzeile roundTo behandle "denselben Sonderfall seit jeher". Sie * behandelt einen anderen: Math.round(-0,5) ergibt -0, deshalb rundet * roundTo ueber den Betrag und setzt das Vorzeichen danach. Die negative * Null bleibt dabei stehen - dieser Fall haelt den berichtigten Satz fest. */ expect(Object.is(roundTo(-0.4, 0), -0)).toBe(true); expect(deutsch.format(roundTo(-0.4, 0))).toBe('-0'); expect(roundTo(-0.5, 0)).toBe(-1); }); it('gibt die Zwischenzeit einer knapp negativen Rechnung als 0 s aus', () => { /* * Ausloeser aus dem Befund: raeumender Fussgaengerstrom ohne Raeumweg * (tue = 0 s, tr = 0 s) gegen einen einfahrenden Kfz-Strom mit 5 m * Einfahrweg (te = 5/11,1 = 0,4505 s). raw = -0,4505 s. */ const raeumt: ClearingStream = { mode: 'fuss', movement: 'querung', clearingDistance: 0, vehicleClass: 'keine', vZul: 0, }; const faehrtEin: EnteringStream = { mode: 'kfz', movement: 'geradeaus', enteringDistance: 5, }; const ergebnis = computeIntergreen(raeumt, faehrtEin); expect(ergebnis.raw).toBeLessThan(0); expect(ergebnis.intergreen).toBe(0); expect(deutsch.format(ergebnis.intergreen)).toBe('0'); }); });