extends SceneTree var failures: Array[String] = [] func _init() -> void: var window_script: Script = load("res://scenes/combat/combo_window.gd") var resolver_script: Script = load("res://scenes/combat/input_resolver.gd") if window_script == null: failures.append("Missing combo_window.gd") _finish() return if resolver_script == null: failures.append("Missing input_resolver.gd") _finish() return var window: RefCounted = window_script.new() window.record("A") window.record("Ø") window.record("SP") _expect_array(window.get_slots(), ["A", "Ø", "SP"], "miss placeholder should be visible in slots") _expect_string(window.get_pattern(), "ASP", "miss placeholder should be ignored by pattern") window.clear("test-reset") window.record("W") window.record("A") window.record("S") _expect_array(window.get_slots(), ["W", "A", "S"], "three recorded slots") window.record("SP") _expect_array(window.get_slots(), ["W", "A", "S", "SP"], "fourth input should be visible before clear") _expect_string(window.consume_pending_clear_reason(), "full", "fourth input should request full clear") window.clear("test-reset") window.record("W") var resolved: Dictionary = resolver_script.resolve(window) _expect_bool(resolved.is_empty(), true, "W alone should not resolve a skill") window.record("A") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_wa", "W+A skill") _expect_array(window.get_slots(), ["W", "A"], "W+A should be visible before skill clear") window.clear("test-reset") window.record("W") window.record("Ø") window.record("A") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_a", "miss should break W+A into trailing A only") window.clear("test-reset") window.record("W") resolved = resolver_script.resolve(window) _expect_bool(resolved.is_empty(), true, "W alone should not resolve before mirrored W+D") window.record("D") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_wd", "W+D should mirror W+A skill") _expect_string(str(resolved.get("animation", "")), "warrior_wa", "W+D should reuse W+A animation") _expect_string(str(resolved.get("displacement", "")), "right", "W+D should move right") _expect_array(window.get_slots(), ["W", "D"], "W+D should be visible before skill clear") window.clear("test-reset") window.record("A") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_a", "A skill") _expect_string(str(resolved.get("animation", "")), "warrior_a", "A should play row 10 animation") _expect_string(str(resolved.get("displacement", "")), "left", "A should move left") _expect_bool(bool(resolved.get("clear_window", true)), false, "A skill should not clear window") window.record("A") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_aa", "A+A skill") _expect_bool(bool(resolved.get("clear_window", true)), false, "A+A skill should not clear window") window.record("A") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_aaa", "A+A+A skill") _expect_bool(bool(resolved.get("clear_window", true)), false, "A+A+A skill should not clear window") _expect_array(window.get_slots(), ["A", "A", "A"], "A+A+A should be visible before skill clear") window.clear("test-reset") window.record("D") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_d", "D skill") _expect_string(str(resolved.get("animation", "")), "warrior_a", "D should reuse row 10 animation") _expect_string(str(resolved.get("displacement", "")), "right", "D should move right") _expect_bool(bool(resolved.get("clear_window", true)), false, "D skill should not clear window") window.record("D") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_dd", "D+D should mirror A+A skill") _expect_string(str(resolved.get("animation", "")), "warrior_aa", "D+D should reuse A+A animation") window.record("D") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_ddd", "D+D+D should mirror A+A+A skill") _expect_string(str(resolved.get("animation", "")), "warrior_aaa", "D+D+D should reuse A+A+A animation") _expect_array(window.get_slots(), ["D", "D", "D"], "D+D+D should be visible before skill clear") window.clear("test-reset") window.record("A") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_a_space", "A+Space skill") _expect_string(str(resolved.get("animation", "")), "warrior_a_space", "A+Space should play row 17 animation") _expect_string(str(resolved.get("displacement", "")), "left", "A+Space should move left") _expect_bool(bool(resolved.get("clear_window", false)), true, "A+Space should clear window") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_a_space_space", "A+Space+Space skill") _expect_string(str(resolved.get("animation", "")), "warrior_a_space_space", "A+Space+Space should play row 15 animation") _expect_bool(bool(resolved.get("clear_window", false)), true, "A+Space+Space should clear window") window.clear("test-reset") window.record("D") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_d_space", "D+Space skill") _expect_string(str(resolved.get("animation", "")), "warrior_a_space", "D+Space should reuse row 17 animation") _expect_string(str(resolved.get("displacement", "")), "right", "D+Space should move right") _expect_bool(bool(resolved.get("clear_window", false)), true, "D+Space should clear window") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_d_space_space", "D+Space+Space skill") _expect_string(str(resolved.get("animation", "")), "warrior_a_space_space", "D+Space+Space should reuse row 15 animation") _expect_bool(bool(resolved.get("clear_window", false)), true, "D+Space+Space should clear window") window.clear("test-reset") window.record("A") window.record("A") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_aa_space", "A+A+Space skill") _expect_bool(bool(resolved.get("clear_window", false)), true, "A+A+Space should clear window") window.clear("test-reset") window.record("A") window.record("D") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_ad_space", "A+D+Space skill") _expect_string(str(resolved.get("displacement", "")), "right", "A+D+Space should move toward the last direction") _expect_bool(bool(resolved.get("clear_window", false)), true, "A+D+Space should clear window") window.clear("test-reset") window.record("D") window.record("A") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_da_space", "D+A+Space skill") _expect_string(str(resolved.get("displacement", "")), "left", "D+A+Space should move toward the last direction") _expect_bool(bool(resolved.get("clear_window", false)), true, "D+A+Space should clear window") window.clear("test-reset") window.record("D") window.record("D") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_dd_space", "D+D+Space skill") _expect_bool(bool(resolved.get("clear_window", false)), true, "D+D+Space should clear window") window.clear("test-reset") window.record("S") resolved = resolver_script.resolve(window) _expect_bool(resolved.is_empty(), true, "S alone should not resolve a skill") window.record("Ø") window.record("SP") resolved = resolver_script.resolve(window) _expect_bool(resolved.is_empty(), true, "S miss Space should not resolve projectile skill") window.clear("test-reset") window.record("S") resolved = resolver_script.resolve(window) _expect_bool(resolved.is_empty(), true, "S alone should not resolve a skill") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_s_projectile_1", "S+Space skill") _expect_bool(bool(resolved.get("clear_window", true)), false, "S+Space skill should not clear window") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_s_projectile_2", "S+Space+Space skill") _expect_bool(bool(resolved.get("clear_window", true)), false, "S+Space+Space skill should not clear window") window.record("SP") resolved = resolver_script.resolve(window) _expect_string(str(resolved.get("id", "")), "skill_s_projectile_3", "S+Space+Space+Space skill") _expect_bool(bool(resolved.get("clear_window", true)), false, "S+Space+Space+Space skill should not clear window") _expect_array(window.get_slots(), ["S", "SP", "SP", "SP"], "S projectile chain should fill four slots before clear") _finish() func _expect_array(actual: Array, expected: Array, label: String) -> void: if actual != expected: failures.append("%s: expected %s, got %s" % [label, expected, actual]) func _expect_string(actual: String, expected: String, label: String) -> void: if actual != expected: failures.append("%s: expected %s, got %s" % [label, expected, actual]) func _expect_bool(actual: bool, expected: bool, label: String) -> void: if actual != expected: failures.append("%s: expected %s, got %s" % [label, expected, actual]) func _finish() -> void: if failures.is_empty(): print("PASS combo window") quit(0) else: for failure: String in failures: push_error(failure) quit(1)