/* ===================================================================== ZAEHLT DER LAEUFER AUCH WIRKLICH ALLE? (25.09.2026) ===================================================================== Der naechtliche Lauf meldete am 25.09.2026 „37 Pruefungen sind rot". Acht davon waren gar nicht rot: Sie liefen fehlerfrei durch, Exitcode 0, keine einzige FEHL-Zeile -- aber `alles-pruefen.mjs` zaehlte bei ihnen NULL Einzelpruefungen, und „null Pruefungen ist ein Fehler" ist eine richtige Regel. DER GRUND WAR EIN GROSSBUCHSTABE. Der Zaehler suchte `(ok|FEHL)`; diese acht Dateien schreiben ` OK `. Zwei Schaeden auf einmal: 1. Ihre Punkte fehlten in der Gesamtzahl -- allein in fuenf der acht waren das 114 Stueck. Ausgerechnet die Zahl, die vor stillen Aussetzern schuetzen soll, war selbst eine Luecke. 2. Acht dauerhaft rote Eintraege in einer Notiz, die morgens gelesen wird. Eine Warnung, die immer kommt, ist keine mehr. WARUM ES DAFUER EINE PRUEFUNG GIBT UND NICHT NUR EINEN KOMMENTAR: Weil der Kommentar den naechsten Fall nicht verhindert. Morgen legt jemand eine Pruefdatei an, die ihre Ergebnisse wieder anders schreibt -- mit drei Leerzeichen, mit einem Haken, auf englisch -- und sie verschwindet genauso lautlos aus der Gesamtzahl. Diese Datei startet deshalb ein paar der schnellsten Pruefungen WIRKLICH und vergleicht, was der Ausdruck aus ihrer Ausgabe herausliest. DER AUSDRUCK WIRD AUS alles-pruefen.mjs GELESEN, nicht hier noch einmal hingeschrieben. Zwei Fassungen desselben Musters waeren die Sorte Dopplung, die genau dann auseinanderlaeuft, wenn es darauf ankommt. Aufrufen mit: node server/pruef-pruefzaehler.mjs ===================================================================== */ import { readFileSync } from "node:fs"; import { spawn } from "node:child_process"; import { join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; const WURZEL = join(dirname(fileURLToPath(import.meta.url)), ".."); let fehler = 0; const ok = (gut, text) => { if (!gut) fehler++; console.log(` ${gut ? "ok " : "FEHL"} ${text}`); }; /* ---- Den Ausdruck holen, den der Laeufer wirklich benutzt --------- */ const laeufer = readFileSync(join(WURZEL, "tools", "alles-pruefen.mjs"), "utf8"); const treffer = laeufer.match(/const einzeln = \(aus\.match\((\/.+?\/gm)\)/); if (!treffer) { console.log(" FEHL KONNTE NICHT NACHSEHEN: der Zaehl-Ausdruck steht nicht mehr da,"); console.log(" wo diese Pruefung ihn sucht (tools/alles-pruefen.mjs)."); console.log(" Das ist kein Befund am Programm -- diese Datei muss nachgezogen werden."); process.exit(1); } const quelle = treffer[1]; console.log(`Der Laeufer zaehlt mit: ${quelle}\n`); const bauen = () => new RegExp(quelle.slice(1, quelle.lastIndexOf("/")), "gm"); /* ---- Die schnellsten Vertreter beider Schreibweisen --------------- */ const PROBEN = [ { datei: "pruef-tippziele.mjs", schreibweise: "OK" }, { datei: "pruef-turn-wege.mjs", schreibweise: "OK" }, { datei: "pruef-leerzustand.mjs", schreibweise: "OK" }, { datei: "pruef-deutsche-texte.mjs", schreibweise: "ok" }, ]; const laufen = (datei) => new Promise((fertig) => { const kind = spawn(process.execPath, [join(WURZEL, "server", datei)], { cwd: WURZEL, stdio: ["ignore", "pipe", "pipe"] }); let aus = ""; kind.stdout.on("data", (d) => { aus += d; }); kind.stderr.on("data", (d) => { aus += d; }); const wecker = setTimeout(() => { try { kind.kill("SIGKILL"); } catch { /* weg */ } }, 120_000); kind.on("close", (code) => { clearTimeout(wecker); fertig({ aus, code }); }); kind.on("error", () => { clearTimeout(wecker); fertig({ aus, code: -1 }); }); }); console.log("=== Jede Schreibweise wird gezaehlt ==="); for (const p of PROBEN) { const r = await laufen(p.datei); const zahl = (r.aus.match(bauen()) || []).length; ok(zahl > 0, `${p.datei.padEnd(26)} schreibt "${p.schreibweise}" -> ${zahl} Punkte erkannt`); } /* ---- GEGENPROBE: der Ausdruck darf nicht alles zaehlen ------------ */ console.log("\n=== Gegenprobe: er zaehlt nicht wahllos mit ==="); const beispiel = [ "OK ohne Einrueckung ist kein Pruefpunkt", " OK zu weit eingerueckt", " OKAY ist kein eigenes Wort", " Ergebnis: alles gut", " ok ein echter", " OK auch ein echter", " FEHL ein dritter", ].join("\n"); const gezaehlt = (beispiel.match(bauen()) || []).length; ok(gezaehlt === 3, `von sieben Zeilen zaehlen genau die drei echten (${gezaehlt})`); /* Und er muss einen Aussetzer auch WIRKLICH sehen koennen. */ ok(((" ok etwas\n ok noch etwas").match(bauen()) || []).length === 2, "zwei Punkte werden als zwei gezaehlt"); ok((("kein einziger Punkt hier").match(bauen()) || []).length === 0, "und eine Ausgabe ohne Punkte als null -- sonst waere 'null ist ein Fehler' blind"); console.log(`\n${fehler === 0 ? "ALLES IN ORDNUNG" : fehler + " Fehler"}`); process.exit(fehler === 0 ? 0 : 1);