test runner added
This commit is contained in:
416
tests/unit/test_turn_manager.gd
Normal file
416
tests/unit/test_turn_manager.gd
Normal file
@@ -0,0 +1,416 @@
|
||||
extends GutTest
|
||||
|
||||
## Unit tests for TurnManager.gd
|
||||
|
||||
var turn_manager: TurnManager
|
||||
|
||||
# Signal tracking
|
||||
var phase_changed_called: bool = false
|
||||
var last_phase: Enums.TurnPhase
|
||||
var turn_changed_called: bool = false
|
||||
var last_turn_player: int = -1
|
||||
var turn_started_called: bool = false
|
||||
var turn_ended_called: bool = false
|
||||
|
||||
|
||||
func before_each():
|
||||
turn_manager = TurnManager.new()
|
||||
phase_changed_called = false
|
||||
turn_changed_called = false
|
||||
turn_started_called = false
|
||||
turn_ended_called = false
|
||||
|
||||
turn_manager.phase_changed.connect(_on_phase_changed)
|
||||
turn_manager.turn_changed.connect(_on_turn_changed)
|
||||
turn_manager.turn_started.connect(_on_turn_started)
|
||||
turn_manager.turn_ended.connect(_on_turn_ended)
|
||||
|
||||
|
||||
func _on_phase_changed(phase: Enums.TurnPhase):
|
||||
phase_changed_called = true
|
||||
last_phase = phase
|
||||
|
||||
|
||||
func _on_turn_changed(player_index: int):
|
||||
turn_changed_called = true
|
||||
last_turn_player = player_index
|
||||
|
||||
|
||||
func _on_turn_started(_player_index: int, _turn_number: int):
|
||||
turn_started_called = true
|
||||
|
||||
|
||||
func _on_turn_ended(_player_index: int):
|
||||
turn_ended_called = true
|
||||
|
||||
|
||||
## Initialization Tests
|
||||
|
||||
func test_initial_state():
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.ACTIVE)
|
||||
assert_eq(turn_manager.current_player_index, 0)
|
||||
assert_eq(turn_manager.turn_number, 0)
|
||||
assert_eq(turn_manager.attack_step, Enums.AttackStep.PREPARATION)
|
||||
assert_null(turn_manager.current_attacker)
|
||||
assert_null(turn_manager.current_blocker)
|
||||
|
||||
|
||||
## Start Game Tests
|
||||
|
||||
func test_start_game_player_0():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
assert_eq(turn_manager.turn_number, 1)
|
||||
assert_eq(turn_manager.current_player_index, 0)
|
||||
assert_true(turn_manager.is_first_turn)
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.ACTIVE)
|
||||
assert_true(phase_changed_called)
|
||||
assert_true(turn_started_called)
|
||||
|
||||
|
||||
func test_start_game_player_1():
|
||||
turn_manager.start_game(1)
|
||||
|
||||
assert_eq(turn_manager.current_player_index, 1)
|
||||
assert_eq(turn_manager.turn_number, 1)
|
||||
|
||||
|
||||
## Phase Progression Tests
|
||||
|
||||
func test_phase_progression_sequence():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
# ACTIVE -> DRAW
|
||||
turn_manager.advance_phase()
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.DRAW)
|
||||
|
||||
# DRAW -> MAIN_1
|
||||
turn_manager.advance_phase()
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.MAIN_1)
|
||||
|
||||
# MAIN_1 -> ATTACK
|
||||
turn_manager.advance_phase()
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.ATTACK)
|
||||
|
||||
# ATTACK -> MAIN_2
|
||||
turn_manager.advance_phase()
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.MAIN_2)
|
||||
|
||||
# MAIN_2 -> END
|
||||
turn_manager.advance_phase()
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.END)
|
||||
|
||||
|
||||
func test_phase_progression_wraps_to_new_turn():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
# Progress through all phases
|
||||
for i in range(5): # ACTIVE -> DRAW -> MAIN_1 -> ATTACK -> MAIN_2
|
||||
turn_manager.advance_phase()
|
||||
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.END)
|
||||
|
||||
# END -> ACTIVE (new turn, player switches)
|
||||
turn_manager.advance_phase()
|
||||
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.ACTIVE)
|
||||
assert_eq(turn_manager.current_player_index, 1) # Player switched
|
||||
assert_eq(turn_manager.turn_number, 2)
|
||||
assert_false(turn_manager.is_first_turn)
|
||||
|
||||
|
||||
func test_phase_emits_signal():
|
||||
turn_manager.start_game(0)
|
||||
phase_changed_called = false
|
||||
|
||||
turn_manager.advance_phase()
|
||||
|
||||
assert_true(phase_changed_called)
|
||||
assert_eq(last_phase, Enums.TurnPhase.DRAW)
|
||||
|
||||
|
||||
func test_turn_changed_signal():
|
||||
turn_manager.start_game(0)
|
||||
turn_changed_called = false
|
||||
|
||||
# Progress through full turn
|
||||
for i in range(6):
|
||||
turn_manager.advance_phase()
|
||||
|
||||
assert_true(turn_changed_called)
|
||||
assert_eq(last_turn_player, 1)
|
||||
|
||||
|
||||
func test_turn_ended_signal():
|
||||
turn_manager.start_game(0)
|
||||
turn_ended_called = false
|
||||
|
||||
# Progress through full turn
|
||||
for i in range(6):
|
||||
turn_manager.advance_phase()
|
||||
|
||||
assert_true(turn_ended_called)
|
||||
|
||||
|
||||
## Phase Query Tests
|
||||
|
||||
func test_is_main_phase():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
assert_false(turn_manager.is_main_phase()) # ACTIVE
|
||||
|
||||
turn_manager.advance_phase() # DRAW
|
||||
assert_false(turn_manager.is_main_phase())
|
||||
|
||||
turn_manager.advance_phase() # MAIN_1
|
||||
assert_true(turn_manager.is_main_phase())
|
||||
|
||||
turn_manager.advance_phase() # ATTACK
|
||||
assert_false(turn_manager.is_main_phase())
|
||||
|
||||
turn_manager.advance_phase() # MAIN_2
|
||||
assert_true(turn_manager.is_main_phase())
|
||||
|
||||
turn_manager.advance_phase() # END
|
||||
assert_false(turn_manager.is_main_phase())
|
||||
|
||||
|
||||
func test_is_attack_phase():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
assert_false(turn_manager.is_attack_phase())
|
||||
|
||||
# Progress to attack phase
|
||||
turn_manager.advance_phase() # DRAW
|
||||
turn_manager.advance_phase() # MAIN_1
|
||||
turn_manager.advance_phase() # ATTACK
|
||||
|
||||
assert_true(turn_manager.is_attack_phase())
|
||||
|
||||
turn_manager.advance_phase() # MAIN_2
|
||||
assert_false(turn_manager.is_attack_phase())
|
||||
|
||||
|
||||
## Draw Count Tests
|
||||
|
||||
func test_first_turn_draws_one():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
assert_eq(turn_manager.get_draw_count(), 1)
|
||||
|
||||
|
||||
func test_subsequent_turns_draw_two():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
# Complete first turn
|
||||
for i in range(6):
|
||||
turn_manager.advance_phase()
|
||||
|
||||
assert_false(turn_manager.is_first_turn)
|
||||
assert_eq(turn_manager.get_draw_count(), 2)
|
||||
|
||||
|
||||
## Attack Phase State Machine Tests
|
||||
|
||||
func test_attack_phase_initial_state():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
assert_eq(turn_manager.attack_step, Enums.AttackStep.PREPARATION)
|
||||
assert_null(turn_manager.current_attacker)
|
||||
assert_null(turn_manager.current_blocker)
|
||||
|
||||
|
||||
func test_start_attack_declaration():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
var result = turn_manager.start_attack_declaration()
|
||||
|
||||
assert_true(result)
|
||||
assert_eq(turn_manager.attack_step, Enums.AttackStep.DECLARATION)
|
||||
|
||||
|
||||
func test_start_attack_declaration_invalid_state():
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration() # Now in DECLARATION
|
||||
|
||||
# Can't start again from DECLARATION
|
||||
var result = turn_manager.start_attack_declaration()
|
||||
|
||||
assert_false(result)
|
||||
|
||||
|
||||
func test_set_attacker():
|
||||
var attacker = CardInstance.new(TestCardData.create_forward(), 0)
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration()
|
||||
|
||||
var result = turn_manager.set_attacker(attacker)
|
||||
|
||||
assert_true(result)
|
||||
assert_eq(turn_manager.current_attacker, attacker)
|
||||
assert_eq(turn_manager.attack_step, Enums.AttackStep.BLOCK_DECLARATION)
|
||||
|
||||
|
||||
func test_set_attacker_null_fails():
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration()
|
||||
|
||||
var result = turn_manager.set_attacker(null)
|
||||
|
||||
assert_false(result)
|
||||
assert_eq(turn_manager.attack_step, Enums.AttackStep.DECLARATION)
|
||||
|
||||
|
||||
func test_set_attacker_wrong_state_fails():
|
||||
var attacker = CardInstance.new(TestCardData.create_forward(), 0)
|
||||
turn_manager.start_game(0)
|
||||
# Don't call start_attack_declaration, still in PREPARATION
|
||||
|
||||
var result = turn_manager.set_attacker(attacker)
|
||||
|
||||
assert_false(result)
|
||||
|
||||
|
||||
func test_set_blocker():
|
||||
var attacker = CardInstance.new(TestCardData.create_forward("att"), 0)
|
||||
var blocker = CardInstance.new(TestCardData.create_forward("blk"), 1)
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration()
|
||||
turn_manager.set_attacker(attacker)
|
||||
|
||||
var result = turn_manager.set_blocker(blocker)
|
||||
|
||||
assert_true(result)
|
||||
assert_eq(turn_manager.current_blocker, blocker)
|
||||
assert_eq(turn_manager.attack_step, Enums.AttackStep.DAMAGE_RESOLUTION)
|
||||
|
||||
|
||||
func test_set_blocker_null_valid():
|
||||
var attacker = CardInstance.new(TestCardData.create_forward(), 0)
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration()
|
||||
turn_manager.set_attacker(attacker)
|
||||
|
||||
var result = turn_manager.set_blocker(null) # No block
|
||||
|
||||
assert_true(result)
|
||||
assert_null(turn_manager.current_blocker)
|
||||
assert_eq(turn_manager.attack_step, Enums.AttackStep.DAMAGE_RESOLUTION)
|
||||
|
||||
|
||||
func test_set_blocker_wrong_state_fails():
|
||||
var blocker = CardInstance.new(TestCardData.create_forward(), 1)
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration()
|
||||
# Don't set attacker, still in DECLARATION
|
||||
|
||||
var result = turn_manager.set_blocker(blocker)
|
||||
|
||||
assert_false(result)
|
||||
|
||||
|
||||
func test_complete_attack():
|
||||
var attacker = CardInstance.new(TestCardData.create_forward(), 0)
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration()
|
||||
turn_manager.set_attacker(attacker)
|
||||
turn_manager.set_blocker(null)
|
||||
|
||||
var result = turn_manager.complete_attack()
|
||||
|
||||
assert_true(result)
|
||||
assert_null(turn_manager.current_attacker)
|
||||
assert_null(turn_manager.current_blocker)
|
||||
assert_eq(turn_manager.attack_step, Enums.AttackStep.DECLARATION) # Ready for next attack
|
||||
|
||||
|
||||
func test_complete_attack_wrong_state_fails():
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration()
|
||||
# Still in DECLARATION, not DAMAGE_RESOLUTION
|
||||
|
||||
var result = turn_manager.complete_attack()
|
||||
|
||||
assert_false(result)
|
||||
|
||||
|
||||
func test_end_attack_phase_from_preparation():
|
||||
turn_manager.start_game(0)
|
||||
# Advance to attack phase
|
||||
turn_manager.advance_phase() # DRAW
|
||||
turn_manager.advance_phase() # MAIN_1
|
||||
turn_manager.advance_phase() # ATTACK
|
||||
|
||||
var result = turn_manager.end_attack_phase()
|
||||
|
||||
assert_true(result)
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.MAIN_2)
|
||||
|
||||
|
||||
func test_end_attack_phase_from_declaration():
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.advance_phase() # DRAW
|
||||
turn_manager.advance_phase() # MAIN_1
|
||||
turn_manager.advance_phase() # ATTACK
|
||||
turn_manager.start_attack_declaration()
|
||||
|
||||
var result = turn_manager.end_attack_phase()
|
||||
|
||||
assert_true(result)
|
||||
assert_eq(turn_manager.current_phase, Enums.TurnPhase.MAIN_2)
|
||||
|
||||
|
||||
func test_end_attack_phase_invalid_state():
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration()
|
||||
turn_manager.set_attacker(CardInstance.new(TestCardData.create_forward(), 0))
|
||||
# Now in BLOCK_DECLARATION
|
||||
|
||||
var result = turn_manager.end_attack_phase()
|
||||
|
||||
assert_false(result)
|
||||
|
||||
|
||||
func test_attack_state_reset_on_new_turn():
|
||||
var attacker = CardInstance.new(TestCardData.create_forward(), 0)
|
||||
turn_manager.start_game(0)
|
||||
turn_manager.start_attack_declaration()
|
||||
turn_manager.set_attacker(attacker)
|
||||
|
||||
# Complete the turn
|
||||
for i in range(6):
|
||||
turn_manager.advance_phase()
|
||||
|
||||
# New turn should have reset attack state
|
||||
assert_eq(turn_manager.attack_step, Enums.AttackStep.PREPARATION)
|
||||
assert_null(turn_manager.current_attacker)
|
||||
assert_null(turn_manager.current_blocker)
|
||||
|
||||
|
||||
## Display String Tests
|
||||
|
||||
func test_get_phase_string():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
assert_eq(turn_manager.get_phase_string(), "Active Phase")
|
||||
|
||||
turn_manager.advance_phase()
|
||||
assert_eq(turn_manager.get_phase_string(), "Draw Phase")
|
||||
|
||||
turn_manager.advance_phase()
|
||||
assert_eq(turn_manager.get_phase_string(), "Main Phase 1")
|
||||
|
||||
|
||||
func test_get_attack_step_string():
|
||||
turn_manager.start_game(0)
|
||||
|
||||
assert_eq(turn_manager.get_attack_step_string(), "Preparation")
|
||||
|
||||
turn_manager.start_attack_declaration()
|
||||
assert_eq(turn_manager.get_attack_step_string(), "Declare Attacker")
|
||||
|
||||
turn_manager.set_attacker(CardInstance.new(TestCardData.create_forward(), 0))
|
||||
assert_eq(turn_manager.get_attack_step_string(), "Declare Blocker")
|
||||
|
||||
turn_manager.set_blocker(null)
|
||||
assert_eq(turn_manager.get_attack_step_string(), "Damage Resolution")
|
||||
Reference in New Issue
Block a user