// 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 = (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").resource_exists::("ActiveAttacks").resource_exists::("TerrainData").resource_exists::("DeterministicRng").resource_exists::("CoastalTiles").resource_exists::("PlayerEntityMap").resource_exists::("ClientPlayerId").resource_exists::("HumanPlayerCount").resource_exists::("LocalPlayerContext").resource_exists::("SpawnPhase").resource_exists::("SpawnTimeout").resource_exists::("SpawnManager").resource_exists::("LocalTurnServerHandle").resource_exists::("TurnReceiver").resource_exists::("TurnGenerator"); } #[test] fn test_initialize_creates_player_entities() { let world = create_initialized_world(100, 100); // Get entity map let entity_map = world.resource::(); // 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::(*human_entity).is_some(), "Human player missing PlayerName component"); assert!(world.get::(*human_entity).is_some(), "Human player missing PlayerColor component"); assert!(world.get::(*human_entity).is_some(), "Human player missing BorderTiles component"); assert!(world.get::(*human_entity).is_some(), "Human player missing Troops component"); assert!(world.get::(*human_entity).is_some(), "Human player missing TerritorySize component"); // Verify initial troops are correct let troops = world.get::(*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::(*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::(); assert!(spawn_phase.active, "SpawnPhase should be active after initialization"); let spawn_timeout = world.resource::(); 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").resource_exists::("ActiveAttacks"); borders_core::game::cleanup_game_resources(&mut world); world.assert().resource_missing::("TerritoryManager").resource_missing::("ActiveAttacks").resource_missing::("TerrainData").resource_missing::("DeterministicRng").resource_missing::("CoastalTiles").resource_missing::("LocalPlayerContext").resource_missing::("TurnReceiver").resource_missing::("SpawnManager").resource_missing::("SpawnTimeout").resource_missing::("TurnGenerator"); } #[test] fn test_cannot_start_game_twice() { let world = create_initialized_world(100, 100); world.assert().resource_exists::("TerritoryManager"); let entity_map = world.resource::(); let _initial_count = entity_map.0.len(); let has_territory_manager = world.contains_resource::(); 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::(); 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()); }