Vier rote Pruefungen -- drei Phantome und ein echtes Gewicht

Weiter durch die rote Liste. Drei der vier Befunde zeigten auf
gesunden Code; die Pruefungen selbst waren seit einem Umbau nicht
nachgezogen worden.

pruef-schritt (2 rot -> 71 gruen statt 47)
  Meldete "1 von 6 Kategorien". Die Karte geht seit dem 01.10.2026
  gefiltert auf ("zugetragen"), Bloecke ohne solche Punkte werden gar
  nicht gezeichnet. Die Pruefung zaehlte danach alle. Schlimmer: Weil
  dann kein Block mehr zugeklappt war, lief der Klick auf einen
  zugeklappten 30 Sekunden in die Frist und riss den Lauf mit -- 24 von
  71 Pruefungen liefen nie. Jetzt wird erst die Vorgabe geprueft (sie
  ist eine Zusage), dann auf "Alle" gestellt.

pruef-glocke (1 rot -> 34 gruen)
  Meldete "auf der Anmeldeseite steht der Knopf". Gemessen landete sie
  auf start.html: Dieselbe Seite war eine Zeile zuvor angemeldet durch
  zwanzig Arbeitsseiten gelaufen, und angemeldet fuehrt /workspace/
  nicht zur Wand. Jetzt eigener Kontext ohne Keks -- und davor die
  Zeile, dass die Wand wirklich erreicht wurde.

pruef-zeichen (1 rot -> 8 gruen)
  Meldete content: "·" als Kodierungstruemmer. Die Bytes sind C2 B7,
  also korrektes UTF-8; der Mittelpunkt ist ein begruendeter Trennpunkt
  (seit 03.10.). Die Regel stammt aus einer Zeit, in der sie selbst
  festhielt: "KEINE einzige benutzt ein Zeichen aus diesem Block."
  Jetzt eine benannte Ausnahme MIT Veraltungsschutz: Jedes Zeichen
  darin muss wirklich vorkommen, sonst wird die Ausnahme rot.

pruef-tempo-workspace (1 rot -> 9 gruen) -- DER ECHTE BEFUND
  uebersicht.html 959 KB, bereich.html?b=live 1094 KB bei einer Grenze
  von 900. Die Pruefung sagt jetzt auch, WORAN es liegt, und die
  Antwort war eindeutig: ZWEI Buehnenbilder auf einer Seite, die eines
  zeigt (281 KB studio + 262 KB portal).

  Ursache: start.css traegt an body.start::before einen Rueckfall
  (studio), und kopf.js setzt `data-buehne` erst, wenn die Seite steht.
  Bis dahin ist der Rueckfall geholt -- auf 43 von 45 Seiten.

  Jetzt steht die Szene fest im <body>, erzeugt aus bereiche.js
  (tools/buehne-festschreiben.mjs, 20 Seiten). bereich.html bedient
  fuenf Bretter und kann das nicht; sie bekommt ein kleines Skript
  gleich hinter <body>, das die Szene aus `?b=` setzt, bevor gezeichnet
  wird. Gemessen: 1094 -> 879 KB, und die Grenze haelt wieder.

  DIE ZUORDNUNG STEHT DAMIT AN ZWEI STELLEN. Das ist nur vertretbar,
  weil sie nicht auseinanderlaufen kann: pruef-buehnen-fest.mjs (neu,
  13 Pruefungen) haelt HTML gegen bereiche.js, prueft die Lage des
  Skripts und dass jede genannte Szene eine Regel hat.

  Dabei gefunden und berichtigt -- zweimal an mir selbst: Der erste
  Entwurf verglich Szenen mit Dateinamen und meldete teamlage.html
  ("eingang") als Fehler; die Szene gibt es, ihre Regel zeigt nur auf
  ein crew-Bild. Und der Lage-Anker suchte `data-buehne`, das Skript
  schreibt `dataset.buehne` -- indexOf gab -1, die Rechnung wurde
  negativ und meldete "-2276 Zeichen dahinter".

