extends SceneTree ## Suite: Prüfsummen-Fremdformat-Dialog (t_9814f18f). ## Ausführen: godot4 --headless --path . --script res://tests/test_svmap_resign_dialog.gd ## Exit 0 = alles grün. Läuft OHNE UI (nur SvmapIO/SvmapDocument). ## ## Deckt den Sly-Fall ab: Datei von fremdem Writer (V13 schlägt fehl, ## Kern V3–V16 grün) → checksum_only_failure → load_from_file_resign ## akzeptiert + signiert v2 + Roundtrip bleibt stabil. var failures := 0 var checks := 0 func _init() -> void: _cleanup() _run_tests() _cleanup() if failures == 0: print("ALL OK: %d checks" % checks) quit(0) else: print("FAILED: %d/%d checks" % [failures, checks]) quit(1) func _cleanup() -> void: for path in ["user://test_resign.svmap", "user://test_resign2.svmap"]: if FileAccess.file_exists(path): DirAccess.remove_absolute(ProjectSettings.globalize_path(path)) func _check(cond: bool, label: String) -> void: checks += 1 if cond: print(" ok: %s" % label) else: failures += 1 print(" FAIL: %s" % label) func _errors_contain(errors: Array, needle: String) -> bool: for e in errors: if str(e).contains(needle): return true return false func _run_tests() -> void: print("== Fremdformat-Dialog: Erkennung + Resign-Weg (t_9814f18f) ==") var doc := SvmapDocument.create_new("Resign-Test", 512.0, "mittag") _check(doc.has("format_version"), "Test-Dokument erzeugt") # 1) Normaler Save + Load. var save := SvmapIO.save_to_file("user://test_resign.svmap", doc) _check(save["ok"], "Baseline-Map gespeichert (v2)") # 2) Prüfsumme manipulieren (64 Nullen) → V13-only-Fehler. var text := FileAccess.get_file_as_string("user://test_resign.svmap") var parsed: Variant = JSON.parse_string(text) var bad: Dictionary = parsed bad["checksum"]["value"] = "0".repeat(64) var fa := FileAccess.open("user://test_resign.svmap", FileAccess.WRITE) fa.store_string(JSON.stringify(bad, " ")) fa.close() var broken := SvmapIO.load_from_file("user://test_resign.svmap") _check(not broken["ok"], "manipulierte Prüfsumme → Load schlägt fehl") _check(_errors_contain(broken["errors"], "V13"), "Fehler ist V13 (Prüfsumme)") _check(SvmapIO.checksum_only_failure(broken["errors"]), "checksum_only_failure erkennt V13-only-Fall") # 3) Kern-defekte Map (Name leer) → NICHT als V13-only erkennbar. var core_bad: Dictionary = JSON.parse_string(text) core_bad["info"]["name"] = "" var fa2 := FileAccess.open("user://test_resign2.svmap", FileAccess.WRITE) fa2.store_string(JSON.stringify(core_bad, " ")) fa2.close() var core := SvmapIO.load_from_file("user://test_resign2.svmap") _check(not core["ok"], "Kern-defekte Map (Name leer) schlägt fehl") _check(not SvmapIO.checksum_only_failure(core["errors"]), "Kern-Fehler ist KEIN V13-only-Fall (harter Abbruch bleibt)") # 4) Resign-Weg: Datei trotz manipulierter Prüfsumme laden. var resign := SvmapIO.load_from_file_resign("user://test_resign.svmap") _check(resign["ok"], "load_from_file_resign akzeptiert V13-only-Datei") _check(str(resign["data"]["checksum"]["schema"]) == "v2", "Resign trägt schema v2") # 5) Resign-Dokument speichern + laden → stabiler v2-Roundtrip. var resave := SvmapIO.save_to_file("user://test_resign.svmap", resign["data"]) _check(resave["ok"], "Resign-Dokument gespeichert") var reload := SvmapIO.load_from_file("user://test_resign.svmap") _check(reload["ok"], "Resign-Map lädt normal (Roundtrip)") _check(str(reload["data"]["checksum"]["schema"]) == "v2", "Datei trägt v2 nach Resave") # 6) Adversarial-Float im Sly-Fall: 15-stelliger Wert überlebt Resign+Save+Load. var adv: Dictionary = JSON.parse_string(FileAccess.get_file_as_string("user://test_resign.svmap")) if (adv["objects"] as Array).size() > 0: adv["objects"][0]["pos"][1] = 0.000457770656900891 var adv_save := SvmapIO.save_to_file("user://test_resign.svmap", adv) _check(adv_save["ok"], "Map mit adversarial Float gespeichert (Quantisierung)") var adv_load := SvmapIO.load_from_file("user://test_resign.svmap") _check(adv_load["ok"], "Map mit adversarial Float lädt (v2-Hash formatunabhängig)") else: _check(true, "kein Objekt im Default-Dokument — Float-Check entfällt (v2-Suite deckt adversarial ab)")