neon-sprawl/client/test/hotbar_dev_bootstrap_test.gd

79 lines
2.3 KiB
GDScript

extends GdUnitTestSuite
## NEO-85: dev hotbar bootstrap binds prototype_pulse to slot 0 when empty.
const HotbarState := preload("res://scripts/hotbar_state.gd")
const DEV_BOOTSTRAP_CAST_ABILITY_ID := "prototype_pulse"
class SpyHotbarClient:
extends Node
var bind_calls: Array = []
func request_bind_slot(slot_index: int, ability_id: String) -> void:
bind_calls.append([slot_index, ability_id])
class BootstrapHarness:
extends Node
var bootstrap_attempted: bool = false
var _hotbar_state: Node
var _hotbar_client: SpyHotbarClient
func setup(parent: Node, slot0_ability: Variant) -> void:
_hotbar_state = HotbarState.new()
_hotbar_client = SpyHotbarClient.new()
parent.add_child(_hotbar_state)
parent.add_child(_hotbar_client)
var rows: Array = []
for i in range(8):
var row: Dictionary = {"slotIndex": i}
if i == 0 and slot0_ability is String:
row["abilityId"] = slot0_ability
rows.append(row)
_hotbar_state.call("apply_slots", rows)
func maybe_dev_bind_pulse_slot0() -> void:
if bootstrap_attempted:
return
if not is_instance_valid(_hotbar_state) or not is_instance_valid(_hotbar_client):
return
var slots: Array = _hotbar_state.call("slots_snapshot") as Array
if slots.is_empty():
return
var slot0: Variant = slots[0]
if slot0 is String and not (slot0 as String).strip_edges().is_empty():
return
bootstrap_attempted = true
_hotbar_client.request_bind_slot(0, DEV_BOOTSTRAP_CAST_ABILITY_ID)
func test_empty_slot0_triggers_pulse_bind_once() -> void:
# Arrange
var harness := BootstrapHarness.new()
auto_free(harness)
add_child(harness)
harness.setup(self, null)
# Act
harness.maybe_dev_bind_pulse_slot0()
harness.maybe_dev_bind_pulse_slot0()
# Assert
assert_that(harness._hotbar_client.bind_calls.size()).is_equal(1)
assert_that(int(harness._hotbar_client.bind_calls[0][0])).is_equal(0)
assert_that(str(harness._hotbar_client.bind_calls[0][1])).is_equal(
DEV_BOOTSTRAP_CAST_ABILITY_ID
)
func test_slot0_already_bound_skips_bootstrap() -> void:
# Arrange
var harness := BootstrapHarness.new()
auto_free(harness)
add_child(harness)
harness.setup(self, "prototype_pulse")
# Act
harness.maybe_dev_bind_pulse_slot0()
# Assert
assert_that(harness._hotbar_client.bind_calls.size()).is_equal(0)
assert_that(harness.bootstrap_attempted).is_false()