Gegenproben gefahren: Szene verschoben -> rot mit Abstand; Ausnahme
verwaist -> rot; erfundene Szene -> erkannt.
Dazu gruen: css-klassen, workspace-seiten, neue-seiten, haus-trennung,
kopfleiste-farbe.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-10-07 13:05:54 +02:00
co-authored by Claude Opus 5
parent 14fa825848
commit da7508b6ce
52 changed files with 1132 additions and 718 deletions
+183
View File
@@ -0,0 +1,183 @@
/* =====================================================================
DIE SZENE STEHT FEST IM DOKUMENT -- und stimmt mit bereiche.js
=====================================================================
WARUM ES DIESE PRUEFUNG GIBT (07.10.2026)
`pruef-tempo-workspace` meldete zwei Seiten ueber 900 KB. Die
Ursache war nicht ein zu grosses Bild, sondern ZWEI: `start.css`
traegt an `body.start::before` einen Rueckfall (das Studio-Bild),
und `kopf.js` setzt `data-buehne` erst, nachdem die Seite steht.
Bis dahin hat der Browser den Rueckfall laengst geholt -- auf 43
von 45 Seiten, rund 260 KB je Aufruf, fuer ein Bild, das niemand
zu sehen bekommt.
Seit heute steht die Szene fest im <body>. Damit gibt es die
Zuordnung an ZWEI Stellen: in bereiche.js (wo sie gepflegt wird)
und im Dokument (wo sie frueh genug ankommt).
EINE ABSCHRIFT MIT WAECHTER IST ETWAS ANDERES ALS EINE ABSCHRIFT.
Diese Datei haelt beide gegeneinander. Wer in bereiche.js eine
Szene aendert und die HTML vergisst, bekommt einen roten Lauf --
und nicht eine Seite, die seit Wochen das falsche Bild zeigt und
dazu ein zweites laedt.
NICHT BETROFFEN ist bereich.html: Dort haengt die Szene am
`?b=`-Parameter (vier verschiedene), sie kann also nicht fest im
Dokument stehen. Das steht hier ausdruecklich und nicht als
stille Luecke.
Aufrufen mit: node server/pruef-buehnen-fest.mjs
===================================================================== */
import { readFileSync, existsSync, readdirSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const HIER = dirname(fileURLToPath(import.meta.url));
const SEITEN = join(HIER, "..", "workspace");
let geprueft = 0, fehler = 0;
const ok = (b, t) => { geprueft++; console.log((b ? " ok " : " FEHL ") + t); if (!b) fehler++; };
/* ---- Die Zuordnung aus bereiche.js --------------------------------- */
const quelle = readFileSync(join(SEITEN, "assets", "js", "bereiche.js"), "utf8");
const ausKachel = new Map();
const mitParameter = new Set();
for (const m of quelle.matchAll(/ziel:\s*'([^']+)'\s*,\s*szene:\s*'([^']+)'/g)) {
const [, ziel, szene] = m;
if (ziel.includes("?")) { mitParameter.add(ziel.split("?")[0]); continue; }
if (ausKachel.has(ziel) && ausKachel.get(ziel) !== szene) ausKachel.set(ziel, null);
else if (!ausKachel.has(ziel)) ausKachel.set(ziel, szene);
}
console.log("\n=== 1. Die Zuordnung ist ueberhaupt lesbar ===\n");
/* DER DRITTE AUSGANG: Faende das Muster nichts, waere alles darunter
trivial gruen -- „keine Abweichung" auf einer leeren Liste. */
ok(ausKachel.size >= 15,
`${ausKachel.size} Seiten mit fester Szene in bereiche.js gefunden`);
ok(mitParameter.size >= 1,
`und ${mitParameter.size} Seite(n) mit Parameter, die keine feste haben kann `
+ `(${[...mitParameter].join(", ")})`);
console.log("\n=== 2. Jede dieser Seiten traegt sie im Dokument ===\n");
let stimmt = 0;
const abweichend = [];
for (const [datei, szene] of ausKachel) {
if (!szene) continue;
const pfad = join(SEITEN, datei);
if (!existsSync(pfad)) { abweichend.push(`${datei}: Datei fehlt`); continue; }
const text = readFileSync(pfad, "utf8");
const b = text.match(/<body class="start"[^>]*>/);
const steht = b?.[0].match(/data-buehne="([^"]+)"/)?.[1] ?? null;
if (steht === szene) stimmt++;
else abweichend.push(`${datei}: Dokument "${steht}" gegen bereiche.js "${szene}"`);
}
/* DIE ZAHL GEHOERT IN DIE BEDINGUNG -- sonst waere „keine Abweichung"
auch dann wahr, wenn gar nichts geprueft wurde. */
ok(stimmt >= 15 && abweichend.length === 0,
`${stimmt} Seiten tragen ihre Szene fest und richtig`
+ (abweichend.length ? `:\n ` + abweichend.slice(0, 6).join("\n ") : ""));
console.log("\n=== 2b. Und die Seite mit Parameter setzt sie frueh genug ===\n");
{
/* bereich.html bedient fuenf Bretter; welches gemeint ist, steht erst
in der Adresse. Sie traegt deshalb ein kleines Skript GANZ OBEN im
Dokument, das die Szene setzt, bevor gezeichnet wird -- sonst holt
der Browser erst den Rueckfall und dann das richtige Bild
(gemessen: 1094 KB statt 879 KB).
Die Zuordnung steht damit an zwei Stellen. Hier wird sie
gegeneinander gehalten. */
const html = readFileSync(join(SEITEN, "bereich.html"), "utf8");
const ausSeite = new Map([...html.matchAll(/(\w+):\s*"([a-z-]+)"/g)]
.filter((m) => /SZENE\s*=|live|community|technik|schutz|agentur/.test(m[0]))
.map((m) => [m[1], m[2]]));
const ausBereiche = new Map([...quelle.matchAll(
/ziel:\s*'bereich\.html\?b=([a-z]+)'\s*,\s*szene:\s*'([a-z-]+)'/g)]
.map((m) => [m[1], m[2]]));
ok(ausBereiche.size >= 4,
`bereiche.js nennt ${ausBereiche.size} Bretter mit Szene`);
/* FRUEH GENUG heisst: vor allen anderen Skripten und ohne defer.
Ein `defer` hier waere derselbe Fehler noch einmal, nur eine Ebene
tiefer -- und man saehe ihn nicht. */
/* `dataset.buehne` und nicht `data-buehne`: Das Skript setzt die
Eigenschaft, es schreibt kein Attribut hin. Mein erster Anker war
die Schreibweise aus dem HTML -- `indexOf` gab -1 zurueck, die
Rechnung wurde negativ, und die Zeile meldete „-2276 Zeichen
dahinter". Ein Suchbegriff, den es nicht gibt, ist kein Befund
ueber die Seite, sondern einer ueber die Pruefung. */
const stelleSkript = html.indexOf("dataset.buehne");
const stelleBody = html.indexOf("<body");
ok(stelleSkript > stelleBody && stelleSkript - stelleBody < 2000,
`das Skript steht gleich hinter <body> (${stelleSkript - stelleBody} Zeichen dahinter)`);
ok(!/<script[^>]*\bdefer\b[^>]*>[^<]*dataset\.buehne/s.test(html),
"und nicht mit defer -- sonst kaeme es zu spaet");
const uneinig = [];
for (const [brett, szene] of ausBereiche) {
if (ausSeite.get(brett) !== szene) {
uneinig.push(`${brett}: Seite "${ausSeite.get(brett)}" gegen bereiche.js "${szene}"`);
}
}
ok(ausBereiche.size > 0 && uneinig.length === 0,
`alle ${ausBereiche.size} Bretter stimmen mit bereiche.js ueberein`
+ (uneinig.length ? `: ${uneinig.join(", ")}` : ""));
}
console.log("\n=== 3. Der Rueckfall bleibt -- fuer die eine Seite, die ihn braucht ===\n");
const stil = readFileSync(join(SEITEN, "assets", "css", "start.css"), "utf8");
ok(/body\.start::before[^}]*background-image:\s*url\(/s.test(stil),
"start.css hat weiterhin einen Rueckfall fuer Seiten ohne feste Szene");
console.log("\n=== 4. Gegenprobe: wuerde eine Abweichung auffallen? ===\n");
{
/* Dieselbe Rechnung auf einem erfundenen Paar -- ohne sie hiesse
„keine Abweichung" nur, dass der Vergleich nie etwas findet. */
const erfunden = [["probe.html", "wald", "garage"]];
const gefunden = erfunden.filter(([, imDokument, inKachel]) => imDokument !== inKachel);
ok(gefunden.length === 1, "ein erfundenes Paar mit zwei Szenen wird als Abweichung erkannt");
const gleich = [["probe.html", "wald", "wald"]].filter(([, a, b2]) => a !== b2);
ok(gleich.length === 0, "und ein uebereinstimmendes Paar nicht");
}
console.log("\n=== 5. Und keine Seite behauptet eine Szene, die es nicht gibt ===\n");
{
/* GEPRUEFT WIRD GEGEN DIE REGELN IM STIL, nicht gegen Dateinamen.
Der erste Entwurf verglich mit `buehne-<name>-breit.webp` und
meldete prompt teamlage.html mit „eingang" als Fehler. Der Fund
war falsch und der Weg dorthin lehrreich: Die Szene „eingang" gibt
es sehr wohl -- ihre Regel zeigt nur auf ein `crew-buehne-*`-Bild,
weil diese Seite zum Haus von Team Dogi gehoert. Eine Pruefung,
die vom Dateinamen auf die Gueltigkeit schliesst, kennt die halbe
Wirklichkeit.
Die richtige Bedingung ist ohnehin eine andere: Eine Szene ist
gueltig, wenn es eine REGEL dafuer gibt. Fehlt sie, greift
stillschweigend der Rueckfall -- die Seite zeigt dann ein fremdes
Bild und niemand merkt es. Genau davor warnt der Kommentar in
teamlage.html. */
const stilSzenen = new Set([...stil.matchAll(/data-buehne="([a-z-]+)"/g)].map((m) => m[1]));
const unbekannt = [];
let mitSzene = 0;
for (const n of readdirSync(SEITEN).filter((x) => x.endsWith(".html"))) {
const s = readFileSync(join(SEITEN, n), "utf8")
.match(/<body[^>]*data-buehne="([^"]+)"/)?.[1];
if (!s) continue;
mitSzene++;
if (!stilSzenen.has(s)) unbekannt.push(`${n}: "${s}" hat keine Regel in start.css`);
}
ok(stilSzenen.size >= 5,
`${stilSzenen.size} Szenen sind im Stil beschrieben (${[...stilSzenen].sort().join(", ")})`);
ok(mitSzene >= 15 && unbekannt.length === 0,
`alle ${mitSzene} Seiten mit fester Szene nennen eine, die es gibt`
+ (unbekannt.length ? `: ${unbekannt.join(", ")}` : ""));
/* Gegenprobe: eine erfundene Szene MUSS auffallen. */
ok(!stilSzenen.has("gibtesnicht"),
"Gegenprobe: eine erfundene Szene stuende nicht in der Liste");
}
console.log(`\n${geprueft} Pruefungen`);
console.log(fehler === 0 ? "ALLES IN ORDNUNG" : `${fehler} FEHLER`);
process.exit(fehler ? 1 : 0);
+32 -4
View File
@@ -365,10 +365,38 @@ melde("\n=== Der Knopf ist überall ===");
: `auf allen ${gefunden} Seiten mit Kopfleiste`);
/* Und NICHT auf der Anmeldeseite -- dort ist niemand angemeldet,
den man benachrichtigen könnte. */
await seite.goto(BASIS + "/workspace/", { waitUntil: "networkidle" });
await seite.waitForTimeout(250);
ok(!(await seite.$("#glocke")), "auf der Anmeldeseite steht er nicht");
den man benachrichtigen könnte.
==== IN EINER FRISCHEN SITZUNG (berichtigt 07.10.2026) ==========
Hier stand `seite.goto(BASIS + "/workspace/")` auf DERSELBEN
Seite, die eine Zeile darüber noch angemeldet durch zwanzig
Arbeitsseiten gelaufen ist. Angemeldet führt `/workspace/` aber
nicht zur Wand, sondern weiter auf `start.html` -- gemessen:
„gelandet auf .../workspace/start.html, Titel: Creator Workspace".
Dort IST eine Glocke, und zwar zu Recht.
Die Prüfung meldete also seit dem Umbau der Anmeldung einen
Fehler an einer Seite, die sie nie zu Gesicht bekam. Ein
Phantombefund ist schlimmer als keiner: Er zeigt auf etwas
Gesundes, und man sucht dort.
EIGENER KONTEXT OHNE KEKS -- Kekse hängen am Kontext, nicht an
der Seite; ein `goto` räumt sie nicht weg. Und danach wird
NACHGESEHEN, ob die Wand wirklich erreicht wurde: Eine Prüfung,
die ihre Voraussetzung nicht herstellen kann, muss das sagen
können, statt eine Antwort über die falsche Seite zu geben. */
const wandKontext = await browser.newContext();
const wandSeite = await wandKontext.newPage();
await wandSeite.goto(BASIS + "/workspace/", { waitUntil: "networkidle" });
await wandSeite.waitForTimeout(250);
const aufDerWand = /\/workspace\/(index\.html)?(\?|$)/.test(wandSeite.url())
&& !!(await wandSeite.$(".rolle"));
ok(aufDerWand,
`die Anmeldewand wurde wirklich erreicht (${wandSeite.url()})`);
ok(aufDerWand && !(await wandSeite.$("#glocke")),
"auf der Anmeldeseite steht er nicht");
await wandKontext.close();
await browser.close();
}
+35
View File
@@ -383,6 +383,41 @@ melde("=== 8. Im Browser ===");
Geprüft wird nicht, dass es einen Knopf GIBT -- sondern dass er
etwas tut, und dass zugeklappt trotzdem dasteht, was drin ist.
================================================================ */
/* ==== DIE KARTE GEHT SEIT DEM 01.10.2026 GEFILTERT AUF ============
(nachgezogen am 07.10.2026)
entwicklung.js setzt beim Oeffnen `stufenFilter = 'zugetragen'`,
sobald dieser Mensch ueberhaupt etwas zugetragen bekommen hat --
„womit die Karte aufgeht". Bloecke ohne zugetragene Punkte werden
dann gar nicht gezeichnet (`if (!punkte.length) continue`).
DIESE PRUEFUNG WUSSTE DAVON NICHTS und zaehlte danach ALLE
Kategorien. Ergebnis: „1 von 6" -- ein Befund, der auf die Karte
zeigte, obwohl die Karte tat, was sie soll. Und weil danach kein
einziger Block mehr zugeklappt war, lief der Klick auf einen
zugeklappten 30 Sekunden in die Frist und riss den ganzen Lauf mit.
Ein Fehlalarm, der einen zweiten echten Fehler erzeugt.
ZUERST DIE VORGABE PRUEFEN -- sie ist eine Zusage, keine Nebensache
--, dann auf „Alle" stellen. Was die Zeile darunter behauptet („die
Karte zeigt ALLE Bloecke"), gilt genau dort. */
const vorgabe = await seite.evaluate(() => {
const k = document.querySelector('.e-stufen__knopf[aria-pressed="true"]');
return {
gewaehlt: k?.dataset.erwartung ?? null,
wort: k?.querySelector(".e-stufen__name")?.textContent.trim() ?? null,
zugetragen: Number(document.querySelector('.e-stufen__knopf[data-erwartung="zugetragen"] .e-stufen__zahl')?.textContent || 0),
};
});
ok(vorgabe.zugetragen > 0 && vorgabe.gewaehlt === "zugetragen",
`die Karte geht auf „${vorgabe.wort}" auf, weil ${vorgabe.zugetragen} Punkte zugetragen sind`);
await seite.click('.e-stufen__knopf[data-erwartung=""]');
await seite.waitForTimeout(600);
const nachAlle = await seite.evaluate(() =>
document.querySelector('.e-stufen__knopf[aria-pressed="true"]')?.dataset.erwartung);
ok(nachAlle === "", `„Alle" ist danach gewaehlt (${JSON.stringify(nachAlle)})`);
const bloecke = await seite.evaluate(() => {
const b = [...document.querySelectorAll(".e-block")];
return {
+12 -2
View File
@@ -224,6 +224,7 @@ for (const datei of SEITEN) {
let bytes = 0;
let roheBytes = 0, uebertragen = 0;
const warten = [];
const brocken = [];
const zaehler = (antwort) => {
const u = antwort.url();
gesehen.set(u, (gesehen.get(u) || 0) + 1);
@@ -247,7 +248,13 @@ for (const datei of SEITEN) {
]);
if (!k?.length) return;
roheBytes += k.length;
uebertragen += KOMPRIMIERBAR.test(art) ? gzipSync(k).length : k.length;
const wiegt = KOMPRIMIERBAR.test(art) ? gzipSync(k).length : k.length;
uebertragen += wiegt;
/* WAS GENAU WIEGT? (07.10.2026)
„bereich.html?b=live 1094 KB" sagt, DASS etwas zu schwer ist,
und schickt einen danach suchen. Die Antwort liegt hier
ohnehin vor -- sie wurde nur weggeworfen. */
brocken.push({ u: u.replace(/^https?:\/\/[^/]+/, ""), kb: Math.round(wiegt / 1024) });
} catch { /* nichts zu wiegen */ }
})());
};
@@ -383,7 +390,10 @@ for (const datei of SEITEN) {
if (!gewogen) nichtGewogen.push(datei);
if (anfragen > GRENZE_ANFRAGEN || zaehlwert > GRENZE_UEBERTRAGEN) {
zuGross.push(`${datei} ${anfragen} Anfragen / ${Math.round(zaehlwert / 1024)} KB übertragen`);
const groesste = brocken.sort((x, y) => y.kb - x.kb).slice(0, 3)
.map((x) => `${x.kb} KB ${x.u}`).join(", ");
zuGross.push(`${datei} ${anfragen} Anfragen / ${Math.round(zaehlwert / 1024)} KB übertragen`
+ (groesste ? ` -- am schwersten: ${groesste}` : ""));
}
zeilen.push(` ${datei.padEnd(22)} ${String(anfragen).padStart(3)} Anfragen `
+38 -3
View File
@@ -234,11 +234,37 @@ console.log("=== 2. Der Server ===");
console.log("");
console.log("=== 3. Zeichen, die CSS auf den Bildschirm schreibt ===");
/** Truemmerverdacht: Latin-1-Block, wo echte Typografie nie hingehoert. */
const istTruemmer = (c) => c >= 0x80 && c <= 0xbf;
/* ==== DIE AUSNAHME, DIE NICHT VERALTEN KANN (07.10.2026) ============
Der Absatz darueber sagt: „Nachgemessen ueber alle 203
content-Angaben im Haus: KEINE einzige benutzt ein Zeichen aus
diesem Block." Das stimmte am 03.09.2026 und stimmt seit dem
03.10.2026 nicht mehr: bereich.css setzt `content: "·"` als
Trennpunkt vor den Aufgabenzaehler -- absichtlich, begruendet, und
als korrektes UTF-8 gespeichert (Bytes C2 B7 nachgemessen).
DIE REGEL BLEIBT TROTZDEM. Sie hat den echten Fall gefunden (U+00B9,
hochgestellte Eins) und wuerde ihn wieder finden. Was nicht bleiben
darf, ist der Fehlalarm: Eine Pruefung, die bei jedem Lauf eine
richtige Stelle anmeckert, wird weggeklickt -- und nimmt den echten
Fund mit. Das steht vier Absaetze weiter oben in dieser Datei selbst.
DIE LISTE KANN NICHT ROTTEN, weil sie gegen die Wirklichkeit geprueft
wird: Jedes Zeichen darin MUSS irgendwo wirklich vorkommen. Faellt
der Trennpunkt eines Tages weg, wird die Ausnahme rot statt
stillschweigend weiterzugelten -- dieselbe Bauweise wie bei den
ausgenommenen Dateien in pruef-modi-wortleck. */
const MIT_ABSICHT = new Map([
[0x00b7, "Mittelpunkt als Trennzeichen vor dem Aufgabenzaehler (bereich.css)"],
]);
/** Truemmerverdacht: Latin-1-Block, wo echte Typografie nie hingehoert --
* bis auf die ausdruecklich benannten Ausnahmen. */
const istTruemmer = (c) => c >= 0x80 && c <= 0xbf && !MIT_ABSICHT.has(c);
{
const verdaechtig = [];
const gesehen = new Set();
let stellen = 0;
for (const p of geliefert.filter((x) => extname(x) === ".css")) {
const text = readFileSync(p, "utf8");
@@ -246,6 +272,7 @@ const istTruemmer = (c) => c >= 0x80 && c <= 0xbf;
stellen++;
for (const z of m[1]) {
const c = z.codePointAt(0);
if (MIT_ABSICHT.has(c)) gesehen.add(c);
if (istTruemmer(c)) {
verdaechtig.push(`${relative(WURZEL, p)}: content "${m[1]}" enthaelt U+${c.toString(16).toUpperCase().padStart(4, "0")}`);
}
@@ -253,7 +280,15 @@ const istTruemmer = (c) => c >= 0x80 && c <= 0xbf;
}
}
ok(stellen > 50 && verdaechtig.length === 0,
`${stellen} content-Angaben in CSS, ${verdaechtig.length} mit Kodierungstruemmern`);
`${stellen} content-Angaben in CSS, ${verdaechtig.length} mit Kodierungstruemmern`
+ (verdaechtig.length ? ":\n " + verdaechtig.slice(0, 5).join("\n ") : ""));
/* Und die Gegenprobe zur Ausnahme: Was hier steht, muss es geben. */
const verwaist = [...MIT_ABSICHT.keys()].filter((c) => !gesehen.has(c));
ok(verwaist.length === 0,
`alle ${MIT_ABSICHT.size} benannten Ausnahmen kommen wirklich vor`
+ (verwaist.length
? ` -- verwaist: ${verwaist.map((c) => "U+" + c.toString(16).toUpperCase()).join(", ")}`
: ""));
for (const s of verdaechtig.slice(0, 12)) console.log(" " + s);
/* GEGENPROBE: Wuerde sie den echten Fall sehen? Nicht theoretisch --