Phase 6: Kompatibilitaetsabnahme abschliessen und archivieren

This commit is contained in:
2026-09-07 12:34:06 +02:00
parent 54ee427c1c
commit 993c3e7638
21 changed files with 752 additions and 58 deletions

View File

@@ -1,27 +1,74 @@
# Kompatibilitäts-Testkorpus
Kleine Referenzprogramme mit dokumentierter erwarteter Ausgabe. Jede
`name.bas` hat eine `name.out` mit der exakten Konsolenausgabe (UTF-8,
LF-Zeilenenden). **Achtung:** PRINT gibt Zahlen mit führendem Leerzeichen
(bzw. `-`) und nachgestelltem Leerzeichen aus — auch am Zeilenende. Die
`.out`-Dateien enthalten daher signifikante Leerzeichen am Zeilenende;
Editoren dürfen sie nicht wegtrimmen; `.gitattributes` schützt die Dateien
vor Zeilenenden-Konvertierung.
Kleine BAS- und FRM-Referenzprogramme mit unabhängig begründeter Sollausgabe.
`cargo test --locked -p tb-cli --test compat` übersetzt sie, führt sie ohne
Terminal durch die TBVM und vergleicht jeden Lauf mit seiner `.out`.
Jeder Fall läuft zweimal. Mehrere deklarierte Bildschirmgrößen besitzen
jeweils eine eigene `<name>.<cols>x<rows>.out`.
Ab Phase 2 führt ein Test-Harness (`cargo test`) jede Datei per
`tbc run` aus und vergleicht die Ausgabe. Bis dahin dienen die
`.out`-Dateien als festgehaltene Verhaltensspezifikation — wo möglich am
Vorbild (Emulator) verifiziert, sonst nach Referenzlage rekonstruiert
und mit `TODO verify` im Programmkopf markiert.
Snapshots enthalten das getrimmte Textbild und bei abweichenden Farben eine
Attributebene. UTF-8 und LF sind verbindlich. PRINT-Leerzeichen sind auch am
Zeilenende signifikant; `.gitattributes` schützt `.out` vor Konvertierung.
Breite Zeichen erscheinen einmal, ihre Fortsetzungszellen werden nicht als
zusätzliches Leerzeichen ausgegeben. Die Farbdiagnose nennt Bildschirmspalten.
Konventionen:
- Nur Konsolen-E/A (keine Forms) bis Phase 4
- Kein Zufall/Zeit, außer der Test fixiert die Saat (`RANDOMIZE` mit
Konstante) bzw. prüft nur Invarianten
Kopfzeilen stehen bei BAS am Anfang, bei FRM in den ersten acht Codezeilen:
- `tb-screen: 80x25` ist Pflicht; mehrere Größen werden durch Kommas getrennt.
- `tb-resize: nach 1 auf 120x40` liefert eine einzelne Größenänderung nach
dem angegebenen Host-Zustellpunkt.
- `tb-keys:` beschreibt Tasten; `<TAB>`, `<ENTER>`, `<ESC>`, `<F1>` bis `<F12>`
und Pfeiltasten sind benannt, `+`/`^`/`%` stehen für Shift/Ctrl/Alt.
- `tb-events:` ordnet Tasten, Maus, Zeit und Resize ausdrücklich, etwa
`key:<TAB> | resize:100x30 | mouse:down,1,0,4,25 | time:250ms`.
Mausfelder sind Art, Taste, Modifikatoren, Zeile, Spalte (einsbasiert).
`time:` rückt die virtuelle Uhr um den Wert vor; ohne Zeitschritt steht sie
bei 0. `mouse:up` und `mouse:move` ergänzen Loslassen und Bewegung.
- `tb-clock: 25ms/Zustellpunkt` ist die alternative Uhr für TIMER-Traps;
der Harness verbietet fehlende Trap-Uhren und die Mischung mit tb-events.
- `tb-tempdir` führt Dateiprogramme in einem frischen leeren Arbeitsverzeichnis
aus und entfernt es danach, auch beim Entrollen eines Testfehlers.
- `tb-tz: +00:00` setzt eine feste Zone, `tb-tz: unknown` prüft UTC-Rückfall.
Datums-/Zeitproben setzen ihre Werte oder prüfen ausdrücklich Invarianten;
Zufall verwendet eine feste Saat.
`release-formular.frm` verbindet Fokuswechsel, Mausklick, Menü und Resize
mit farbiger Unicode-Ausgabe. Das Soll folgt den Handlern
`Lost;Got;Click;Menu;`, `COLOR 14,1` (e1) und `LOCATE 2,90` nach Resize auf
100×30. Der Test verändert gezielt ein Zeichen und ein Attribut in der
Erwartung und muss beides erkennen. Das Soll wird nicht aus dem VM-Istwert
gewonnen. Bestehende `formular.frm`-/Listen-/Timerfälle prüfen zusätzlich
die sichtbare Formularzeichnung und modale Übergänge.
Die Programme `eingabefortschritt`, `timezoneknown` und `timezonefallback`
prüfen den TerminalBasic-Vertrag für Codepoints, gemeinsame Dateileseposition
und den sichtbaren Zonenzustand. `tb-tz: +00:00` setzt eine bekannte UTC-Zone,
`tb-tz: unknown` erzwingt den UTC-Rückfall. Späterer Ausfall und Erholung
werden zusätzlich mit einer ersetzbaren Zonenquelle in den Laufzeit- und
VM-Tests geprüft, ohne die Zeitzone des Rechners zu verändern.
prüfen Codepoints, gemeinsame Dateileseposition und Zonenzustand. Späterer
Zonenausfall und Erholung werden mit einer ersetzbaren Quelle geprüft,
ohne die Rechnerzeitzone zu ändern.
## Erforderliche Release-Grundabnahme
```sh
python3 tests/support/release-abnahme.py --vbdos-repo /absoluter/pfad/zu/vbdos
```
Der Aufruf funktioniert auch außerhalb des Checkouts mit absolutem Skriptpfad.
Er benötigt Python 3, Cargo/Rust sowie Git und tar für den Fremdbestand.
Er lädt nichts herunter. Der Git-Bestand muss HEAD
`1cdd2b32b829fe1721d0b6aecc433abc47a96fb6` enthalten; der Test exportiert exakt
diese Revision in temporäre Verzeichnisse, sodass lokale Änderungen am
Fremdcheckout nicht in die Prüfung eingehen.
Zuerst läuft der erforderliche Fremdtest mit `--include-ignored`, danach
Workspace-Regressionen, Inventarbericht, Format, Clippy und die vorhandenen
Compile-/VM-Benchmarks. Jeder Fehler beendet den Aufruf erfolglos. Ohne
Bestand oder mit falscher Revision entsteht kein bestandener Release-Nachweis.
Der normale Entwicklertest darf den Fremdtest weiter ignorieren; er allein
ist keine Release-Abnahme. Das ignorierte Golden-Erzeugungswerkzeug wird vom
Release-Aufruf niemals gestartet. Bestehende Sollwerte werden nur nach
Prüfung ihrer Spec-/Referenzgrundlage geändert.
Fallzuordnung, Eingabefolgen, Referenzrevision und Messwerte stehen im Change
`phase-6-01-kompatibilitaet-und-leistungsabnahme` in `abnahmematrix.md` und
`verification.md` (nach Archivierung unter `openspec/changes/archive/`).
Diese Grundabnahme ersetzt keine native EXE-/TBL-, reale Terminalmatrix-
oder Gitea-Releaseprüfung; diese folgen mit Phase-6-Changes 0207.

