Files
smart-rgb/crates/borders-core/tests/lifecycle_tests.rs
2025-10-25 15:20:26 -05:00

112 lines
6.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Game lifecycle tests: initialization, player spawning, cleanup
mod common;
use assert2::assert;
use std::sync::Arc;
use borders_core::prelude::*;
use common::{MapBuilder, WorldAssertExt};
// Helper to eliminate 15+ lines of boilerplate in each test
fn create_initialized_world(map_width: u16, map_height: u16) -> World {
let mut world = World::new();
let terrain_data = Arc::new(MapBuilder::new(map_width, map_height).all_conquerable().build());
let conquerable_tiles: Vec<bool> = (0..(map_width as usize * map_height as usize)).map(|_| true).collect();
let (_intent_tx, intent_rx) = flume::unbounded();
let params = GameInitParamsBuilder::for_testing(map_width, map_height, conquerable_tiles, NationId::ZERO, intent_rx, terrain_data).build();
borders_core::game::initialize_game_resources(&mut world.commands(), params);
world.flush();
world
}
#[test]
fn test_initialize_game_creates_all_resources() {
let world = create_initialized_world(100, 100);
world.assert().resource_exists::<TerritoryManager>("TerritoryManager").resource_exists::<ActiveAttacks>("ActiveAttacks").resource_exists::<TerrainData>("TerrainData").resource_exists::<DeterministicRng>("DeterministicRng").resource_exists::<CoastalTiles>("CoastalTiles").resource_exists::<PlayerEntityMap>("PlayerEntityMap").resource_exists::<ClientPlayerId>("ClientPlayerId").resource_exists::<HumanPlayerCount>("HumanPlayerCount").resource_exists::<LocalPlayerContext>("LocalPlayerContext").resource_exists::<SpawnPhase>("SpawnPhase").resource_exists::<SpawnTimeout>("SpawnTimeout").resource_exists::<SpawnManager>("SpawnManager").resource_exists::<server::LocalTurnServerHandle>("LocalTurnServerHandle").resource_exists::<server::TurnReceiver>("TurnReceiver").resource_exists::<server::TurnGenerator>("TurnGenerator");
}
#[test]
fn test_initialize_creates_player_entities() {
let world = create_initialized_world(100, 100);
// Get entity map
let entity_map = world.resource::<PlayerEntityMap>();
// Verify 1 human + 10 bots = total players (matches create_initialized_world params)
let expected_bot_count = 10; // From create_initialized_world params
assert!(entity_map.0.len() == 1 + expected_bot_count, "Should have exactly {} player entities (1 human + {} bots), but found {}", 1 + expected_bot_count, expected_bot_count, entity_map.0.len());
// Verify human player (ID 0) exists
let human_entity = entity_map.0.get(&NationId::ZERO).expect("Human player entity not found");
// Verify human has all required components
assert!(world.get::<PlayerName>(*human_entity).is_some(), "Human player missing PlayerName component");
assert!(world.get::<PlayerColor>(*human_entity).is_some(), "Human player missing PlayerColor component");
assert!(world.get::<BorderTiles>(*human_entity).is_some(), "Human player missing BorderTiles component");
assert!(world.get::<Troops>(*human_entity).is_some(), "Human player missing Troops component");
assert!(world.get::<TerritorySize>(*human_entity).is_some(), "Human player missing TerritorySize component");
// Verify initial troops are correct
let troops = world.get::<Troops>(*human_entity).unwrap();
assert!(troops.0 == player::INITIAL_TROOPS, "Human player should start with {} troops, but has {}", player::INITIAL_TROOPS, troops.0);
// Verify territory size starts at 0
let territory_size = world.get::<TerritorySize>(*human_entity).unwrap();
assert!(territory_size.0 == 0, "Human player should start with 0 territory, but has {}", territory_size.0);
}
#[test]
fn test_spawn_phase_activates() {
let world = create_initialized_world(100, 100);
// Verify spawn phase is active
let spawn_phase = world.resource::<SpawnPhase>();
assert!(spawn_phase.active, "SpawnPhase should be active after initialization");
let spawn_timeout = world.resource::<SpawnTimeout>();
assert!(spawn_timeout.duration_secs > 0.0, "SpawnTimeout should have a positive duration");
}
#[test]
fn test_cleanup_removes_all_resources() {
let mut world = create_initialized_world(100, 100);
world.assert().resource_exists::<TerritoryManager>("TerritoryManager").resource_exists::<ActiveAttacks>("ActiveAttacks");
borders_core::game::cleanup_game_resources(&mut world);
world.assert().resource_missing::<TerritoryManager>("TerritoryManager").resource_missing::<ActiveAttacks>("ActiveAttacks").resource_missing::<TerrainData>("TerrainData").resource_missing::<DeterministicRng>("DeterministicRng").resource_missing::<CoastalTiles>("CoastalTiles").resource_missing::<LocalPlayerContext>("LocalPlayerContext").resource_missing::<server::TurnReceiver>("TurnReceiver").resource_missing::<SpawnManager>("SpawnManager").resource_missing::<SpawnTimeout>("SpawnTimeout").resource_missing::<server::TurnGenerator>("TurnGenerator");
}
#[test]
fn test_cannot_start_game_twice() {
let world = create_initialized_world(100, 100);
world.assert().resource_exists::<TerritoryManager>("TerritoryManager");
let entity_map = world.resource::<PlayerEntityMap>();
let _initial_count = entity_map.0.len();
let has_territory_manager = world.contains_resource::<TerritoryManager>();
assert!(has_territory_manager, "This check prevents double-initialization in production code");
}
#[test]
fn test_territory_manager_dimensions() {
let map_width = 80u16;
let map_height = 60u16;
let world = create_initialized_world(map_width, map_height);
let territory_manager = world.resource::<TerritoryManager>();
assert!(territory_manager.width() == map_width, "TerritoryManager width should match map width: expected {}, got {}", map_width, territory_manager.width());
assert!(territory_manager.height() == map_height, "TerritoryManager height should match map height: expected {}, got {}", map_height, territory_manager.height());
assert!(territory_manager.len() == (map_width as usize) * (map_height as usize), "TerritoryManager should have width × height tiles: expected {}, got {}", (map_width as usize) * (map_height as usize), territory_manager.len());
}