frontend: Warnungs-Modell vereinheitlichen (strukturiert: Typ + Zeile)

TASKS Phase 1 (abgeschlossen). Warnungen sind jetzt maschinenlesbare Objekte
{type, line, ...data} statt vorformatierter Strings: der Renderer emittiert
{type:'mixedGate', line, label}; src/warnings.js `formatWarning(w, t)` macht
daraus an EINER Stelle den lokalisierten, HTML-escapten Anzeigetext. Damit sind
Typ und Zeilennummer sortier-/filter-/testbar, und Phase 2 (unbekannte
Statuszeichen -> {type:'unknownStatus', line, code}) dockt ohne Formatstreuung an.

tests/warnings.test.js + Mixed-Gate-Test im Renderer (29 Tests grün).
Ende-zu-Ende im Browser verifiziert (lokalisierte Warnung mit Zeile + Label).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-07-21 21:01:43 +02:00
co-authored by Claude Opus 4.8
parent 5905712aa5
commit 32a02021ed
6 changed files with 74 additions and 4 deletions
+14
View File
@@ -79,6 +79,20 @@ describe('renderTreeHtml — „Untergliederung fehlt" (Geister-Knoten, SPEC §5
});
});
describe('renderTreeHtml — strukturierte Warnungen', () => {
it('gemischte Gates ergeben eine {type:mixedGate, line, label}-Warnung', () => {
let {roots} = parse('- Eltern\n - und-Kind\n | oder-Kind');
const {warnings} = renderTreeHtml(roots, {t, showDiscarded: false, cheapPath: false, cheapSet: new Set()});
expect(warnings).toEqual([{type: 'mixedGate', line: 2, label: 'Eltern'}]);
});
it('einheitliche Gates ergeben keine Warnung', () => {
let {roots} = parse('- Eltern\n - a\n - b');
const {warnings} = renderTreeHtml(roots, {t, showDiscarded: false, cheapPath: false, cheapSet: new Set()});
expect(warnings).toEqual([]);
});
});
describe('renderTreeHtml — Moduswechsel ist CSS, nicht Renderer', () => {
it('erzeugt nie eine Modus-Klasse (vertical/kompakt) — die setzt app.js am Container', () => {
const {html} = renderExample();
+23
View File
@@ -0,0 +1,23 @@
import { describe, it, expect } from 'vitest';
import { formatWarning } from '../src/warnings.js';
/* Stub bildet key + interpolierte Variablen sichtbar ab, damit wir prüfen
können, welche Werte (inkl. Escaping) formatWarning durchreicht. */
const t = (key, vars) => `${key}|${JSON.stringify(vars)}`;
describe('formatWarning — vereinheitlichtes Warnungs-Modell', () => {
it('mixedGate reicht Zeile durch und HTML-escaped das Label', () => {
const out = formatWarning({type: 'mixedGate', line: 7, label: 'A & <B>'}, t);
expect(out).toBe('mixedWarn|{"line":7,"label":"A &amp; &lt;B&gt;"}');
});
it('unknownStatus reicht Zeile durch und escaped den Code', () => {
const out = formatWarning({type: 'unknownStatus', line: 3, code: '<'}, t);
expect(out).toBe('unknownStatusWarn|{"line":3,"code":"&lt;"}');
});
it('unbekannter Typ fällt auf eine generische, escapte Meldung zurück', () => {
expect(formatWarning({type: 'was?', line: 9}, t)).toBe('was? (9)');
expect(formatWarning({type: 'x'}, t)).toBe('x (?)');
});
});