M2-Karte t_b84af40f: '▶ Karte testen' (Editor-Seite). Großer deutsch beschrifteter Button oben + Menü-Eintrag: exportiert die AKTUELLE Map (auch ungespeichert) nach user://testrun/<name>.svmap über dieselbe SvmapIO-Validierung wie das Speichern, sucht den scopedvr-client (Klon neben dem Editor ODER client_dir in user://scopedvr_editor.cfg, dokumentiert im README-Abschnitt 'Karte testen') und startet ihn als EIGENEN Prozess (godot --path <client> -- --testmap <map> --mock-master) — Editor bleibt offen, Spiel beendet sich selbst sauber per ESC. Ungültige Map → Klartext-Block statt Start. TestRun-Klasse komplett static + headless testbar. Tests: tests/test_testrun.gd (14 Checks: Temp-Export-Roundtrip, ungültige Map blockiert, Client-Suche inkl. Konfig-Vorrang, Godot-Findung, exakte Argumentliste); run_tests.sh + parse_check.sh um test_testrun/test_run.gd erweitert — volle Suite 220 Checks grün. GODOT-Pfad-Default in tests/run_testmap_e2e.sh des Clients jetzt auto-erkennend (Sly-PC-Pfad → ~/bin/godot4 → PATH).
This commit is contained in:
parent
595d1217d9
commit
0eae5f56ad
8 changed files with 303 additions and 2 deletions
31
README.md
31
README.md
|
|
@ -259,3 +259,34 @@ Mehrfachauswahl + Gruppieren + Gruppen-Verschieben, auf dem UX-Fundament
|
||||||
- **Desktop-Smoke:** `godot … -- --groups-demo [ordner] [--groups-demo-quit]`
|
- **Desktop-Smoke:** `godot … -- --groups-demo [ordner] [--groups-demo-quit]`
|
||||||
fährt Mehrfachauswahl → Gruppieren → gemeinsames Ziehen/Drehen →
|
fährt Mehrfachauswahl → Gruppieren → gemeinsames Ziehen/Drehen →
|
||||||
Undo programmatisch durch und speichert Screenshots.
|
Undo programmatisch durch und speichert Screenshots.
|
||||||
|
|
||||||
|
## Karte testen (M2, Karte t_b84af40f — FERTIG)
|
||||||
|
|
||||||
|
Button „▶ Karte testen“ oben (auch im Datei-Menü) startet die AKTUELLE Map —
|
||||||
|
auch ungespeicherte! — sofort als Spiel in einem EIGENEN Fenster. Der Editor
|
||||||
|
bleibt offen. Im Spiel: WASD laufen, Maus umsehen, Shift sprinten, Leertaste
|
||||||
|
springen, ESC beendet das Test-Fenster sauber (kein Prozess-Kill nötig).
|
||||||
|
|
||||||
|
- **Temp-Export (`src/editor/test_run.gd`):** Die Map wird nach
|
||||||
|
`user://testrun/<name>.svmap` exportiert (deterministischer Name aus dem
|
||||||
|
Map-Namen, erneuter Testlauf überschreibt) — über dieselbe
|
||||||
|
`SvmapIO.save_to_file`-Validierung wie das echte Speichern. Ist die Map
|
||||||
|
noch nicht lauffähig (z. B. Spawn-Zonen fehlen), kommt der Klartext-Block
|
||||||
|
mit den fehlenden Punkten, GESTARTET wird nichts.
|
||||||
|
- **Client-Suche (erste Treffer-Zeile gewinnt):**
|
||||||
|
1. Konfigurationsdatei `user://scopedvr_editor.cfg`:
|
||||||
|
```ini
|
||||||
|
[test]
|
||||||
|
client_dir="/pfad/zu/scopedvr-client"
|
||||||
|
godot_path="/pfad/zu/godot" ; nur nötig, wenn der Editor NICHT über Godot läuft
|
||||||
|
```
|
||||||
|
2. Klon neben dem Editor: `<Editor-Ordner>/../scopedvr-client`
|
||||||
|
(erkennbar an `project.godot`).
|
||||||
|
- **Start:** Der Client läuft als eigener Godot-Prozess
|
||||||
|
(`godot --path <client> -- --testmap <map.svmap> --mock-master`) — kein
|
||||||
|
Master, kein Match-Server, alles lokal. Godot-Binary = das, unter dem der
|
||||||
|
Editor selbst läuft.
|
||||||
|
- **Tests:** `tests/test_testrun.gd` (14 Checks: Temp-Export mit Roundtrip,
|
||||||
|
ungültige Map blockiert, Client-Suche inkl. Konfig-Vorrang, Godot-Findung,
|
||||||
|
exakte Argumentliste). Parse-Check umfasst `test_run.gd`.
|
||||||
|
|
||||||
|
|
|
||||||
91
src/editor/test_run.gd
Normal file
91
src/editor/test_run.gd
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
class_name TestRun
|
||||||
|
extends RefCounted
|
||||||
|
## „▶ Karte testen" (Karte t_b84af40f): Export der AKTUELLEN Map nach Temp
|
||||||
|
## + Start des scopedvr-client als EIGENES Fenster im Testlauf-Modus
|
||||||
|
## (--testmap <pfad>). Der Editor bleibt offen — der Client ist ein eigener
|
||||||
|
## Prozess; das Spiel beendet sich selbst sauber (ESC = „Zurück zum Editor").
|
||||||
|
##
|
||||||
|
## Client-Suche (erste Treffer-Zeile gewinnt):
|
||||||
|
## 1. Konfigurationsdatei user://scopedvr_editor.cfg, Abschnitt [test]:
|
||||||
|
## client_dir="/pfad/zu/scopedvr-client"
|
||||||
|
## 2. Klon neben dem Editor: <Editor-Projektordner>/../scopedvr-client
|
||||||
|
## (erkennbar an project.godot im Ordner).
|
||||||
|
##
|
||||||
|
## Godot-Binary für den Start: das Binary, unter dem der Editor selbst läuft
|
||||||
|
## (OS.get_executable_path — Sly startet den Editor über den Godot-Editor,
|
||||||
|
## also kann DAS auch den Client starten). Läuft der Editor irgendwann als
|
||||||
|
## exportierte App, muss [test] godot_path gesetzt werden.
|
||||||
|
##
|
||||||
|
## Alles static + testbar ohne UI (tests/test_testrun.gd).
|
||||||
|
|
||||||
|
const CFG_PATH := "user://scopedvr_editor.cfg"
|
||||||
|
const TESTRUN_DIR := "user://testrun"
|
||||||
|
|
||||||
|
|
||||||
|
static func load_cfg() -> ConfigFile:
|
||||||
|
var cfg := ConfigFile.new()
|
||||||
|
if FileAccess.file_exists(CFG_PATH):
|
||||||
|
cfg.load(CFG_PATH) # Fehler → Default-Logik greift weiter unten.
|
||||||
|
return cfg
|
||||||
|
|
||||||
|
|
||||||
|
## Liefert den Client-Projektordner (mit project.godot) oder "".
|
||||||
|
static func find_client(project_dir: String, cfg: ConfigFile = null) -> String:
|
||||||
|
var candidates: Array = []
|
||||||
|
if cfg != null:
|
||||||
|
var configured := str(cfg.get_value("test", "client_dir", ""))
|
||||||
|
# Explizit gesetzter Pfad gewinnt, sobald der ORDNER existiert
|
||||||
|
# (bewusst ohne project.godot-Check — wer ihn konfiguriert, weiß es besser).
|
||||||
|
if not configured.is_empty() and DirAccess.dir_exists_absolute(configured):
|
||||||
|
return configured
|
||||||
|
var parent := project_dir.simplify_path().get_base_dir()
|
||||||
|
candidates.append(parent.path_join("scopedvr-client"))
|
||||||
|
for candidate in candidates:
|
||||||
|
var dir := str(candidate).simplify_path()
|
||||||
|
if FileAccess.file_exists(dir.path_join("project.godot")):
|
||||||
|
return dir
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
## Godot-Binary zum Starten des Clients (Editor-Binary oder Konfiguration).
|
||||||
|
static func find_godot(cfg: ConfigFile = null) -> String:
|
||||||
|
var exe := OS.get_executable_path()
|
||||||
|
if exe.get_file().to_lower().contains("godot"):
|
||||||
|
return exe
|
||||||
|
if cfg != null:
|
||||||
|
return str(cfg.get_value("test", "godot_path", ""))
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
## Deterministischer Temp-Pfad aus dem Map-Namen (erneuter Testlauf
|
||||||
|
## überschreibt die alte Export-Datei — kein Müll-Berg).
|
||||||
|
static func temp_map_path(doc: Dictionary) -> String:
|
||||||
|
var raw := str(doc.get("info", {}).get("name", "")).strip_edges()
|
||||||
|
if raw.is_empty():
|
||||||
|
raw = "karte"
|
||||||
|
var safe := ""
|
||||||
|
for ch in raw:
|
||||||
|
var c := ch.to_lower()
|
||||||
|
if (c >= "a" and c <= "z") or (c >= "0" and c <= "9") or ch == "_" or ch == "-" or ch == " ":
|
||||||
|
safe += ch
|
||||||
|
else:
|
||||||
|
safe += "_"
|
||||||
|
safe = safe.strip_edges().replace(" ", "_").rstrip("_")
|
||||||
|
if safe.is_empty():
|
||||||
|
safe = "karte"
|
||||||
|
return TESTRUN_DIR.path_join(safe + ".svmap")
|
||||||
|
|
||||||
|
|
||||||
|
## Exportiert das AKTUELLE Dokument (auch ungespeicherte Maps!) nach Temp.
|
||||||
|
## Rückgabe: {ok, errors, path} — path ist globalisiert (für den Client-Prozess).
|
||||||
|
static func export_temp_map(doc: Dictionary) -> Dictionary:
|
||||||
|
var rel := temp_map_path(doc)
|
||||||
|
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path(TESTRUN_DIR))
|
||||||
|
var result := SvmapIO.save_to_file(rel, doc)
|
||||||
|
result["path"] = ProjectSettings.globalize_path(rel)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
## Argumentliste für den Client-Start (getestet: exakt diese Form).
|
||||||
|
static func launch_args(client_dir: String, map_path: String) -> PackedStringArray:
|
||||||
|
return PackedStringArray(["--path", client_dir, "--", "--testmap", map_path, "--mock-master"])
|
||||||
1
src/editor/test_run.gd.uid
Normal file
1
src/editor/test_run.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cd3gmuvpf5ldv
|
||||||
|
|
@ -94,6 +94,9 @@ var check_btn: Button
|
||||||
var check_dialog: AcceptDialog
|
var check_dialog: AcceptDialog
|
||||||
var check_text: Label
|
var check_text: Label
|
||||||
|
|
||||||
|
# Karte testen (Karte t_b84af40f)
|
||||||
|
var test_btn: Button
|
||||||
|
|
||||||
# Dialoge
|
# Dialoge
|
||||||
var new_dialog: AcceptDialog
|
var new_dialog: AcceptDialog
|
||||||
var open_dialog: FileDialog
|
var open_dialog: FileDialog
|
||||||
|
|
@ -150,6 +153,8 @@ func _build_ui() -> void:
|
||||||
popup.add_item("Speichern (Strg+S)", 2)
|
popup.add_item("Speichern (Strg+S)", 2)
|
||||||
popup.add_item("Speichern unter…", 3)
|
popup.add_item("Speichern unter…", 3)
|
||||||
popup.add_separator()
|
popup.add_separator()
|
||||||
|
popup.add_item("▶ Karte testen", 5)
|
||||||
|
popup.add_separator()
|
||||||
popup.add_item("Beenden", 4)
|
popup.add_item("Beenden", 4)
|
||||||
popup.id_pressed.connect(_on_menu_action)
|
popup.id_pressed.connect(_on_menu_action)
|
||||||
top_h.add_child(file_menu)
|
top_h.add_child(file_menu)
|
||||||
|
|
@ -176,6 +181,14 @@ func _build_ui() -> void:
|
||||||
check_btn.pressed.connect(_on_check_map)
|
check_btn.pressed.connect(_on_check_map)
|
||||||
top_h.add_child(check_btn)
|
top_h.add_child(check_btn)
|
||||||
|
|
||||||
|
# Karte testen (Karte t_b84af40f): Map SOFORT als Spiel zum Durchlaufen.
|
||||||
|
test_btn = Button.new()
|
||||||
|
test_btn.text = "▶ Karte testen"
|
||||||
|
test_btn.custom_minimum_size = Vector2(190, 40)
|
||||||
|
test_btn.tooltip_text = "Startet die Map SOFORT als Spiel zum Durchlaufen — eigenes Fenster, der Editor bleibt offen. ESC im Spiel = zurück zum Editor."
|
||||||
|
test_btn.pressed.connect(_on_test_run)
|
||||||
|
top_h.add_child(test_btn)
|
||||||
|
|
||||||
var title_label := Label.new()
|
var title_label := Label.new()
|
||||||
title_label.text = " %s" % APP_TITLE
|
title_label.text = " %s" % APP_TITLE
|
||||||
title_label.add_theme_font_size_override("font_size", 20)
|
title_label.add_theme_font_size_override("font_size", 20)
|
||||||
|
|
@ -756,6 +769,54 @@ func _on_menu_action(id: int) -> void:
|
||||||
save_dialog.popup_centered()
|
save_dialog.popup_centered()
|
||||||
4: # Beenden
|
4: # Beenden
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
5: # Karte testen
|
||||||
|
_on_test_run()
|
||||||
|
|
||||||
|
|
||||||
|
## „▶ Karte testen" (Karte t_b84af40f): aktuelle Map (auch ungespeichert!)
|
||||||
|
## nach Temp exportieren und den scopedvr-client als EIGENES Fenster starten.
|
||||||
|
## Der Editor bleibt offen; das Spiel beendet sich selbst sauber (ESC).
|
||||||
|
func _on_test_run() -> void:
|
||||||
|
if doc.is_empty():
|
||||||
|
_set_status("Erst eine Map anlegen (Datei → Neue Map), dann testen.", true)
|
||||||
|
return
|
||||||
|
var cfg := TestRun.load_cfg()
|
||||||
|
var client_dir := TestRun.find_client(ProjectSettings.globalize_path("res://"), cfg)
|
||||||
|
if client_dir.is_empty():
|
||||||
|
_show_errors("Karte testen — das Spiel wurde nicht gefunden:", [
|
||||||
|
"Der ScopedVR-Client (Ordner „scopedvr-client“) wurde nicht neben dem Editor gefunden.",
|
||||||
|
"So geht es: Den Client-Ordner neben den Editor-Ordner legen (gleicher Überordner),",
|
||||||
|
"ODER in der Datei scopedvr_editor.cfg im Ordner „ScopedVR Map Editor“ (Godot-App-Daten) eintragen:",
|
||||||
|
" [test]",
|
||||||
|
" client_dir=\"/pfad/zu/scopedvr-client\"",
|
||||||
|
" godot_path=\"/pfad/zu/godot\" (nur nötig, wenn der Editor NICHT über Godot gestartet wird)",
|
||||||
|
])
|
||||||
|
_set_status("Karte testen: Spiel nicht gefunden — siehe Fenster.", true)
|
||||||
|
return
|
||||||
|
var godot := TestRun.find_godot(cfg)
|
||||||
|
if godot.is_empty():
|
||||||
|
_show_errors("Karte testen — Godot-Programm nicht gefunden:", [
|
||||||
|
"Der Editor läuft gerade nicht über ein Godot-Programm, deshalb weiß er nicht,",
|
||||||
|
"wie er das Spiel-Fenster starten soll. Trage in scopedvr_editor.cfg ein:",
|
||||||
|
" [test]",
|
||||||
|
" godot_path=\"/pfad/zu/godot\"",
|
||||||
|
])
|
||||||
|
_set_status("Karte testen: Godot-Programm nicht gefunden — siehe Fenster.", true)
|
||||||
|
return
|
||||||
|
var exported := TestRun.export_temp_map(doc)
|
||||||
|
if not bool(exported["ok"]):
|
||||||
|
_show_errors("Karte testen — die Map ist noch nicht lauffähig:", exported["errors"])
|
||||||
|
_set_status("Testlauf nicht möglich — siehe Fenster für die fehlenden Punkte (z. B. Spawn-Zonen).", true)
|
||||||
|
return
|
||||||
|
var map_name := str(doc.get("info", {}).get("name", "?"))
|
||||||
|
var args := TestRun.launch_args(client_dir, str(exported["path"]))
|
||||||
|
var pid := OS.create_process(godot, args)
|
||||||
|
if pid <= 0:
|
||||||
|
_show_errors("Karte testen — Start fehlgeschlagen:", [
|
||||||
|
"Das Spiel-Fenster konnte nicht gestartet werden (Programm: %s)." % godot])
|
||||||
|
_set_status("Karte testen: Start fehlgeschlagen.", true)
|
||||||
|
return
|
||||||
|
_set_status("▶ Karte „%s“ läuft im Test-Fenster — WASD laufen, ESC zurück zum Editor. Der Editor bleibt offen." % map_name)
|
||||||
|
|
||||||
|
|
||||||
func _on_new_map_confirmed() -> void:
|
func _on_new_map_confirmed() -> void:
|
||||||
|
|
|
||||||
116
tests/test_testrun.gd
Normal file
116
tests/test_testrun.gd
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
extends SceneTree
|
||||||
|
## Editor-Tests (headless): Karte t_b84af40f — „▶ Karte testen" Verkabelung.
|
||||||
|
## Ausführen: godot --headless --path . --script res://tests/test_testrun.gd
|
||||||
|
## Exit 0 = alles grün. Läuft OHNE UI (TestRun/SvmapIO/SvmapDocument):
|
||||||
|
## Temp-Export (auch ungespeicherte Maps), Client-Suche, Godot-Binär-Findung,
|
||||||
|
## Argument-Aufbau — der eigentliche Prozess-Start ist Desktop-Sache
|
||||||
|
## (run_testmap_e2e.sh im CLIENT deckt die other-Seite ab).
|
||||||
|
|
||||||
|
var failures := 0
|
||||||
|
var checks := 0
|
||||||
|
|
||||||
|
const TEST_DIR := "user://test_testrun"
|
||||||
|
|
||||||
|
|
||||||
|
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 _check(cond: bool, label: String) -> void:
|
||||||
|
checks += 1
|
||||||
|
if cond:
|
||||||
|
print(" ok: %s" % label)
|
||||||
|
else:
|
||||||
|
failures += 1
|
||||||
|
print(" FAIL: %s" % label)
|
||||||
|
|
||||||
|
|
||||||
|
func _cleanup() -> void:
|
||||||
|
_cleanup_dir(ProjectSettings.globalize_path(TEST_DIR))
|
||||||
|
var rel := TestRun.temp_map_path({"info": {"name": "Testmap"}})
|
||||||
|
var p := ProjectSettings.globalize_path(rel)
|
||||||
|
if FileAccess.file_exists(p):
|
||||||
|
DirAccess.remove_absolute(p)
|
||||||
|
|
||||||
|
|
||||||
|
func _cleanup_dir(base: String) -> void:
|
||||||
|
if not DirAccess.dir_exists_absolute(base):
|
||||||
|
return
|
||||||
|
var d := DirAccess.open(base)
|
||||||
|
if d == null:
|
||||||
|
return
|
||||||
|
for file in d.get_files():
|
||||||
|
DirAccess.remove_absolute(base.path_join(file))
|
||||||
|
for sub in d.get_directories():
|
||||||
|
_cleanup_dir(base.path_join(sub))
|
||||||
|
DirAccess.remove_absolute(base)
|
||||||
|
|
||||||
|
|
||||||
|
func _run_tests() -> void:
|
||||||
|
print("== Temp-Map-Pfad ==")
|
||||||
|
var path := TestRun.temp_map_path({"info": {"name": "Offenes Gelände 2!"}})
|
||||||
|
_check(str(path).begins_with("user://testrun/"), "Temp-Pfad liegt unter user://testrun/")
|
||||||
|
_check(str(path).ends_with("Offenes_Gel_nde_2.svmap"), "Map-Name bereinigt (Sonderzeichen → _, kein trailing _)")
|
||||||
|
path = TestRun.temp_map_path({})
|
||||||
|
_check(str(path).ends_with("karte.svmap"), "fehlender Name → Fallback „karte.svmap“")
|
||||||
|
|
||||||
|
print("== Temp-Export (ungespeicherte Map) ==")
|
||||||
|
var doc := SvmapDocument.create_new("Testkarte", 256.0, "mittag")
|
||||||
|
var exported := TestRun.export_temp_map(doc)
|
||||||
|
_check(bool(exported["ok"]), "neue Map exportiert (ohne je gespeichert zu haben)")
|
||||||
|
var global_path := str(exported["path"])
|
||||||
|
_check(FileAccess.file_exists(global_path), "Temp-Datei existiert auf Disk")
|
||||||
|
var back := SvmapIO.load_from_file(global_path)
|
||||||
|
_check(bool(back["ok"]), "Temp-Datei lädt wieder (Prüfsumme gültig — voller Roundtrip)")
|
||||||
|
_check(str(back["data"]["info"]["name"]) == "Testkarte", "Inhalt identisch")
|
||||||
|
|
||||||
|
print("== Temp-Export (ungültige Map → Klartext-Block) ==")
|
||||||
|
var broken: Dictionary = doc.duplicate(true)
|
||||||
|
broken["spawn_zones"] = {"0": {"points": []}, "1": {"points": []}}
|
||||||
|
var failed := TestRun.export_temp_map(broken)
|
||||||
|
_check(not bool(failed["ok"]), "ungültige Map wird NICHT exportiert")
|
||||||
|
_check((failed["errors"] as Array).size() > 0, "Fehlerliste fürs Dialog-Fenster vorhanden")
|
||||||
|
|
||||||
|
print("== Client-Suche ==")
|
||||||
|
var base := ProjectSettings.globalize_path(TEST_DIR)
|
||||||
|
DirAccess.make_dir_recursive_absolute(base.path_join("mein-editor-projekt"))
|
||||||
|
DirAccess.make_dir_recursive_absolute(base.path_join("scopedvr-client"))
|
||||||
|
var f := FileAccess.open(base.path_join("scopedvr-client/project.godot"), FileAccess.WRITE)
|
||||||
|
f.store_string("[application]\n")
|
||||||
|
# 2) Nachbar-Klon wird gefunden:
|
||||||
|
var found := TestRun.find_client(base.path_join("mein-editor-projekt"), ConfigFile.new())
|
||||||
|
_check(found == base.path_join("scopedvr-client"),
|
||||||
|
"Nachbar-Klon ../scopedvr-client gefunden")
|
||||||
|
# 1) Konfiguration gewinnt (Ordner existiert, ohne project.godot-Check):
|
||||||
|
var cfg := ConfigFile.new()
|
||||||
|
cfg.set_value("test", "client_dir", base.path_join("irgendwo"))
|
||||||
|
DirAccess.make_dir_recursive_absolute(base.path_join("irgendwo"))
|
||||||
|
var found2 := TestRun.find_client(base.path_join("mein-editor-projekt"), cfg)
|
||||||
|
_check(found2 == base.path_join("irgendwo"), "Konfig-Pfad hat Vorrang (Ordner existiert)")
|
||||||
|
# 3) Gar nichts da:
|
||||||
|
DirAccess.remove_absolute(base.path_join("scopedvr-client/project.godot"))
|
||||||
|
var found3 := TestRun.find_client(base.path_join("mein-editor-projekt"), ConfigFile.new())
|
||||||
|
_check(found3 == "", "kein Client → leerer String (Fehler-Dialog greift)")
|
||||||
|
|
||||||
|
print("== Godot-Binär-Findung ==")
|
||||||
|
var exe := TestRun.find_godot(ConfigFile.new())
|
||||||
|
_check(not exe.is_empty() and exe.get_file().to_lower().contains("godot"),
|
||||||
|
"Editor läuft über Godot → dasselbe Binary zum Starten")
|
||||||
|
|
||||||
|
print("== Argument-Aufbau ==")
|
||||||
|
var args := TestRun.launch_args("/pfad/client", "/tmp/x.svmap")
|
||||||
|
var want := ["--path", "/pfad/client", "--", "--testmap", "/tmp/x.svmap", "--mock-master"]
|
||||||
|
var ok := args.size() == want.size()
|
||||||
|
if ok:
|
||||||
|
for i in want.size():
|
||||||
|
if str(args[i]) != want[i]:
|
||||||
|
ok = false
|
||||||
|
_check(ok, "launch_args exakt: --path … -- --testmap … --mock-master")
|
||||||
1
tests/test_testrun.gd.uid
Normal file
1
tests/test_testrun.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dhycopnavsglm
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
GODOT=~/bin/godot4
|
GODOT=~/bin/godot4
|
||||||
fail=0
|
fail=0
|
||||||
for f in src/ui/main.gd src/editor/library_browser.gd src/editor/object_ops.gd \
|
for f in src/ui/main.gd src/editor/test_run.gd src/editor/library_browser.gd src/editor/object_ops.gd \
|
||||||
src/editor/interaction.gd tools/gen_thumbs.gd tests/test_library.gd; do
|
src/editor/interaction.gd tools/gen_thumbs.gd tests/test_library.gd; do
|
||||||
out=$("$GODOT" --headless --path . --check-only --script "res://$f" 2>&1 | grep -iv "godot engine\|^$" || true)
|
out=$("$GODOT" --headless --path . --check-only --script "res://$f" 2>&1 | grep -iv "godot engine\|^$" || true)
|
||||||
if [ -n "$out" ]; then
|
if [ -n "$out" ]; then
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
GODOT=~/bin/godot4
|
GODOT=~/bin/godot4
|
||||||
rc=0
|
rc=0
|
||||||
for t in test_ux test_editor_svmap test_terrain test_library test_spawns; do
|
for t in test_ux test_editor_svmap test_terrain test_library test_spawns test_testrun; do
|
||||||
"$GODOT" --headless --path . --script "res://tests/$t.gd" > "/tmp/$t.log" 2>&1
|
"$GODOT" --headless --path . --script "res://tests/$t.gd" > "/tmp/$t.log" 2>&1
|
||||||
code=$?
|
code=$?
|
||||||
line=$(grep -E "ALL OK|FAILED" "/tmp/$t.log" | tail -1)
|
line=$(grep -E "ALL OK|FAILED" "/tmp/$t.log" | tail -1)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue