mirror of
https://github.com/Xevion/smart-rgb.git
synced 2025-12-07 05:16:34 -06:00
112 lines
6.0 KiB
Rust
112 lines
6.0 KiB
Rust
// 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());
|
||
}
|