lsa-planer
LSA-Planer Professional – Planungssoftware für Lichtsignalanlagen nach RiLSA 2015 und § 45 StVO. EUPL-1.2.
/ tests ui zahlenfeldMeldung.test.ts
| 1 | import { afterEach, describe, expect, it } from 'vitest'; |
| 2 | import { numberCell } from '@/ui/inputs'; |
| 3 | |
| 4 | /** |
| 5 | * Befund 66 zur Fassung 5.8.0. |
| 6 | * |
| 7 | * Die beiden Rueckfallwege von `numberCell` setzen den vorherigen Wert wieder |
| 8 | * in das Feld und sagen in der Meldung, welcher Wert das war. Beide bildeten |
| 9 | * diesen Satz aus `String(value)` - dieselbe Zeichenkette, die in das |
| 10 | * `input[type=number]` zurueckgeschrieben wird und dort den englischen |
| 11 | * Dezimalpunkt braucht. In der Meldung ist der Punkt falsch: Sie ist die |
| 12 | * einzige Rueckmeldung auf die abgelehnte Eingabe, und eine Sprachausgabe |
| 13 | * liest den Punkt als Satzende - "zwoelf Punkt fuenf" statt "zwoelf Komma |
| 14 | * fuenf". Dieselbe Datei begruendet das acht Zeilen vorher im Bereichshinweis |
| 15 | * ausdruecklich, und `mitEinheit()` in derselben Funktion formatiert bereits |
| 16 | * ueber `fmt.numShort`. |
| 17 | */ |
| 18 | |
| 19 | afterEach(() => { |
| 20 | document.body.replaceChildren(); |
| 21 | }); |
| 22 | |
| 23 | function letzteWarnung(): string { |
| 24 | const meldungen = [...document.querySelectorAll('.meldung-warnung')]; |
| 25 | return meldungen[meldungen.length - 1]?.textContent ?? ''; |
| 26 | } |
| 27 | |
| 28 | describe('Zahlenfeld: die Wiederherstellungsmeldung nennt den Wert in deutscher Schreibweise (Befund 66)', () => { |
| 29 | it('meldet beim geleerten Pflichtfeld "12,5" statt "12.5"', () => { |
| 30 | // Zwischenzeitfenster, Feld "Räumweg": aus dem Lageplan abgeleitete Wege |
| 31 | // haben zwei Nachkommastellen, und die Schrittweite 0,1 erzeugt sie auch |
| 32 | // ueber die Pfeiltasten. |
| 33 | let gemeldet: number | null = -1; |
| 34 | const feld = numberCell( |
| 35 | 12.5, |
| 36 | (wert) => { |
| 37 | gemeldet = wert; |
| 38 | }, |
| 39 | { min: 0, max: 100, step: 0.1, einheit: 'm' }, |
| 40 | ); |
| 41 | feld.setAttribute('aria-label', 'Räumweg'); |
| 42 | document.body.append(feld); |
| 43 | |
| 44 | feld.value = ''; |
| 45 | feld.dispatchEvent(new Event('change')); |
| 46 | |
| 47 | const meldung = letzteWarnung(); |
| 48 | expect(meldung).toContain('Der vorherige Wert 12,5 wurde wiederhergestellt'); |
| 49 | // Kein englischer Dezimalpunkt im vorgelesenen Satz. |
| 50 | expect(meldung).not.toMatch(/\d\.\d/); |
| 51 | // Das Feld selbst behaelt den Punkt: `input[type=number]` nimmt nur ihn an. |
| 52 | expect(feld.value, 'vorheriger Wert steht wieder im Feld').toBe('12.5'); |
| 53 | expect(gemeldet, 'ein abgelehnter Wert darf nicht weitergereicht werden').toBe(-1); |
| 54 | }); |
| 55 | |
| 56 | it('meldet bei unlesbarer Eingabe "0,75" statt "0.75"', () => { |
| 57 | /* |
| 58 | * Der zweite Rueckfallweg. Ein `input[type=number]` gibt eine unlesbare |
| 59 | * Eingabe als leere Zeichenkette heraus - jsdom wie der Browser. Um genau |
| 60 | * diesen Zweig zu erreichen, wird der Feldtyp fuer die Eingabe kurz auf |
| 61 | * `text` gestellt; der Empfaenger liest nur `input.value` und sieht davon |
| 62 | * nichts. |
| 63 | */ |
| 64 | const feld = numberCell(0.75, () => {}, { min: 0, max: 1, step: 0.05 }); |
| 65 | feld.setAttribute('aria-label', 'Lastzuganteil'); |
| 66 | document.body.append(feld); |
| 67 | |
| 68 | feld.setAttribute('type', 'text'); |
| 69 | feld.value = '12,5,3'; |
| 70 | feld.dispatchEvent(new Event('change')); |
| 71 | |
| 72 | const meldung = letzteWarnung(); |
| 73 | expect(meldung).toContain('Der vorherige Wert 0,75 gilt weiter'); |
| 74 | expect(meldung).not.toMatch(/\d\.\d/); |
| 75 | }); |
| 76 | |
| 77 | it('laesst die Wertangabe weg, wenn es gar keinen vorherigen Wert gab', () => { |
| 78 | // Gegenprobe: Bei `null` bleibt das Feld leer, und der Satz nennt keine |
| 79 | // Zahl - die Kennzeichnung als offene Pflichtangabe bleibt richtig. |
| 80 | const feld = numberCell(null, () => {}, { min: 0, max: 100 }); |
| 81 | document.body.append(feld); |
| 82 | |
| 83 | feld.value = ''; |
| 84 | feld.dispatchEvent(new Event('change')); |
| 85 | |
| 86 | expect(feld.value).toBe(''); |
| 87 | expect(feld.getAttribute('aria-invalid')).toBe('true'); |
| 88 | const meldung = letzteWarnung(); |
| 89 | expect(meldung).toContain('Das Feld darf nicht leer bleiben'); |
| 90 | expect(meldung, 'ohne vorherigen Wert steht keine Zahl im Satz').not.toMatch(/\d/); |
| 91 | }); |
| 92 | }); |