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:
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 `
|
||||
|
||||
@@ -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 --
|
||||
|
||||
Reference in New Issue
Block a user