View File

@@ -0,0 +1,60 @@
VERSION 1.00
Begin Form Formular
Height = 10
Width = 40
Begin Menu mnuDatei
Caption = "&Datei"
Begin Menu mnuOpen
Caption = "&Open"
End
End
Begin TextBox Text1
Left = 2
Top = 2
Width = 18
Height = 1
TabIndex = 0
End
Begin CommandButton Ok
Caption = "&OK"
Left = 23
Top = 3
Width = 10
Height = 1
TabIndex = 1
End
End
' tb-screen: 80x25
' tb-events: time:0ms | key:<TAB> | resize:100x30 | mouse:down,1,0,4,25 | mouse:up,1,0,4,25 | key:%d | key:o
' Soll: LostFocus vor GotFocus, ein Click, dann Menue. COLOR e1;
' nach Resize passt die Ausgabe ab Spalte 90. Unicode belegt Doppelzellen.
' Quellen: Specs forms-objektmodell, textbildschirm, release-kompatibilitaet.
DIM SHARED trace$
Formular.Show
Text1.SetFocus
FOR i% = 1 TO 20
DOEVENTS
NEXT
Formular.Hide
COLOR 14, 1
CLS
PRINT trace$; "中"
LOCATE 2, 90
PRINT "界Z";
END
SUB Text1_LostFocus()
SHARED trace$
trace$ = trace$ + "Lost;"
END SUB
SUB Ok_GotFocus()
SHARED trace$
trace$ = trace$ + "Got;"
END SUB
SUB Ok_Click()
SHARED trace$
trace$ = trace$ + "Click;"
END SUB
SUB mnuOpen_Click()
SHARED trace$
trace$ = trace$ + "Menu;"
END SUB

View File

@@ -0,0 +1,5 @@
Lost;Got;Click;Menu;中
界Z
--- Attribute (Vordergrund/Hintergrund je Zelle, hex) ---
e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1
e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env python3
"""Erforderlicher Phase-6-Abnahmesatz; keine Downloads oder Golden-Erzeugung."""
import argparse
import os
from pathlib import Path
import subprocess
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--vbdos-repo", type=Path, required=True,
help="lokaler cout/vbdos-Git-Bestand in der in foreign.rs fixierten Revision")
args = parser.parse_args()
env = dict(os.environ, TB_VBDOS_REPO=str(args.vbdos_repo.resolve()))
root = Path(__file__).resolve().parents[2]
commands = [
["cargo", "test", "--locked", "-p", "tb-cli", "--test", "foreign", "--",
"--include-ignored", "--nocapture"],
["cargo", "test", "--locked", "--workspace"],
["cargo", "test", "--locked", "-p", "tb-cli", "--test", "inventar", "--",
"--exact", "abdeckungsstand_wird_ausgewiesen", "--nocapture"],
["cargo", "fmt", "--all", "--", "--check"],
["cargo", "clippy", "--locked", "--workspace", "--all-targets", "--", "-D", "warnings"],
["cargo", "bench", "--locked", "-p", "tb-vm", "--bench", "compile", "--bench", "vm"],
]
for command in commands:
print("+ " + " ".join(command), flush=True)
result = subprocess.run(command, cwd=root, env=env, check=False)
if result.returncode:
return result.returncode if result.returncode > 0 else 1
print("Phase-6-Grundabnahme bestanden; native Ziel-/Releaseabnahme folgt in Changes 0207.")
return 0
if __name__ == "__main__":
raise SystemExit(main())