Forms-Zustand und Darstellung korrigieren und Change archivieren
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
# Verifikation: forms-zustand-und-bedienung
|
||||
|
||||
Abnahme vom 05.09.2026, umgesetzt auf Basis von `644a862`.
|
||||
Nach erfolgreicher Verifikation am selben Tag synchronisiert und archiviert. **V1, V2 und V3 sind behoben. Keine
|
||||
offenen Befunde im Change.** Beide Delta-Requirements, alle acht Szenarien,
|
||||
die ergänzten Abnahmetasks und D1–D3 wurden erneut gegen Code und Tests geprüft.
|
||||
|
||||
| Dimension | Ergebnis |
|
||||
| --- | --- |
|
||||
| Vollständigkeit | 7/7 Tasks vollständig umgesetzt; beide Delta-Requirements mit allen acht Szenarien abgedeckt. Task 4.2 einschließlich Mindestmaßen und verwandten Zeichenpfaden erfüllt. |
|
||||
| Korrektheit | 428 Workspace-Tests und alle vier Review-Proben bestanden. Keine kritischen Befunde, Warnungen oder offenen Verbesserungsvorschläge. |
|
||||
| Kohärenz | D1–D3 umgesetzt. Die stabile Sortierung erhält die Auswahl; Simple-ComboBox und ListBox verwenden denselben Listenrenderer. |
|
||||
|
||||
## V3 — behoben; historischer Befund vor der Korrektur
|
||||
|
||||
Die folgenden Beobachtungen gelten für den vorherigen Stand. Die Korrektur
|
||||
und ihre erweiterten Nachweise stehen im nächsten Abschnitt.
|
||||
|
||||
### V3 (ursprünglich mittel): Listenrenderer überschreitet zulässige Mindestmaße
|
||||
|
||||
**Reproduktion:** Sichtbare Simple-ComboBox mit Width = 1, Height = 5,
|
||||
Left = 2, Top = 2 in einem ausreichend großen Formular. Gegenüber dem
|
||||
Bildschirm mit ausgeblendetem Control werden auch die Zellen in Spalte 4,
|
||||
Zeilen 4–7 überschrieben; die einzige erlaubte Controlspalte ist Spalte 3.
|
||||
Eine ListBox mit Width = 1 hat denselben horizontalen Überlauf. Bei einer
|
||||
ListBox mit Width = 6, Height = 1 wird zusätzlich die vollständige Zeile
|
||||
unterhalb des Controls gezeichnet. Benachbarte Inhalte können dadurch
|
||||
überschrieben werden.
|
||||
|
||||
**Ursache:** [list_lines](../../../../crates/tb-ui/src/forms.rs#L2047) verwendet
|
||||
`box_lines`, das Breite und Höhe auf mindestens 2 erhöht. Für Width < 3
|
||||
kehrt der Listenrenderer ohne Begrenzung zurück; im ListBox-Pfad fehlt
|
||||
auch eine abschließende Höhenbegrenzung. `write_at` begrenzt ausschließlich
|
||||
auf den Bildschirm. [Width und Height](../../../../crates/tb-frontend/src/forms.rs#L202)
|
||||
lassen ausdrücklich den Wert 1 zu.
|
||||
|
||||
**Vertrag:** Task 4.2 verlangt die Prüfung von Kürzung und Größenbegrenzung
|
||||
für die Simple-ComboBox. Der neue gemeinsame Renderer übernimmt die bereits
|
||||
vorhandene Mindestmaß-Lücke auch für die nun dargestellte Simple-Liste.
|
||||
Die bestehenden Regressionen prüfen Breite 6 und kleine Combo-Höhen,
|
||||
aber weder Breite 1 noch die ListBox-Höhe 1.
|
||||
|
||||
**Behebung:** Die gemeinsame Listenausgabe auf die tatsächlich angeforderte
|
||||
Breite und Höhe begrenzen. Mindestbreite 1 für beide Klassen und Mindesthöhe 1
|
||||
für ListBox durch Bildschirmprüfungen absichern; normale Maße beibehalten.
|
||||
|
||||
**Nachweis:** `listen_bleiben_auch_bei_minimalmassen_im_controlrechteck` in
|
||||
[review-probes.rs](review-probes.rs) prüft den tatsächlichen Bildschirm vor
|
||||
und nach Einblenden des Controls. Die Kontrollfälle ComboBox 15×5 und
|
||||
ListBox 6×4 bleiben innerhalb ihrer Grenzen; die drei Mindestmaßfälle
|
||||
schlugen vor der Behebung fehl und bestehen jetzt mit unveränderten Erwartungen.
|
||||
|
||||
## Behebung und Regressionen
|
||||
|
||||
- **V1:** Gemeinsame Sortierung für Laufzeit- und initiale Property-Zugriffe.
|
||||
Sortierung ohne Beachtung der Groß-/Kleinschreibung; ursprüngliche Indizes
|
||||
erhalten die Auswahl auch zwischen gleichen Texten. Regressionen prüfen
|
||||
beide Klassen, alle ComboBox-Stile, Basis-/Arrayindex 0 und dynamische
|
||||
Arrayelemente, wiederholtes Sortieren sowie anschließendes Einfügen/Entfernen.
|
||||
Der Formular-Korpus prüft jetzt das Einschalten von Sorted nach dem Befüllen
|
||||
mit unveränderter Sollausgabe.
|
||||
- **V2:** Simple verwendet den bestehenden Listenrenderer samt Rahmen und
|
||||
Auswahlmarkierung. Der Bildschirmtest prüft tatsächliche Einträge, Auswahl,
|
||||
Entfernen und erhaltenen Eingabetext. V3 ergänzt die Mindestmaßabnahme.
|
||||
- **V3:** `list_lines` begrenzt sämtliche Rahmenzeilen auf die angeforderte
|
||||
Breite und Höhe, auch vor dem frühen Rücksprung für schmale Controls.
|
||||
Alle Aufrufer (ListBox, Simple-ComboBox, DirListBox und FileListBox)
|
||||
verwenden diese Korrektur. Die gemeinsame Textkürzung zählt dieselben
|
||||
Zellenbreiten wie TextScreen und behandelt Steuerzeichen als Leerzeichen.
|
||||
`TextScreen::print_line` verwendet den vorhandenen Zellenschreibpfad ohne
|
||||
Umbruch oder Scrollen; `write_at` nutzt ihn für Forms-Ausgaben.
|
||||
Das normale BASIC-PRINT behält Umbruch und Scrollen.
|
||||
|
||||
Die zusätzliche Regression
|
||||
`listenrenderer_haelt_zellgrenzen_auch_an_bildschirmraendern_ein` vergleicht
|
||||
alle Bildschirmzellen außerhalb des jeweiligen Controlrechtecks einschließlich
|
||||
Farben und Unicode-Fortsetzungsmarkierung. **3.360 Kombinationen bestehen:**
|
||||
ListBox, Combo-Stile 0/1/2, DirListBox, FileListBox und DriveListBox;
|
||||
Basis- und dynamische Arrayelemente; Breiten 1/2/3/6/15/254 und Höhen
|
||||
1/2/3/5/254; vier Positionen einschließlich rechtem/unterem Bildschirmrand
|
||||
und vollständig außerhalb; leere und gefüllte Listen mit langen Texten,
|
||||
breiten Unicode-Zeichen und CR/LF. Vor der Korrektur schlug dieser Test
|
||||
bereits bei einer ListBox 1×1 fehl.
|
||||
|
||||
`ui_zeile_bleibt_am_rand_ohne_umbruch_oder_scrollen` prüft zusätzlich
|
||||
vollständig passende und nicht passende breite Zeichen, Farben, CR/LF
|
||||
sowie den rechten/unteren Rand und einen eigenen VIEW-PRINT-Bereich.
|
||||
Bestehende Zeichenbild-, Auswahl-, Timer-, VM- und Korpustests bestehen
|
||||
unverändert in ihren Erwartungen.
|
||||
|
||||
## Ursprüngliche Befunde — historischer Stand vor der Behebung
|
||||
|
||||
Die folgenden Ist-Beobachtungen dokumentieren den fehlgeschlagenen Review.
|
||||
Beide Befunde sind durch die Nachweise oben geschlossen.
|
||||
|
||||
### V1: Nachträgliches Sorted lässt den Listeninhalt unsortiert
|
||||
|
||||
**Reproduktion:** In ListBox oder ComboBox zuerst `b`, dann `a` hinzufügen,
|
||||
Eintrag 0 (`b`) auswählen, anschließend `Sorted = -1` setzen und `c`
|
||||
hinzufügen. **Ist:** `List = [b, a, c]`, ListIndex = 0.
|
||||
**Soll:** sortierte Liste `[a, b, c]` mit weiterhin ausgewähltem `b`, Index 1.
|
||||
|
||||
Der [Property-Setter](../../../../crates/tb-ui/src/forms.rs#L430) speichert
|
||||
SORTED ohne Sortierung des vorhandenen Inhalts. [ADDITEM](../../../../crates/tb-ui/src/forms.rs#L1025)
|
||||
verwendet anschließend `partition_point`, das bereits sortierte Daten
|
||||
voraussetzt. Der Fehler tritt bei beiden Klassen auf.
|
||||
|
||||
**Vertrag:** Delta „Steuerelemente mit Listeninhalt“, Sortierung bei
|
||||
Sorted = −1 und Konsistenz von List/ListIndex/Text; Task 1.1.
|
||||
Die Tests setzen Sorted ausschließlich vor dem Befüllen und decken den
|
||||
zulässigen Wechsel an einer gefüllten Liste nicht ab.
|
||||
|
||||
**Behebung:** Beim Einschalten der Sortierung vorhandene Einträge sortieren
|
||||
und die Auswahl ihrem bisherigen Eintrag zuordnen; anschließend Einfügen
|
||||
und Entfernen weiterhin konsistent halten. Regression für beide Klassen,
|
||||
einschließlich der Auswahl, ergänzen.
|
||||
|
||||
### V2: ComboBox.Style 1 zeichnet keine Listeneinträge
|
||||
|
||||
**Reproduktion:** Sichtbare ComboBox mit Style = 1, Width = 15, Height = 5,
|
||||
Text = `frei`; ADDITEM `apfel` und `birne`. **Ist:** Der Bildschirm zeigt
|
||||
`frei` und einen leeren eingerahmten Listenbereich. **Soll:** Die beiden
|
||||
Einträge erscheinen in diesem ausreichend großen Bereich.
|
||||
|
||||
Der [Renderer](../../../../crates/tb-ui/src/forms.rs#L2184) hängt für Style 1
|
||||
nur `box_lines` mit leerem Inhalt an. Er liest die vorhandenen Listeneinträge
|
||||
für diesen Bereich nicht. Die Probe prüft zuerst, dass das Control über den
|
||||
Text `frei` tatsächlich sichtbar ist, und danach die beiden Listeneinträge.
|
||||
|
||||
**Vertrag:** Delta „Steuerelemente mit Listeninhalt“ verlangt die Darstellung
|
||||
aller drei ComboBox-Stile; die [Forms-Referenz](../../../../docs/forms-referenz.md#L180)
|
||||
zeigt für Simple einen sichtbaren Listeneintrag. Task 1.1 verlangt die Prüfung
|
||||
aller Stile. Der bestehende Stiltest prüft nur Zeilenzahl und Präfix;
|
||||
die neuen Auswahltests prüfen nur die oberste Zeile.
|
||||
|
||||
**Behebung:** Den vorhandenen Listeninhalt samt Auswahl im Simple-Bereich
|
||||
darstellen und dessen Inhalt mit einem Bildschirmtest absichern. Die bereits
|
||||
festgelegten Zeichenformen beibehalten.
|
||||
|
||||
Beide Lücken bestanden bereits vor diesem Change. Es handelt sich um
|
||||
verbleibende Abweichungen im übernommenen Listen-Requirement, nicht um neu
|
||||
eingeführte Regressionen. Die Korrekturen wurden nach diesem Review umgesetzt.
|
||||
|
||||
## Szenarioabdeckung und positive Nachweise
|
||||
|
||||
| Delta-Szenario | Nachweis |
|
||||
| --- | --- |
|
||||
| Element hinzufügen | Bestehender Sorted-Listentest und neue Auswahlmatrix: a/b, ListCount und List(i). Nachträgliches Einschalten einschließlich stabiler Auswahl durch V1-Regressionen abgesichert. |
|
||||
| Keine Auswahl | ListIndex −1 bei leerer Liste und nach Entfernen der Auswahl. |
|
||||
| Auswahl ausdrücklich aufheben | Modellmatrix für ListBox und ComboBox-Stile 0/1/2; Formular-Korpus. |
|
||||
| Eintrag vor Auswahl einfügen | Sortierte/unsortierte Modellmatrix prüft Indexverschiebung und erhaltenen Text. |
|
||||
| Timer feuert im Abstand | Zwei Ereignisse nach 250 ms aktiver Zeit, mehrere Timer und Arrayelemente, identische Wiederholung. |
|
||||
| Interval 0 schaltet ab | Modelltest, Arrayindex-0-Reset und Änderung im VM-Handler. |
|
||||
| Späte Aktivierung | VM: direkte Property, Control-Parameter und Enabled; Aktivierung bei 1000, still bei 1099, einmal bei 1100 ms. Zusätzliche erfolgreiche Probe für spät geladenes Timer-Arrayelement. |
|
||||
| Abschalten verwirft anstehende Ereignisse | Interval/Enabled-Reset, Array-Entladen und Handlerwechsel mit altem Rückstau. |
|
||||
|
||||
Erneut ausgeführt:
|
||||
|
||||
- `cargo test --workspace`: **428 bestanden, 0 fehlgeschlagen, 1 ignoriert**.
|
||||
Ignoriert bleibt der Generator für Sollausgaben; keine Golden Files geändert.
|
||||
- `openspec validate forms-zustand-und-bedienung --strict`: gültig.
|
||||
- `git diff --check`: erfolgreich.
|
||||
- [Zusätzliche Review-Proben](review-probes.rs): **4 bestanden, 0 fehlgeschlagen**.
|
||||
|
||||
`cargo clippy -p tb-ui -p tb-vm -p tb-runtime --all-targets --all-features -- -D warnings`
|
||||
und `cargo fmt --all -- --check` wurden nach der Behebung erfolgreich ausgeführt. Kein interaktiver Terminal-/VBDOS-Vergleich und
|
||||
keine Windows-/Linux-Matrix. Die Darstellungsprobe prüft den echten Zellenpuffer
|
||||
ohne Terminal; Timerprüfungen verwenden ausschließlich virtuelle Hostzeit.
|
||||
|
||||
## Review-Proben reproduzieren
|
||||
|
||||
Im Repository-Wurzelverzeichnis ausführen; erzeugt einen separaten temporären
|
||||
Cargo-Treiber. Auf dem korrigierten Stand bestehen alle vier Proben.
|
||||
|
||||
```sh
|
||||
python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import json, subprocess, tempfile
|
||||
root = Path.cwd()
|
||||
p = Path(tempfile.mkdtemp(prefix='tb-forms-review-'))
|
||||
manifest = '[package]\nname="tb-forms-review"\nversion="0.0.0"\nedition="2021"\n[workspace]\n'
|
||||
manifest += '[[test]]\nname="probes"\npath=' + json.dumps(str(root / 'openspec/changes/archive/2026-09-05-forms-zustand-und-bedienung/review-probes.rs')) + '\n[dependencies]\n'
|
||||
for name in ['tb-ui', 'tb-vm', 'tb-runtime', 'tb-frontend']:
|
||||
manifest += name + ' = { path = ' + json.dumps(str(root / 'crates' / name)) + ' }\n'
|
||||
(p / 'Cargo.toml').write_text(manifest)
|
||||
subprocess.run(['cargo', 'test', '--manifest-path', str(p / 'Cargo.toml'), '--offline', '--test', 'probes', '--', '--nocapture'], check=True, timeout=120)
|
||||
PY
|
||||
```
|
||||
Reference in New Issue
Block a user