lsa-planer

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

/ vitest.config.ts

8,6 KB Rohdatei
vitest.config.ts — 173 Zeilen
1 import { coverageConfigDefaults, defineConfig } from 'vitest/config';
2 import { fileURLToPath, URL } from 'node:url';
3
4 /*
5 * DIE ABDECKUNGSMESSUNG - Umfang, Ausnahme, Schwellen.
6 *
7 * Bis 5.13.0 mass sie nur `src/domain/**` und `src/services/**`, und Schwellen
8 * gab es keine. Beides ist geaendert; die Begruendung steht hier, weil sie an
9 * keiner anderen Stelle sinnvoll steht.
10 * `tests/tools/abdeckungsmessung.test.ts` haelt die Zusagen dieses
11 * Kommentars fest - es faehrt keine Messung, sondern prueft Datei fuer Datei,
12 * dass der Umfang jede Quelldatei des Baumes erfasst, dass jeder Bereich eine
13 * Schwelle hat, dass keine gesenkt wurde und dass die Schnellstufe die Messung
14 * ueberhaupt faehrt.
15 *
16 * WAS GEMESSEN WIRD. Alles, was ausgeliefert wird oder ein versioniertes
17 * Erzeugnis herstellt: `src/**` (Renderer samt Oberflaeche, Ausdruck und
18 * Einstiegspunkt), `shared/**` (die IPC-Kanaele), `electron/**` (Hauptprozess)
19 * und `tools/**` (erzeugt `beispiele/*.svg`).
20 *
21 * WAS NICHT GEMESSEN WIRD - und warum das keine Beschoenigung ist:
22 *
23 * - `scripts/*.mjs` (clean, lizenztexte, pruefsummen) laufen als EIGENER
24 * Prozess. `tests/tools/` startet sie mit `spawnSync` und misst ihre
25 * Wirkung; die v8-Messung dieses Prozesses sieht davon nichts und wuerde
26 * sie mit 0 % fuehren. Eine Null, die nur sagt "hier misst das Werkzeug
27 * nicht", verwaessert jede Zahl daneben.
28 *
29 * - `electron/preload.ts` ist die einzige namentliche Ausnahme. Die Datei
30 * laeuft ausschliesslich im Preload-Zusammenhang von Electron unter
31 * `sandbox: true` und ruft beim Laden `contextBridge.exposeInMainWorld` auf;
32 * unter Vitest ist sie nicht einbindbar. Ihre 0 % waeren keine Messung,
33 * sondern eine Eigenschaft des Messgeraets - mitgezaehlt druecken sie
34 * `electron/**` von 83,58 auf 79,02 % und setzten die Schwelle fuer die
35 * sechs messbaren Dateien um viereinhalb Punkte zu tief. Geprueft ist sie
36 * trotzdem, an zwei Stellen: `tests/electron/brueckeVersion.test.ts` liest
37 * ihren Quelltext, und `e2e/rauchtest.spec.ts` prueft am GEBAUTEN Stand,
38 * dass die Bruecke vollstaendig freigegeben ist. Der Test zur
39 * Abdeckungsmessung laesst die Ausnahme nur gelten, solange diese beiden
40 * Wachen stehen.
41 *
42 * WAS DIE MESSUNG VERZERRT - benannt, nicht weggerechnet:
43 *
44 * - `electron/main.ts` steht bei 74,59 %. Die Luecke ist fast vollstaendig
45 * `createWindow` samt seinen Ereignisbehandlungen (`render-process-gone`,
46 * `zoom-changed`, `unresponsive`). Sie brauchen ein laufendes Fenster.
47 *
48 * HIER STANDEN AUCH `will-navigate` UND `setWindowOpenHandler`, mit dem
49 * Zusatz "genau das prueft `e2e/rauchtest.spec.ts` am gebauten Stand".
50 * GEMESSEN: Der Rauchtest hatte sechs Faelle, und das Wort "navigate" kam
51 * darin nicht vor. Eine Abdeckungsausnahme, gedeckt von einem Test, den es
52 * nicht gab - und das an den beiden Wachen, die verhindern, dass das
53 * Programm verlassen wird.
54 *
55 * Beide sind seither anders gebaut: Die Entscheidung steht als reine
56 * Funktion in `electron/navigation.ts`, wird von
57 * `tests/tools/navigationGrenze.test.ts` erschoepfend geprueft und faellt
58 * damit IN die Abdeckung; in `main.ts` blieb nur die Verdrahtung. Dass sie
59 * greift, prueft der Rauchtest jetzt wirklich - mit einer `http:`-Adresse,
60 * weil eine `https:`-Adresse bei jedem Lauf einen Browser oeffnen wuerde.
61 *
62 * - `src/main.ts` steht bei 81,38 %. Ungemessen sind die Verdrahtungen der
63 * Dateibefehle (Oeffnen, Speichern, Speichern unter); sie brauchen die
64 * Desktop-Bruecke und einen Dateidialog.
65 *
66 * - `src/platform/**` sind sechs ausfuehrbare Zeilen und zwei Funktionen in
67 * einer sonst reinen Typdatei. Die 66,66 % entstehen daraus, dass
68 * `hasDesktopBridge` von niemandem aufgerufen wird. Die Zahl ist richtig,
69 * aber sie sagt ueber die Pruefdichte nichts - eine einzige Zeile
70 * verschiebt sie um 16 Punkte.
71 *
72 * WIE DIE SCHWELLEN ENTSTANDEN SIND. Eine Schwelle hat eine Aufgabe: fallen,
73 * wenn die Abdeckung SINKT. Sie steht deshalb nicht auf einer runden Zahl,
74 * sondern knapp unter dem gemessenen Stand - abgerundet auf eine
75 * Nachkommastelle, davon noch ein Zehntelpunkt Luft. Je Bereich eine eigene
76 * Schwelle, sonst deckt `src/domain/**` die Oberflaeche zu. Die Werte unten
77 * sind am Stand 5.13.0 gemessen.
78 *
79 * WARUM UEBERHAUPT LUFT. Gar keine waere unzuverlaessig: Vier Laeufe ueber
80 * denselben Baum lieferten fuer Zeilen und Funktionen jedes Mal dieselben
81 * Zahlen, bei den ZWEIGEN aber wechselnde - `src/app/**` zaehlte zweimal 219
82 * von 238 und zweimal 218 von 237, also 92,01 gegen 91,98 %. Die Luft deckt
83 * diese Streuung ab und sonst wenig: Sie betraegt einen bis zwei
84 * Zehntelpunkte, in `src/domain/**` achtzehn Zeilen von 9803, in `src/ui/**`
85 * zwanzig von 11544. Mehr waere die Erlaubnis, Pruefung abzubauen.
86 *
87 * WELCHE SCHWELLENARTEN. `lines` und `statements` liefern unter dem
88 * v8-Anbieter in JEDEM Bereich denselben Wert (nachgemessen; v8-to-istanbul
89 * bildet je Anweisung genau einen Zeilenbereich). Deshalb steht hier nur
90 * `lines` - eine zweite Zahl daneben bewachte dasselbe zweimal. `branches` und
91 * `functions` sagen etwas anderes und stehen einzeln.
92 *
93 * NEU MESSEN: Wert im Zweifel auf 100 setzen, `npm run test:coverage` fahren
94 * und die Zeile "ERROR: Coverage for ... does not meet ..." lesen - sie nennt
95 * den gemessenen Wert je Bereich. Kein `thresholds.autoUpdate`: Das schriebe
96 * waehrend des pre-commit-Hakens in diese Datei und veraenderte die Wache
97 * unbemerkt.
98 */
99 export default defineConfig({
100 resolve: {
101 alias: {
102 '@': fileURLToPath(new URL('./src', import.meta.url)),
103 '@shared': fileURLToPath(new URL('./shared', import.meta.url)),
104 },
105 },
106 test: {
107 globals: true,
108 environment: 'node',
109 include: ['tests/**/*.test.ts'],
110 environmentMatchGlobs: [
111 ['tests/ui/**', 'jsdom'],
112 ['tests/export/**', 'jsdom'],
113 ],
114 coverage: {
115 provider: 'v8',
116 include: ['src/**', 'shared/**', 'electron/**', 'tools/**'],
117 exclude: [...coverageConfigDefaults.exclude, 'electron/preload.ts'],
118 reporter: ['text', 'html'],
119 /*
120 * Auch bei rotem Lauf messen.
121 *
122 * Ohne diese Zeile bricht vitest nach einem gefallenen Fall ab, ohne
123 * Bericht und ohne Vergleich mit den Schwellen (nachgefahren am
124 * 07.09.2026). Ein roter Lauf faellt ohnehin - aber solange ein FREMDER
125 * Fall rot ist, liesse sich nicht mehr belegen, dass die Schwellen halten,
126 * und genau das braucht man waehrend einer Behebung.
127 */
128 reportOnFailure: true,
129 thresholds: {
130 // Auffangnetz fuer alles, was unten keinen eigenen Eintrag hat - etwa
131 // eine neue Datei unmittelbar unter src/.
132 lines: 93.4,
133 branches: 89.0,
134 functions: 90.4,
135
136 'src/domain/**': { lines: 96.3, branches: 91.4, functions: 97.1 },
137 'src/services/**': { lines: 95.7, branches: 89.8, functions: 97.6 },
138 'src/app/**': { lines: 94.4, branches: 91.8, functions: 93.7 },
139 'src/render/**': { lines: 99.1, branches: 92.5, functions: 99.9 },
140 'src/ui/**': { lines: 91.3, branches: 86.0, functions: 84.1 },
141
142 // Sechs Zeilen, zwei Funktionen - siehe "Was die Messung verzerrt".
143 // Der Eintrag steht trotzdem hier: unter dem Auffangnetz waere der
144 // schwaechste Bereich des Baumes unsichtbar.
145 'src/platform/**': { lines: 66.5, branches: 49.9, functions: 49.9 },
146
147 // Der Einstiegspunkt des Renderers, als einzelne Datei.
148 'src/main.ts': { lines: 81.2, branches: 75.6, functions: 74.9 },
149
150 // shared/ipc.ts hat keine Zweige und keine Funktionen; 0 von 0 zaehlt
151 // istanbul als 100 %. Die Schwelle greift, sobald dort ein
152 // ungeprueftes Stueck Ablauflogik entsteht.
153 'shared/**': { lines: 99.9, branches: 99.9, functions: 99.9 },
154
155 // Ohne preload.ts, siehe oben.
156 'electron/**': { lines: 83.4, branches: 84.6, functions: 79.3 },
157
158 /*
159 * MIT 5.43.0 GESENKT, und zwar durch eine Behebung: Das Werkzeug gibt
160 * die Hinweise der Ableitung aus, und der Hinweis "einfahrweg-null"
161 * entstand an jeder Furt, solange der Einfahrweg einer Querung an der
162 * Zeichenrichtung hing. Seit die Vermessung die unguenstigere
163 * Gehrichtung nimmt, gibt es ihn dort nicht mehr; die Ausgabeschleife
164 * und der Zweig "keine Beziehung" werden vom Lauf des Werkzeugs nicht
165 * mehr genommen. Gemessen am 18.09.2026: 99,0 % Zeilen und 88,67 %
166 * Zweige statt 99,3 % und 89,5 %. Der Kode bleibt, denn ein Hinweis
167 * kann wiederkommen; die Schwelle folgt der Messung.
168 */
169 'tools/**': { lines: 98.9, branches: 88.5, functions: 99.9 },
170 },
171 },
172 },
173 });