waffensachkunde

Waffensachkunde – Lernsoftware für die Sachkundeprüfung nach § 7 WaffG. Barrierefrei, offline, EUPL-1.2.

/ app tests ansicht.test.ts

4,2 KB Rohdatei
app/tests/ansicht.test.ts — 126 Zeilen
1 // @vitest-environment node
2 /**
3 * Die Stufenlogik der Anzeigegröße.
4 *
5 * Reine Rechnerei, ohne Fenster: welche Stufe auf welche folgt, wie
6 * unbrauchbare Werte bereinigt werden, wo die Grenzen liegen. Ob der Zoom im
7 * echten Fenster ankommt, misst `e2e/anzeigegroesse.spec.ts`.
8 */
9
10 import { describe, expect, it } from 'vitest';
11
12 import {
13 ANZEIGEGROESSEN,
14 ANZEIGEGROESSE_STANDARD,
15 anzeigegroesseBereinigen,
16 anzeigegroesseText,
17 groesser,
18 istGroesstmoeglich,
19 istKleinstmoeglich,
20 kleiner,
21 zoomfaktor,
22 } from '../src/shared/ansicht';
23
24 describe('Stufen', () => {
25 it('enthält die Vorgabe und reicht bis 400 Prozent', () => {
26 /* WCAG 1.4.4 verlangt, dass sich Text auf 200 Prozent vergrößern lässt,
27 ohne dass Inhalt oder Funktion verloren gehen. Weniger anzubieten wäre
28 ein Verstoß, den niemand sieht.
29
30 1.4.10 (Reflow) misst bei 400 Prozent auf 1280 Pixeln Fensterbreite,
31 also bei 320 CSS-Pixeln. Ohne eine 400er-Stufe wäre dieser Prüffall
32 mit Bordmitteln nicht herstellbar. */
33 expect(ANZEIGEGROESSEN).toContain(ANZEIGEGROESSE_STANDARD);
34 expect(Math.max(...ANZEIGEGROESSEN)).toBeGreaterThanOrEqual(400);
35 });
36
37 it('bietet zwischen 200 und 400 Prozent Zwischenstufen an', () => {
38 /* Ein Sprung von 200 auf 400 wäre eine Verdopplung in einem Klick: Wer
39 225 Prozent braucht, säße vor einer Skala, die ihn übergeht. */
40 const oben = ANZEIGEGROESSEN.filter((stufe) => stufe > 200 && stufe < 400);
41
42 expect(oben.length).toBeGreaterThanOrEqual(2);
43 });
44
45 it('steigt lückenlos an', () => {
46 const sortiert = [...ANZEIGEGROESSEN].sort((a, b) => a - b);
47
48 expect([...ANZEIGEGROESSEN]).toEqual(sortiert);
49 expect(new Set(ANZEIGEGROESSEN).size).toBe(ANZEIGEGROESSEN.length);
50 });
51 });
52
53 describe('anzeigegroesseBereinigen', () => {
54 it('lässt gültige Stufen stehen', () => {
55 for (const stufe of ANZEIGEGROESSEN) {
56 expect(anzeigegroesseBereinigen(stufe)).toBe(stufe);
57 }
58 });
59
60 it('nimmt für Unbrauchbares die Vorgabe', () => {
61 for (const wert of [undefined, null, 'gross', Number.NaN, {}, [], true]) {
62 expect(anzeigegroesseBereinigen(wert)).toBe(ANZEIGEGROESSE_STANDARD);
63 }
64 });
65
66 it('begrenzt nach oben und unten', () => {
67 expect(anzeigegroesseBereinigen(5000)).toBe(400);
68 expect(anzeigegroesseBereinigen(-10)).toBe(80);
69 });
70
71 it('rundet zur nächstkleineren Stufe ab', () => {
72 /* Nicht zur nächstgelegenen: Wer einen Zwischenwert gespeichert hat,
73 soll nicht plötzlich größer sehen als vorher. */
74 expect(anzeigegroesseBereinigen(149)).toBe(125);
75 expect(anzeigegroesseBereinigen(101)).toBe(100);
76 });
77 });
78
79 describe('Stufenwechsel', () => {
80 it('geht Schritt für Schritt hoch und wieder herunter', () => {
81 let wert: number = ANZEIGEGROESSE_STANDARD;
82 const hoch: number[] = [];
83 for (let i = 0; i < ANZEIGEGROESSEN.length + 3; i++) {
84 wert = groesser(wert);
85 hoch.push(wert);
86 }
87
88 expect(hoch.at(-1)).toBe(400);
89 expect(new Set(hoch).size).toBeLessThan(hoch.length); // bleibt oben stehen
90
91 let runter = 400;
92 for (let i = 0; i < ANZEIGEGROESSEN.length + 3; i++) {
93 runter = kleiner(runter);
94 }
95 expect(runter).toBe(80);
96 });
97
98 it('bleibt an den Enden stehen, statt umzuspringen', () => {
99 expect(groesser(400)).toBe(400);
100 expect(kleiner(80)).toBe(80);
101 expect(istGroesstmoeglich(400)).toBe(true);
102 expect(istKleinstmoeglich(80)).toBe(true);
103 expect(istGroesstmoeglich(200)).toBe(false);
104 expect(istGroesstmoeglich(100)).toBe(false);
105 });
106
107 it('kommt auch von einem ungültigen Ausgangswert weiter', () => {
108 expect(groesser(Number.NaN)).toBe(groesser(ANZEIGEGROESSE_STANDARD));
109 });
110 });
111
112 describe('Darstellung', () => {
113 it('rechnet Prozent in Chromiums Zoomfaktor um', () => {
114 expect(zoomfaktor(100)).toBe(1);
115 expect(zoomfaktor(200)).toBe(2);
116 expect(zoomfaktor(400)).toBe(4);
117 expect(zoomfaktor(80)).toBeCloseTo(0.8, 5);
118 });
119
120 it('schreibt Prozent aus, statt das Zeichen zu setzen', () => {
121 /* „125 %" liest ein Screenreader je nach Stimme als „125" – die
122 Einheit ginge verloren. */
123 expect(anzeigegroesseText(125)).toBe('125 Prozent');
124 expect(anzeigegroesseText(9999)).toBe('400 Prozent');
125 });
126 });