113 lines
4.1 KiB
GDScript
113 lines
4.1 KiB
GDScript
extends SceneTree
|
|
|
|
var failures: Array[String] = []
|
|
|
|
|
|
func _init() -> void:
|
|
_run.call_deferred()
|
|
|
|
|
|
func _run() -> void:
|
|
for path: String in [
|
|
"res://scenes/components/input_intent.gd",
|
|
"res://scenes/components/input_component.gd",
|
|
"res://scenes/components/combo_window.gd",
|
|
"res://scenes/components/state_machine.gd",
|
|
"res://scenes/components/energy_component.gd",
|
|
"res://scenes/components/burst_component.gd",
|
|
"res://scenes/components/charge_component.gd",
|
|
"res://scenes/components/action_controller.gd",
|
|
"res://scenes/combat/action_resolver.gd",
|
|
"res://resources/player_action_bindings.gd",
|
|
"res://resources/player_action_bindings.tres",
|
|
]:
|
|
_expect(load(path) != null, "%s should load" % path)
|
|
|
|
var resolver_script: Script = load("res://scenes/combat/action_resolver.gd")
|
|
if resolver_script != null:
|
|
if resolver_script.has_method("clear_cache"):
|
|
resolver_script.call("clear_cache")
|
|
var expected := {
|
|
"A": &"ground_attack_left_1",
|
|
"AA": &"ground_attack_left_2",
|
|
"D": &"ground_attack_right_1",
|
|
"DD": &"ground_attack_right_2",
|
|
"W": &"launcher_up",
|
|
"S": &"block_start",
|
|
"SS": &"block_start",
|
|
}
|
|
for pattern: String in expected:
|
|
var action: Resource = resolver_script.call("resolve_pattern", pattern)
|
|
_expect(action != null, "ActionResolver should resolve %s" % pattern)
|
|
if action != null:
|
|
_expect(StringName(str(action.get("id"))) == expected[pattern], "%s should resolve to %s" % [pattern, expected[pattern]])
|
|
_check_s_basic_fallback_keeps_exact_combos(resolver_script)
|
|
|
|
var gd_files := _all_gd_files(["res://scenes/components", "res://scenes/combat", "res://resources"])
|
|
for path: String in gd_files:
|
|
var text := _read_text(path)
|
|
_expect(not text.contains("legacy_skill_"), "%s should not hardcode old skill ids" % path)
|
|
_expect(not text.contains("legacy_time_phase"), "%s should not keep legacy time phase placeholders" % path)
|
|
_expect(not text.contains("legacy_time_anchor"), "%s should not keep legacy time anchor placeholders" % path)
|
|
_finish()
|
|
|
|
|
|
func _check_s_basic_fallback_keeps_exact_combos(resolver_script: Script) -> void:
|
|
resolver_script.call("reload", "res://tests/fixtures/actions")
|
|
var s_action: Resource = resolver_script.call("resolve_pattern", "S")
|
|
var combo_action: Resource = resolver_script.call("resolve_pattern", "SD")
|
|
var fallback_action: Resource = resolver_script.call("resolve_pattern", "AS")
|
|
_expect(s_action != null, "S fixture action should resolve")
|
|
if s_action != null:
|
|
_expect(StringName(str(s_action.get("id"))) == &"test_block_start", "S alone should resolve to the immediate block action")
|
|
_expect(combo_action != null, "S follow-up combo fixture should resolve")
|
|
if combo_action != null:
|
|
_expect(StringName(str(combo_action.get("id"))) == &"test_s_followup_combo", "S follow-up combo should beat trailing S fallback")
|
|
_expect(fallback_action != null, "Unmatched pattern ending in S should still fall back to immediate block")
|
|
if fallback_action != null:
|
|
_expect(StringName(str(fallback_action.get("id"))) == &"test_block_start", "Only unmatched S suffixes should use block fallback")
|
|
resolver_script.call("clear_cache")
|
|
|
|
|
|
func _all_gd_files(dirs: Array[String]) -> Array[String]:
|
|
var result: Array[String] = []
|
|
for dir_path: String in dirs:
|
|
_collect_gd_files(dir_path, result)
|
|
return result
|
|
|
|
|
|
func _collect_gd_files(dir_path: String, result: Array[String]) -> void:
|
|
var dir := DirAccess.open(dir_path)
|
|
if dir == null:
|
|
return
|
|
for subdir: String in dir.get_directories():
|
|
_collect_gd_files("%s/%s" % [dir_path, subdir], result)
|
|
for file_name: String in dir.get_files():
|
|
if file_name.ends_with(".gd"):
|
|
result.append("%s/%s" % [dir_path, file_name])
|
|
|
|
|
|
func _read_text(path: String) -> String:
|
|
var file := FileAccess.open(path, FileAccess.READ)
|
|
if file == null:
|
|
failures.append("Could not read %s" % path)
|
|
return ""
|
|
var text := file.get_as_text()
|
|
file.close()
|
|
return text
|
|
|
|
|
|
func _expect(condition: bool, label: String) -> void:
|
|
if not condition:
|
|
failures.append(label)
|
|
|
|
|
|
func _finish() -> void:
|
|
if failures.is_empty():
|
|
print("PASS rhythm action architecture")
|
|
quit(0)
|
|
else:
|
|
for failure: String in failures:
|
|
push_error(failure)
|
|
quit(1)
|