Files
claude-regelwerk/.vault-tools/trading-plattform-pruefung/mutanten_ts.py
T
Pascal MichelandClaude Opus 5 2c9a4475fc Regelwerk, Agenten, Skills und Werkzeuge veröffentlichen
Erster Stand des öffentlichen Ausschnitts aus dem Vault. Die .gitignore
arbeitet als Positivliste: ausgeschlossen ist alles, eingeschlossen nur,
was ausdrücklich wieder aufgenommen wird. Notizen, Projekte, Finanzen,
das Sitzungsgedächtnis und settings.local.json bleiben damit außen vor.

Der Kundenname in AI/Regelwerk/seo.md ist durch eine neutrale
Bezeichnung ersetzt; die Regeln selbst sind unverändert.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-17 22:38:15 +02:00

117 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Mutantenlauf Frontend auf der materialisierten Kopie (Windows-Python, vitest je Datei).
Je Mutant: Datei als Bytes sichern, genau eine Stelle ersetzen, die Testdatei fahren, zurueckspielen.
Erwartet ist ROT; ein gruener Mutant ist ein Befund. Zuerst die Grundlinie.
"""
import subprocess
import sys
from pathlib import Path
DASH = Path(sys.argv[1]) / "dashboard" # Windows-Pfad der Kopie mit dem angewendeten Plan
MUTANTEN = [
(
"stufe() gibt den rohen Index zurueck",
"src/components/LaufKampagne.tsx",
" const wert = aktion - (verteilung.length - 1) / 2;",
" const wert = aktion;",
"src/components/LaufKampagne.test.tsx",
),
(
"stufe() ohne Pruefung der Verteilung",
"src/components/LaufKampagne.tsx",
" if (!Array.isArray(verteilung) || verteilung.length % 2 === 0) return STRICH;",
" if (!Array.isArray(verteilung)) return STRICH;",
"src/components/LaufKampagne.test.tsx",
),
(
"stufe() ohne Pruefung des Bereichs",
"src/components/LaufKampagne.tsx",
" if (aktion < 0 || aktion >= verteilung.length) return STRICH;\n",
"",
"src/components/LaufKampagne.test.tsx",
),
(
"Stille Fenster als Ertrag formatiert",
"src/components/LaufKampagne.tsx",
" wert={anteil(abschluss.anteil_fenster_ohne_trade)}",
" wert={prozent(abschluss.anteil_fenster_ohne_trade)}",
"src/components/LaufKampagne.test.tsx",
),
(
"close() merkt sich das Ende nicht",
"src/lib/api.ts",
" beendet = true;\n",
"",
"src/lib/api.test.ts",
),
(
"close() raeumt den Zeitgeber nicht",
"src/lib/api.ts",
" if (zeitgeber !== null) clearTimeout(zeitgeber);\n",
"",
"src/lib/api.test.ts",
),
(
# Der Backslash kommt aus chr(92): Eine Escape-Folge im eigenen Quelltext wertet sonst
# irgendeine Schicht aus -- genau das ist bei der Umsetzung passiert.
"Lizenztext mit doppeltem Backslash (Escape-Folge als Klartext auf der Seite)",
"src/components/Markt.tsx",
"Charts" + chr(92) + "u2122 Copyright (" + chr(92) + "u0441) 2025",
"Charts" + chr(92) * 2 + "u2122 Copyright (" + chr(92) * 2 + "u0441) 2025",
"src/components/Markt.test.tsx",
),
]
def fahre(testdatei: str) -> tuple[bool, str]:
ergebnis = subprocess.run(
f"npx vitest run {testdatei}",
cwd=DASH,
shell=True,
capture_output=True,
text=True,
encoding="utf-8",
errors="replace",
stdin=subprocess.DEVNULL,
)
ausgabe = ergebnis.stdout + ergebnis.stderr
rote = [z.strip() for z in ausgabe.splitlines() if z.strip().startswith(("×", "FAIL", "✗")) or " > " in z and "FAIL" in z]
return ergebnis.returncode == 0, "; ".join(rote[:4])
def main() -> int:
befunde = 0
for testdatei in sorted({m[4] for m in MUTANTEN}):
gruen, _ = fahre(testdatei)
if not gruen:
print(f"BEFUND Grundlinie: {testdatei} ist ohne Mutant nicht gruen")
return 2
print("Grundlinie gruen.")
for name, datei, alt, neu, testdatei in MUTANTEN:
pfad = DASH / datei
sicherung = pfad.read_bytes()
text = sicherung.decode("utf-8")
anzahl = text.count(alt)
if anzahl != 1:
print(f"BEFUND Mutant '{name}': Stelle steht {anzahl}-mal in {datei}")
befunde += 1
continue
try:
pfad.write_bytes(text.replace(alt, neu).encode("utf-8"))
gruen, rote = fahre(testdatei)
finally:
pfad.write_bytes(sicherung)
if gruen:
print(f"BEFUND Mutant '{name}' bleibt GRUEN ({testdatei})")
befunde += 1
else:
print(f"rot {name} [{rote}]")
print(f"{befunde} Befund(e).")
return 2 if befunde else 0
if __name__ == "__main__":
sys.exit(main())