Ports: auch die Messwerkzeuge leiten ihre Nummer ab
GEMESSEN, BEVOR ICH ETWAS ANGEFASST HABE:
204 pruef-Dateien, abgeleitete Ports 5000-5409 (dicht belegt)
24 mess-Dateien, Nummern von Hand: 4471 bis 5493
davon IM Pruefbereich: 5387, 5397, 5397, 5399, 5399, 5401, 5403, 5405
untereinander doppelt: 5397, 5399, 5461, 5483, 5491
Aufgefallen ist es, weil mess-buehne und mess-reaktion beide auf 5483
lagen und ein haengengebliebener Lauf gestern einen ganzen Messlauf
gekostet hat.
Beim Umbau kam das Groessere heraus: EINUNDZWANZIG der 24 Messdateien
hatten nicht nur eine Nummer von Hand, sondern ueberhaupt keinen
Waechter -- schlicht `const PORT = 5397;`. Liegt dort schon ein
Server, startet der eigene still nicht, und gemessen wird ab da ein
fremder Stand. Genau der Fehler, gegen den helfer-port.mjs gebaut
wurde; die Messdateien standen die ganze Zeit ausserhalb.
WAS JETZT GILT
Zwei Sorten, zwei Bereiche, beide abgeleitet aus der Stelle im
Alphabet -- jede Sorte unter ihresgleichen, sonst verschoebe eine
neue Pruefung die Nummern aller Messungen. Pruefungen ab 5000,
Messungen ab MESS_BASIS = 5900.
5900 und nicht 5500: dazwischen bleibt Platz fuer 245 weitere
Pruefdateien (bei 5500 waeren es 45). Nach oben 5948 + AUSWEICHEN
4000 = 9948, also unter 10080, der naechsten gesperrten Nummer.
Nachgerechnet, nicht geschaetzt -- eine geschaetzte 4500 hatte bei
BASIS schon einmal danebengelegen.
Eine Wache dazu: Waechst der Pruefbereich bis an MESS_BASIS heran,
bricht die Ableitung ab und sagt, was zu tun ist. Eine stille
Ueberschneidung waere genau der Fehler, den das hier beseitigt.
Die zweite Nummer kommt ueber nr=1, nie ueber `PORT + 1`:
portNummer ueberspringt gesperrte Nummern, deshalb kann die naechste
Zahl die Nummer der naechsten DATEI sein, sobald einmal eine Sperre
dazwischenliegt. Heute liegt dort keine -- das ist Glueck, kein
Entwurf.
NEBENBEI GEFUNDEN UND MIT REPARIERT
Sechs bild-*.mjs riefen den Waechter und warfen seine Antwort weg:
await portMussFreiSein(4315, "das Bildwerkzeug");
process.env.PORT = "4315";
const BASIS = "http://127.0.0.1:4315";
Er lief, meldete nichts und wirkte nicht. Gibt das System den Port
dauerhaft nicht her, weicht er auf Port + 4000 aus und GIBT DIE NEUE
NUMMER ZURUECK -- diese Werkzeuge hoerten danach trotzdem auf der
alten und stuerzten mit `listen EACCES` ab, also mit genau dem
Fehler, gegen den er gebaut wurde. Dazu stand die Zahl dreimal je
Datei. Jetzt einmal, und die Antwort wird benutzt.
tiktok-videos.mjs hatte den Waechter ABGESCHRIEBEN -- eine kurze
eigene Fassung ohne den dritten Ausgang: Bei EACCES meldete sie
"belegt" und brach ab, statt auszuweichen. Auf diesem Rechner ist
genau das am 23.09. eingetreten (Port 5040, Windows-Dienst).
mess-fokus und mess-notizblock hatten dieselbe Abschrift. Eine
abgeschriebene Sicherung ist dieselbe Falle wie eine abgeschriebene
Liste.
GEPRUEFT
pruef-portnummern 15 -> 41 Pruefungen, 0 Fehler
pruef-ports 8 -> 10 Pruefungen, 456 statt 408 Ports geprobt
node --check auf allen 33 geaenderten Dateien
Gegenproben, die wirklich rot werden:
- eine Messdatei auf eine feste Nummer zurueckgesetzt -> 2 FEHL,
danach wieder 41/0
- die Wache: in einem Wegwerf-Ordner mit 452 pruef-Dateien bricht
eigenerPort ab statt still zu ueberlappen; eine Datei knapp
darunter bekommt weiter ihre Nummer (5846)
- die Erkennungen fuer feste Nummern, PORT + 1 und weggeworfene
Waechterantworten je gegen einen gebauten Rueckschritt
Am echten Verhalten gemessen:
- mess-chat-liste und mess-alle-einzelsicht (beide vorher 5397)
GLEICHZEITIG gestartet: 5906 und 5900, beide exit=0. Vorher war
das unmoeglich.
- die 48 neuen Nummern 5900-5947 auf diesem Rechner durchprobiert:
keine belegt, keine vom System gesperrt
- bild-chat.mjs durchgelaufen, drei Bilder, exit=0
Kein Eingriff am laufenden Dienst: helfer-port.mjs wird von index.js
und workspace.js nicht geladen (nachgesehen), nur von Pruef- und
Messwerkzeugen. Beide Haeuser unberuehrt -- es wird keine Zeile
angefasst, die eine Seite ausliefert.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -20,8 +20,11 @@
|
||||
sie faellt nur niemandem auf, bis zwei Laeufe kollidieren.
|
||||
===================================================================== */
|
||||
|
||||
import { readdirSync, readFileSync } from "node:fs";
|
||||
import { eigenerPort, portNummer } from "./helfer-port.mjs";
|
||||
import { mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { eigenerPort, portNummer, MESS_BASIS, GESPERRT } from "./helfer-port.mjs";
|
||||
|
||||
let ok_ = 0, fehl = 0;
|
||||
const ok = (b, text) => { if (b) { ok_++; console.log(" ok " + text); }
|
||||
@@ -30,6 +33,11 @@ const ok = (b, text) => { if (b) { ok_++; console.log(" ok " + text); }
|
||||
const ORDNER = new URL(".", import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, "$1");
|
||||
const dateien = readdirSync(ORDNER)
|
||||
.filter((f) => f.startsWith("pruef-") && f.endsWith(".mjs")).sort();
|
||||
/* DIE MESSDATEIEN GEHOEREN DAZU (01.10.2026). Sie standen bis heute
|
||||
ganz ausserhalb dieser Pruefung -- und genau dort ist der Fehler
|
||||
auch gewachsen, den sie verhindern soll. */
|
||||
const messen = readdirSync(ORDNER)
|
||||
.filter((f) => f.startsWith("mess-") && f.endsWith(".mjs")).sort();
|
||||
|
||||
console.log("\n=== 1. Niemand traegt eine Nummer von Hand ein ===");
|
||||
const vonHand = [];
|
||||
@@ -186,6 +194,247 @@ try { await eigenerPort(import.meta, "Gegenprobe", 7); }
|
||||
catch (f) { zuHoheNummer = /Nummern je Datei/.test(f?.message || ""); }
|
||||
ok(zuHoheNummer, "und eine dritte Nummer je Datei gibt es nicht");
|
||||
|
||||
console.log("\n=== 5. Die Messdateien leiten ihre Nummer auch ab (01.10.2026) ===");
|
||||
/* WAS HIER AM 01.10. GEMESSEN WURDE, BEVOR ES DIESE PRUEFUNG GAB:
|
||||
24 Messdateien, und EINUNDZWANZIG davon hatten ihre Nummer nicht
|
||||
nur von Hand, sondern ganz ohne Waechter -- schlicht
|
||||
`const PORT = 5397;`. Fuenf Nummern waren untereinander doppelt
|
||||
vergeben (5397, 5399, 5461, 5483, 5491), und acht lagen mitten im
|
||||
dicht belegten Bereich der Pruefungen (5000-5409).
|
||||
|
||||
Gekostet hat das einen ganzen Messlauf: mess-buehne und
|
||||
mess-reaktion teilten sich die 5483, ein liegengebliebener Prozess
|
||||
hielt sie, und die zweite Messung lief gegen einen fremden Stand.
|
||||
|
||||
Die Messdateien standen bei alldem AUSSERHALB dieser Pruefung --
|
||||
sie hat 204 Pruefdateien angesehen und die 24 daneben nie. Eine
|
||||
Sicherung, die nur die halbe Menge kennt, faellt genau in der
|
||||
anderen Haelfte aus. */
|
||||
{
|
||||
const festeNummer = [];
|
||||
const ohneWaechter = [];
|
||||
const platteSumme = [];
|
||||
for (const f of messen) {
|
||||
const code = readFileSync(ORDNER + "/" + f, "utf8")
|
||||
.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "");
|
||||
if (/const\s+\w*PORT\w*\s*=\s*\d/.test(code)
|
||||
|| /portMussFreiSein\(\s*\d/.test(code)) festeNummer.push(f);
|
||||
/* `PORT + 1` IST KEINE ABLEITUNG. `portNummer` ueberspringt
|
||||
gesperrte Nummern -- liegt einmal eine dazwischen, ist die
|
||||
naechste Zahl die Nummer der naechsten DATEI. Heute liegt dort
|
||||
keine; das ist Glueck, kein Entwurf. */
|
||||
if (/PORT\s*\+\s*1\b/.test(code)) platteSumme.push(f);
|
||||
const startetServer = /import\(\s*["'`]\.\/index\.js["'`]\s*\)/.test(code)
|
||||
|| /process\.env\.PORT\s*=/.test(code);
|
||||
if (startetServer && !/eigenerPort\(\s*import\.meta/.test(code)) ohneWaechter.push(f);
|
||||
}
|
||||
ok(messen.length > 10, `${messen.length} Messdateien angesehen`);
|
||||
ok(festeNummer.length === 0,
|
||||
`keine traegt eine Nummer von Hand (${festeNummer.slice(0, 4).join(", ") || "—"})`);
|
||||
ok(ohneWaechter.length === 0,
|
||||
`jede, die einen Server startet, leitet ihre Nummer ab (${ohneWaechter.slice(0, 4).join(", ") || "—"})`);
|
||||
ok(platteSumme.length === 0,
|
||||
`keine rechnet ihre zweite Nummer als PORT + 1 (${platteSumme.slice(0, 4).join(", ") || "—"})`);
|
||||
|
||||
/* ---- KANN DIESE ERKENNUNG AUCH NEIN SAGEN? -----------------------
|
||||
Die drei Zeilen darueber melden „in Ordnung", solange sie NICHTS
|
||||
finden -- und genau so sieht auch eine Erkennung aus, die man zu
|
||||
eng gefasst hat. Am 01.10. waren es 21 Treffer; ab morgen sollen
|
||||
es null sein, und dann sagt die Zahl allein nichts mehr darueber,
|
||||
ob noch hingesehen wird. */
|
||||
const alsFest = (c) => /const\s+\w*PORT\w*\s*=\s*\d/.test(c)
|
||||
|| /portMussFreiSein\(\s*\d/.test(c);
|
||||
ok(alsFest("const PORT = 5397;"), "Gegenprobe: eine feste Nummer faellt auf");
|
||||
/* ZUSAMMENGESETZT, NICHT AUSGESCHRIEBEN: Abschnitt 1 dieser Datei
|
||||
sucht in JEDER Pruefdatei nach genau diesem Wortlaut und
|
||||
entfernt vorher nur Kommentare, keine Zeichenketten. Stuende
|
||||
das Beispiel hier am Stueck, zeigte diese Pruefung sich
|
||||
selbst an -- gemessen, sie tat es beim ersten Lauf. */
|
||||
ok(alsFest("const HTTPS_PORT = await portMuss" + "FreiSein(5484);"),
|
||||
" und eine feste Nummer im Waechter ebenfalls");
|
||||
ok(!alsFest("const PORT = await eigenerPort(import.meta);"),
|
||||
" wer ableitet, faellt NICHT auf");
|
||||
ok(/PORT\s*\+\s*1/.test("const HTTPS_PORT = PORT + 1;"),
|
||||
" und PORT + 1 wird als solches erkannt");
|
||||
|
||||
/* ---- Die beiden Bereiche beruehren sich nicht -------------------- */
|
||||
const pruefPorts = [];
|
||||
dateien.forEach((f, i) => pruefPorts.push(portNummer(i * 2), portNummer(i * 2 + 1)));
|
||||
const messPorts = [];
|
||||
messen.forEach((f, i) => messPorts.push(
|
||||
portNummer(i * 2, MESS_BASIS), portNummer(i * 2 + 1, MESS_BASIS)));
|
||||
const hoechstPruef = Math.max(...pruefPorts);
|
||||
ok(hoechstPruef < MESS_BASIS,
|
||||
`die Pruefungen enden bei ${hoechstPruef}, die Messungen fangen bei ${MESS_BASIS} an`
|
||||
+ ` — Luft fuer ${((MESS_BASIS - hoechstPruef) / 2) | 0} weitere Pruefdateien`);
|
||||
|
||||
const zusammen = [...pruefPorts, ...messPorts];
|
||||
ok(new Set(zusammen).size === zusammen.length,
|
||||
`alle ${zusammen.length} Nummern beider Sorten sind verschieden`);
|
||||
const boeseMess = messPorts.filter((p) => GESPERRT.has(p));
|
||||
ok(boeseMess.length === 0,
|
||||
`keine Messnummer steht auf der Sperrliste (${boeseMess.join(", ") || "—"})`);
|
||||
|
||||
/* ---- GEMESSEN, nicht gerechnet: die echte Funktion befragen ------ */
|
||||
const erste = messen[0];
|
||||
const echt = await eigenerPort(
|
||||
{ url: pathToFileURL(ORDNER + "/" + erste).href }, "pruef-portnummern (Selbsttest)");
|
||||
ok(echt === portNummer(0, MESS_BASIS) && echt >= MESS_BASIS,
|
||||
`${erste} bekommt von eigenerPort wirklich ${echt}`);
|
||||
const letzte = messen.at(-1);
|
||||
const echt2 = await eigenerPort(
|
||||
{ url: pathToFileURL(ORDNER + "/" + letzte).href }, "pruef-portnummern (Selbsttest)", 1);
|
||||
ok(echt2 === portNummer((messen.length - 1) * 2 + 1, MESS_BASIS),
|
||||
`und ${letzte} als zweite Nummer ${echt2} — beide aus dem Messbereich`);
|
||||
}
|
||||
|
||||
console.log("\n=== 6. Gegenprobe: die Wache gegen das Zusammenwachsen ===");
|
||||
/* Eine Grenze, die nie anschlaegt, ist keine Grenze. Waechst die Zahl
|
||||
der Pruefdateien so weit, dass ihr Bereich den der Messungen
|
||||
erreicht, bekaemen zwei Laeufe still dieselbe Nummer -- genau der
|
||||
Fehler, den diese ganze Ableitung beseitigt.
|
||||
|
||||
GEPRUEFT WIRD DIE ECHTE FUNKTION, nicht eine Nachbildung ihrer
|
||||
Bedingung: In einem Wegwerf-Ordner liegen so viele leere
|
||||
`pruef-*.mjs`, dass die letzte ueber MESS_BASIS hinauskaeme. Ein
|
||||
eigener Ordner deshalb, weil echte Dateien hier die Nummern aller
|
||||
anderen verschieben wuerden. */
|
||||
{
|
||||
const wegwerf = mkdtempSync(join(tmpdir(), "portwache-"));
|
||||
const noetig = Math.ceil((MESS_BASIS - portNummer(0)) / 2) + 2;
|
||||
for (let i = 0; i < noetig; i++) {
|
||||
writeFileSync(join(wegwerf, `pruef-${String(i).padStart(5, "0")}.mjs`), "");
|
||||
}
|
||||
const letzte = join(wegwerf, `pruef-${String(noetig - 1).padStart(5, "0")}.mjs`);
|
||||
let sagte = "";
|
||||
try { await eigenerPort({ url: pathToFileURL(letzte).href }, "Gegenprobe"); }
|
||||
catch (f) { sagte = f?.message || ""; }
|
||||
ok(/stoesst an den der Messdateien/.test(sagte),
|
||||
`bei ${noetig} Pruefdateien bricht die Ableitung ab statt still zu ueberlappen`);
|
||||
ok(/MESS_BASIS/.test(sagte) && /hochsetzen/.test(sagte),
|
||||
"und sagt dabei, was zu tun ist");
|
||||
|
||||
/* UND DIE ANDERE RICHTUNG: Eine Datei knapp DARUNTER muss noch
|
||||
durchgehen. Ohne das hiesse „bricht ab" womoeglich nur, dass in
|
||||
diesem Ordner alles abbricht. */
|
||||
const knapp = join(wegwerf, `pruef-${String(noetig - 30).padStart(5, "0")}.mjs`);
|
||||
let ging = 0;
|
||||
try { ging = await eigenerPort({ url: pathToFileURL(knapp).href }, "Gegenprobe"); }
|
||||
catch { ging = 0; }
|
||||
ok(ging > 0 && ging < MESS_BASIS,
|
||||
`eine Datei knapp darunter bekommt weiter ihre Nummer (${ging})`);
|
||||
rmSync(wegwerf, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
console.log("\n=== 7. Die uebrigen Werkzeuge, die einen Server starten ===");
|
||||
/* BEIM UMBAU AM 01.10. AUFGEFALLEN: Es gibt eine dritte Sorte. Zehn
|
||||
Werkzeuge starten den Workspace ebenfalls -- `bild-*`, `tmp-lokal`,
|
||||
`tiktok-videos`, `zz-*` -- und alle zehn auf einer Nummer von Hand;
|
||||
sieben davon ohne jeden Waechter.
|
||||
|
||||
SIE LEITEN NICHT AB, UND DAS IST ABSICHT: Es waeren vier weitere
|
||||
Vorsilben mit ein bis sechs Dateien, also vier Bereiche fuer zehn
|
||||
Werkzeuge, die nie gleichzeitig laufen. Der saubere Weg waere, sie
|
||||
`mess-` zu nennen -- ein eigener Schritt.
|
||||
|
||||
WAS HIER GEPRUEFT WIRD, IST DESHALB WENIGER UND TROTZDEM DAS
|
||||
ENTSCHEIDENDE: dass keine dieser Nummern in einen abgeleiteten
|
||||
Bereich faellt und keine zweimal vergeben ist. Genau daraus ist die
|
||||
Doppelung bei den Messdateien entstanden -- aus einer Lage, die
|
||||
einmal in Ordnung war und die danach niemand mehr nachgesehen hat. */
|
||||
{
|
||||
const uebrige = readdirSync(ORDNER)
|
||||
.filter((f) => f.endsWith(".mjs")
|
||||
&& !f.startsWith("pruef-") && !f.startsWith("mess-") && !f.startsWith("helfer-"))
|
||||
.filter((f) => /process\.env\.PORT\s*=/.test(readFileSync(ORDNER + "/" + f, "utf8")))
|
||||
.sort();
|
||||
ok(uebrige.length > 0, `${uebrige.length} weitere Werkzeuge starten einen Server`);
|
||||
|
||||
/* DIE NUMMER MUSS ABLESBAR SEIN. Findet sich keine, wird nicht
|
||||
uebersprungen -- ein uebersprungener Fall beweist nichts, und
|
||||
genau hier soll er auffallen. */
|
||||
const nummern = new Map();
|
||||
const unlesbar = [];
|
||||
for (const f of uebrige) {
|
||||
const code = readFileSync(ORDNER + "/" + f, "utf8")
|
||||
.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "");
|
||||
const t = code.match(/process\.env\.PORT\s*=\s*[`"']?(\d{3,5})/)
|
||||
|| code.match(/const PORT\s*=\s*(\d{3,5})/)
|
||||
|| code.match(/portMussFreiSein\(\s*(\d{3,5})/);
|
||||
if (!t) { unlesbar.push(f); continue; }
|
||||
nummern.set(f, Number(t[1]));
|
||||
}
|
||||
ok(unlesbar.length === 0,
|
||||
`bei jedem steht die Nummer im Quelltext (${unlesbar.join(", ") || "—"})`);
|
||||
|
||||
const werte = [...nummern.values()];
|
||||
const doppelte = werte.filter((p, i) => werte.indexOf(p) !== i);
|
||||
ok(werte.length > 0 && doppelte.length === 0,
|
||||
`keine ihrer ${werte.length} Nummern ist doppelt (${[...new Set(doppelte)].join(", ") || "—"})`);
|
||||
|
||||
const pruefPorts2 = [];
|
||||
dateien.forEach((f, i) => pruefPorts2.push(portNummer(i * 2), portNummer(i * 2 + 1)));
|
||||
const messPorts2 = [];
|
||||
messen.forEach((f, i) => messPorts2.push(
|
||||
portNummer(i * 2, MESS_BASIS), portNummer(i * 2 + 1, MESS_BASIS)));
|
||||
const abgeleitet = new Set([...pruefPorts2, ...messPorts2]);
|
||||
const drin = [...nummern].filter(([, p]) => abgeleitet.has(p));
|
||||
ok(werte.length > 0 && drin.length === 0,
|
||||
"keine liegt in einem abgeleiteten Bereich"
|
||||
+ ` (${drin.map(([f, p]) => `${f}:${p}`).join(", ") || "—"})`);
|
||||
|
||||
/* GEGENPROBE: Diese drei Zeilen melden „in Ordnung", solange sie
|
||||
nichts finden. Also einmal zeigen, dass sie etwas finden KOENNEN. */
|
||||
const probe = [...abgeleitet][0];
|
||||
ok(abgeleitet.has(probe) && probe >= 5000,
|
||||
`Gegenprobe: ${probe} waere ein Treffer — die Liste der abgeleiteten`
|
||||
+ ` Nummern hat ${abgeleitet.size} Eintraege und ist nicht leer`);
|
||||
|
||||
/* ---- EIN WAECHTER, DESSEN ANTWORT NIEMAND LIEST, IST KEINER -----
|
||||
Am 01.10. in allen sechs `bild-*.mjs` gefunden:
|
||||
|
||||
await portMussFreiSein(4315, "das Bildwerkzeug");
|
||||
process.env.PORT = "4315";
|
||||
const BASIS = "http://127.0.0.1:4315";
|
||||
|
||||
Der Waechter lief, meldete nichts und wirkte nicht. Gibt das
|
||||
System den Port dauerhaft nicht her, weicht er auf Port + 4000
|
||||
aus und GIBT DIE NEUE NUMMER ZURUECK -- diese Werkzeuge hoerten
|
||||
danach trotzdem auf der alten und stuerzten mit `listen EACCES`
|
||||
ab, also mit genau dem Fehler, gegen den er gebaut wurde.
|
||||
|
||||
Dazu stand die Zahl dreimal je Datei. Wer eine davon aendert,
|
||||
hat einen Server auf dem einen Port und ein Werkzeug, das den
|
||||
anderen abfragt. */
|
||||
const weggeworfen = [];
|
||||
const mehrfach = [];
|
||||
for (const f of uebrige) {
|
||||
const code = readFileSync(ORDNER + "/" + f, "utf8")
|
||||
.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "");
|
||||
if (/^\s*await\s+(portMussFreiSein|eigenerPort)\(/m.test(code)) weggeworfen.push(f);
|
||||
const n = nummern.get(f);
|
||||
if (n !== undefined) {
|
||||
const wieOft = (code.match(new RegExp(String(n), "g")) || []).length;
|
||||
if (wieOft > 1) mehrfach.push(`${f}:${wieOft}x`);
|
||||
}
|
||||
}
|
||||
ok(weggeworfen.length === 0,
|
||||
`jedes benutzt die Antwort des Waechters (${weggeworfen.join(", ") || "—"})`);
|
||||
ok(mehrfach.length === 0,
|
||||
`und schreibt seine Nummer nur einmal hin (${mehrfach.join(", ") || "—"})`);
|
||||
|
||||
/* GEGENPROBE zu beiden: Erkennen sie den Rueckschritt auch? */
|
||||
const wirftWeg = (c) => /^\s*await\s+(portMussFreiSein|eigenerPort)\(/m.test(c);
|
||||
ok(wirftWeg('await portMuss' + 'FreiSein(4315, "x");'),
|
||||
"Gegenprobe: eine weggeworfene Antwort faellt auf");
|
||||
ok(!wirftWeg('const PORT = await portMuss' + 'FreiSein(4315, "x");'),
|
||||
" wer sie in eine Zeile schreibt, faellt NICHT auf");
|
||||
ok((('p = 4315; q = 4315;').match(/4315/g) || []).length === 2,
|
||||
" und eine zweimal genannte Nummer wird gezaehlt");
|
||||
|
||||
console.log(` ${[...nummern].map(([f, p]) => `${f.replace(/\.mjs$/, "")} ${p}`).join(", ")}`);
|
||||
}
|
||||
|
||||
console.log(`\n${ok_} Pruefungen, ${fehl} Fehler`);
|
||||
console.log(fehl ? "NICHT IN ORDNUNG\n" : "ALLES IN ORDNUNG\n");
|
||||
process.exit(fehl ? 1 : 0);
|
||||
|
||||
Reference in New Issue
Block a user