extends SceneTree var failures: Array[String] = [] func _init() -> void: _run.call_deferred() func _run() -> void: var scene: PackedScene = load("res://scenes/ui/main_ui.tscn") if scene == null: push_error("Could not load main_ui.tscn") quit(1) return var ui := scene.instantiate() root.add_child(ui) await process_frame for node_path: String in [ "RhythmTrack", "RhythmTrack/JudgementLabel", "RhythmTrack/HudReadoutRow/ComboCountLabel", "RhythmTrack/HudReadoutRow/AttackBuffValueLabel", "RhythmTrack/BuffPipRow", "RhythmTrack/JudgementArt", "RhythmTrack/ChartMarkerContainer", "ComboWindow", "StatusBars/HealthBar", "StatusBars/EnergyBar", "StatusBars/ChargeBar", ]: if not ui.has_node(node_path): failures.append("Missing rhythm UI node: %s" % node_path) var bus := _event_bus() bus.emit_signal("judgement_made", &"perfect", 0.0, 12) bus.emit_signal("streak_changed", 20) bus.emit_signal("attack_buff_changed", 5, 7) await process_frame var label := ui.get_node("RhythmTrack/JudgementLabel") as Label if not label.text.contains("PERFECT"): failures.append("RhythmTrack should render EventBus judgement text") var judgement_art := ui.get_node_or_null("RhythmTrack/JudgementArt") as TextureRect var combo_label := ui.get_node_or_null("RhythmTrack/HudReadoutRow/ComboCountLabel") as Label var buff_label := ui.get_node_or_null("RhythmTrack/HudReadoutRow/AttackBuffValueLabel") as Label var buff_row := ui.get_node_or_null("RhythmTrack/BuffPipRow") if judgement_art != null: _expect_bool(judgement_art.visible, true, "RhythmTrack should show judgement art after a judgement") _expect_string(_texture_file(judgement_art.texture), "perfect.png", "Perfect judgement should use the r/perfect art") if combo_label != null: _expect_string(combo_label.text, "combo 20", "RhythmTrack should render combo count under the track") if buff_label != null: _expect_string(buff_label.text, "ATK x 500%", "RhythmTrack should render buff stacks as ATK multiplier text") if buff_row != null: _expect_buff_pips(buff_row, 5) bus.emit_signal("judgement_made", &"miss", 0.0, 13) await process_frame if judgement_art != null: _expect_string(_texture_file(judgement_art.texture), "miss.png", "Miss judgement should use the r/miss art") var player_scene: PackedScene = load("res://scenes/characters/player.tscn") if player_scene == null: failures.append("Player scene should load for EventBus skill facts") else: var player := player_scene.instantiate() root.add_child(player) await process_frame player.call("submit_combo_input", "A", "perfect") await process_frame var skill_label := ui.get_node("ComboSkillLabel") as Label _expect_bool(skill_label.visible, false, "MainUI should keep ComboSkillLabel hidden in the reference HUD") _expect_string(skill_label.text, "", "Hidden ComboSkillLabel should not render skill_executed facts") player.free() ui.free() _finish() func _event_bus() -> Node: var bus := root.get_node_or_null("EventBus") if bus == null: bus = load("res://autoload/event_bus.gd").new() bus.name = "EventBus" root.add_child(bus) return bus func _expect_buff_pips(row: Node, lit_count: int) -> void: _expect_int(row.get_child_count(), 7, "BuffPipRow should always render seven buff slots") for index: int in range(row.get_child_count()): var pip := row.get_child(index) as TextureRect if pip == null: failures.append("BuffPipRow child %d should be a TextureRect" % index) continue var expected_file := "buff_on.png" if index < lit_count else "buff_off.png" _expect_string(_texture_file(pip.texture), expected_file, "Buff pip %d should use %s" % [index, expected_file]) func _texture_file(texture: Texture2D) -> String: if texture == null: return "" return texture.resource_path.get_file() func _expect_int(actual: int, expected: int, label: String) -> void: if actual != expected: failures.append("%s: expected %d, got %d" % [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 _expect_string(actual: String, expected: String, 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 rhythm ui") quit(0) else: for failure: String in failures: push_error(failure) quit(1)