126 lines
5.5 KiB
GDScript
126 lines
5.5 KiB
GDScript
extends SceneTree
|
|
|
|
const CONTENT_PATHS := preload("res://scripts/shared/content_paths.gd")
|
|
const CLI_LAUNCHER := preload("res://scripts/tools/cli_scene_launcher.gd")
|
|
const STAGE_SCENE_IO := preload("res://scripts/stage/stage_scene_io.gd")
|
|
const STAGE_SCENE := preload("res://scenes/stage/sandbox_stage.tscn")
|
|
|
|
const LEGACY_STAGE_PATH: String = "res://tests/.phase14_legacy_paths.scene"
|
|
const RESAVED_STAGE_PATH: String = "res://tests/.phase14_resaved_paths_resaved.scene"
|
|
|
|
var _checks: int = 0
|
|
var _failures: int = 0
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_run")
|
|
|
|
|
|
func _run() -> void:
|
|
_test_path_mapping()
|
|
_test_moved_stage_file_paths()
|
|
await _test_legacy_stage_round_trip()
|
|
_cleanup()
|
|
print("RESULT: %d checks, %d failures" % [_checks, _failures])
|
|
quit(1 if _failures > 0 else 0)
|
|
|
|
|
|
func _expect(condition: bool, message: String) -> void:
|
|
_checks += 1
|
|
if condition:
|
|
print("PASS: " + message)
|
|
else:
|
|
_failures += 1
|
|
push_error("Content path test failed: " + message)
|
|
|
|
|
|
func _test_path_mapping() -> void:
|
|
_expect(CONTENT_PATHS.canonicalize("res://stickmen/basic.stk") == "res://content/stickmen/basic.stk", "legacy stickman resource paths map into content")
|
|
_expect(CONTENT_PATHS.canonicalize("res://props/briefcase.prop") == "res://content/props/briefcase.prop", "legacy prop resource paths map into content")
|
|
_expect(CONTENT_PATHS.canonicalize("res://game_scenes/bend.scene") == "res://content/stages/bend.scene", "legacy stage resource paths map into content")
|
|
_expect(CONTENT_PATHS.canonicalize("res://unmanaged/asset.stk") == "res://unmanaged/asset.stk", "unknown resource paths pass through")
|
|
_expect(CONTENT_PATHS.canonicalize("user://stickmen/basic.stk") == "user://stickmen/basic.stk", "user-selected paths pass through")
|
|
_expect(CONTENT_PATHS.canonicalize("/tmp/external/stickmen/basic.stk") == "/tmp/external/stickmen/basic.stk", "external absolute paths pass through")
|
|
var project_root: String = ProjectSettings.globalize_path("res://").trim_suffix("/")
|
|
var old_absolute: String = project_root.path_join("stickmen/basic.stk")
|
|
var new_absolute: String = project_root.path_join("content/stickmen/basic.stk")
|
|
_expect(CONTENT_PATHS.canonicalize(old_absolute) == new_absolute, "legacy absolute paths inside the project migrate in place")
|
|
var cli_result: Dictionary = CLI_LAUNCHER.parse(["--scene", "res://game_scenes/bend.scene"])
|
|
_expect(String(cli_result.get("scene_path", "")) == "res://content/stages/bend.scene", "CLI stage paths migrate before playback")
|
|
|
|
|
|
func _test_moved_stage_file_paths() -> void:
|
|
var result: Dictionary = STAGE_SCENE_IO.read_file("res://game_scenes/bend.scene")
|
|
_expect(bool(result.get("ok", false)), "stage IO opens a stage through its previous project path")
|
|
|
|
|
|
func _test_legacy_stage_round_trip() -> void:
|
|
_cleanup()
|
|
var legacy_data: Dictionary = {
|
|
# Keep this fixture at the pre-identity schema so the path test also
|
|
# exercises the existing legacy-stage migration into the current format.
|
|
"version": "1.7",
|
|
"scene_name": "Legacy Asset Paths",
|
|
"sky_id": "sky_neutral",
|
|
"background_kind": "sky",
|
|
"plain_color": "#F5EFE0",
|
|
"camera": {"position": {"x": 0.0, "y": -400.0}, "zoom": 0.5},
|
|
"objects": [
|
|
{
|
|
"file_id": "stickman_1",
|
|
"type": "stickman",
|
|
"position": {"x": 0.0, "y": 0.0},
|
|
"rotation": 0.0,
|
|
"stk_path": "res://stickmen/test.stk",
|
|
"action_queue": [],
|
|
},
|
|
{
|
|
"file_id": "prop_1",
|
|
"stage_object_id": "prop_1",
|
|
"type": "prop",
|
|
"position": {"x": 180.0, "y": 0.0},
|
|
"rotation": 0.0,
|
|
"asset_id": "res://props/briefcase.prop",
|
|
"scale": {"x": 1.0, "y": 1.0},
|
|
"material_preset": 1,
|
|
},
|
|
],
|
|
"event_rules": [],
|
|
"metadata": {},
|
|
}
|
|
_expect(bool(STAGE_SCENE_IO.write_file_safe(LEGACY_STAGE_PATH, legacy_data).get("ok", false)), "legacy stage fixture writes")
|
|
var stage: Node2D = STAGE_SCENE.instantiate() as Node2D
|
|
root.add_child(stage)
|
|
await process_frame
|
|
var loaded: bool = bool(stage.call("_load_scene_from_path", LEGACY_STAGE_PATH))
|
|
_expect(loaded, "legacy stage with moved stickman and prop assets loads")
|
|
var world: Node = stage.get("_world") as Node
|
|
_expect(world != null and world.get_child_count() == 2, "both moved assets are present after load")
|
|
var scene_data: Dictionary = stage.call("_collect_scene_data", false) as Dictionary
|
|
var objects: Array = scene_data.get("objects", [])
|
|
var saved_stickman_path: String = ""
|
|
var saved_prop_path: String = ""
|
|
for value: Variant in objects:
|
|
if not value is Dictionary:
|
|
continue
|
|
var entry: Dictionary = value as Dictionary
|
|
if String(entry.get("type", "")) == "stickman":
|
|
saved_stickman_path = String(entry.get("stk_path", ""))
|
|
elif String(entry.get("type", "")) == "prop":
|
|
saved_prop_path = String(entry.get("asset_id", ""))
|
|
_expect(saved_stickman_path == "res://content/stickmen/test.stk", "resaved stickman reference uses the canonical path")
|
|
_expect(saved_prop_path == "res://content/props/briefcase.prop", "resaved prop reference uses the canonical path")
|
|
_expect(bool(STAGE_SCENE_IO.write_file_safe(RESAVED_STAGE_PATH, scene_data).get("ok", false)), "canonical stage document resaves")
|
|
var reread: Dictionary = STAGE_SCENE_IO.read_file(RESAVED_STAGE_PATH)
|
|
_expect(bool(reread.get("ok", false)), "resaved stage document reads successfully")
|
|
var current_path: String = String(stage.get("_current_scene_path"))
|
|
_expect(current_path == LEGACY_STAGE_PATH, "unmanaged stage document path remains unchanged")
|
|
stage.queue_free()
|
|
await process_frame
|
|
|
|
|
|
func _cleanup() -> void:
|
|
for path: String in [LEGACY_STAGE_PATH, RESAVED_STAGE_PATH]:
|
|
if FileAccess.file_exists(path):
|
|
DirAccess.remove_absolute(ProjectSettings.globalize_path(path))
|