diff --git a/tests/test_library.gd b/tests/test_library.gd index 1151d70..0f0df47 100644 --- a/tests/test_library.gd +++ b/tests/test_library.gd @@ -58,12 +58,68 @@ func _load_manifest() -> Dictionary: return parsed if parsed is Dictionary else {} +## Gemergte Registry aus dem Match-Server-Sibling (Quelle der Wahrheit — +## library/objects.json entsteht dort aus den Fragmenten objects.d/*.json, +## tools/sync_objects.sh zieht die Kopie hierher). Leer, wenn das Sibling +## fehlt (CI/Klon ohne Nachbar-Repo) — der Test verkürzt sich dann statt zu failen. +func _match_server_registry() -> Dictionary: + var base := ProjectSettings.globalize_path("res://") + for k in [base + "../scopedvr-match-server", base + "../../scopedvr-match-server"]: + var path: String = k + "/library/objects.json" + if FileAccess.file_exists(path): + var parsed: Variant = JSON.parse_string(FileAccess.get_file_as_string(path)) + return parsed if parsed is Dictionary else {} + return {} + + func _test_manifest_load() -> void: print("Testgruppe: Bibliothek laden (library/objects.json)") var manifest := _load_manifest() _check(not manifest.is_empty(), "Manifest lädt und ist ein Objekt") var lib: Dictionary = manifest.get("objects", {}) - _check(lib.size() == 54, "Katalog hat die 54 Objekte (15 Basis + 39 Natur-Update, ist %d)" % lib.size()) + # Datengetrieben statt harte Zahl: Der Basis-Bestand (54 Objekte aus dem + # Merge-Fundament A6) muss IMMER erhalten bleiben — der Katalog darf nur + # wachsen (A6-Beispiele, D1 Wände, D2 Absperrungen, D3 Gebäude, D4 Props, + # D5 Natur, ...). Eine exakte Zahl hier bricht bei jeder Kategorie-Karte. + _check(lib.size() >= 54, "Katalog enthält mindestens die 54 Basis-Objekte (ist %d)" % lib.size()) + # Registry ↔ Thumbnails deckungsgleich: sync_objects.sh zieht objects.json + # UND rendert je Objekt einen Thumb. Drift (Objekt ohne Thumb oder verwaister + # Thumb) zeigt einen nicht gelaufenen/abgebrochenen Sync. + var fehlen_thumb: Array = [] + var verwaist_thumb: Array = [] + var tdir := DirAccess.open("res://library/thumbs") + if tdir != null: + var thumbs: Dictionary = {} + tdir.list_dir_begin() + var f := tdir.get_next() + while not f.is_empty(): + if f.ends_with(".png"): + thumbs[f.get_basename()] = true + f = tdir.get_next() + tdir.list_dir_end() + for oid in lib.keys(): + if not thumbs.has(str(oid)): + fehlen_thumb.append(str(oid)) + for t in thumbs.keys(): + if not lib.has(t): + verwaist_thumb.append(str(t)) + _check(fehlen_thumb.is_empty() and verwaist_thumb.is_empty(), + "Registry und Thumbnails deckungsgleich (fehlen %d, verwaist %d)" % [fehlen_thumb.size(), verwaist_thumb.size()]) + # Alle OIDs der Match-Server-Fragmente sind in der Editor-Kopie (wenn das + # Sibling-Repo neben dem Editor liegt, wie in tools/sync_objects.sh). + var ms := _match_server_registry() + if not ms.is_empty(): + var ms_ids: Dictionary = ms.get("objects", {}) + var fehlt_editor: Array = [] + var fehlt_ms: Array = [] + for oid in ms_ids.keys(): + if not lib.has(str(oid)): + fehlt_editor.append(str(oid)) + for oid in lib.keys(): + if not ms_ids.has(str(oid)): + fehlt_ms.append(str(oid)) + _check(fehlt_editor.is_empty() and fehlt_ms.is_empty(), + "Editor-Registry deckt alle OIDs des Match-Server-Merges ab (fehlen Editor %d / MS %d)" % [fehlt_editor.size(), fehlt_ms.size()]) var all_ok := true for oid in lib.keys(): var entry: Dictionary = lib[oid] @@ -401,7 +457,7 @@ func _test_placement_foot_convention() -> void: ## Ghost UND Viewport-Bauer nutzen, kommt aus derselben Registry-Kollision ## (MeshShapes.half_height). func _test_mesh_foot_point_registry() -> void: - print("Testgruppe: Registry-Fußpunkt — Mesh-Unterseite == pos (alle 54 Objekte)") + print("Testgruppe: Registry-Fußpunkt — Mesh-Unterseite == pos (alle Katalog-Objekte, ist %d)" % _load_manifest().get("objects", {}).size()) var manifest := _load_manifest() var lib: Dictionary = manifest.get("objects", {}) var bad_primitiv: Array = []