From 9ddd24c2820db9b75ac609707b345b786d1cf539 Mon Sep 17 00:00:00 2001 From: demenik Date: Tue, 2 Dec 2025 17:05:43 +0100 Subject: [PATCH] test: Add growth mechanics tests --- tests/growth.rs | 161 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 tests/growth.rs diff --git a/tests/growth.rs b/tests/growth.rs new file mode 100644 index 0000000..85ed8fb --- /dev/null +++ b/tests/growth.rs @@ -0,0 +1,161 @@ +use bevy::ecs::system::RunSystemOnce; +use pomomon_garden::features::config::components::{BerrySeedConfig, GameConfig}; +use pomomon_garden::features::grid::components::{Grid, Tile, TileState}; +use pomomon_garden::features::inventory::components::ItemType; +use pomomon_garden::features::phase::components::{ + CurrentPhase, Phase, SessionTracker, TimerSettings, +}; +use pomomon_garden::features::phase::handle_continue; +use pomomon_garden::features::phase::messages::NextPhaseMessage; +use pomomon_garden::prelude::*; + +fn setup_growth_app( + grid_width: u32, + grid_height: u32, + initial_tile_states: &[(u32, u32, TileState)], +) -> App { + let mut app = App::new(); + app.add_plugins(MinimalPlugins); + app.add_plugins(AssetPlugin::default()); + + app.init_resource::(); + app.init_resource::(); + // Initialize phase as Finished(Focus) to trigger growth on continue + app.insert_resource(CurrentPhase(Phase::Finished { + completed_phase: Box::new(Phase::Focus { duration: 25.0 }), + })); + + // GameConfig with known seeds + app.insert_resource(GameConfig { + berry_seeds: vec![BerrySeedConfig { + name: "FastSeed".into(), + cost: 1, + grants: 1, + slice: "".into(), + growth_stages: 2, + }], + ..Default::default() + }); + + // Grid Setup + let mut grid_tiles = Vec::with_capacity(grid_width as usize); + for x in 0..grid_width { + let mut column = Vec::with_capacity(grid_height as usize); + for y in 0..grid_height { + let entity = app + .world_mut() + .spawn((Tile { x, y }, TileState::Unclaimed)) + .id(); + column.push(entity); + } + grid_tiles.push(column); + } + app.insert_resource(Grid { + width: grid_width, + height: grid_height, + tiles: grid_tiles, + }); + + for &(x, y, ref state) in initial_tile_states { + if let Ok(entity) = app.world().resource::().get_tile((x, y)) { + *app.world_mut().get_mut::(entity).unwrap() = state.clone(); + } + } + + app.add_message::(); + + app +} + +#[test] +fn test_crop_growth_logic() { + let seed_type = ItemType::BerrySeed { + name: "FastSeed".into(), + }; + + // Scenario: + // (0,0): Watered, Stage 0 -> Should grow to 1, become unwatered + // (1,0): Unwatered, Stage 0 -> Should NOT grow, stay unwatered + // (2,0): Watered, Stage 2 (Max) -> Should NOT grow, become unwatered + + let initial_states = vec![ + ( + 0, + 0, + TileState::Occupied { + seed: seed_type.clone(), + watered: true, + growth_stage: 0, + }, + ), + ( + 1, + 0, + TileState::Occupied { + seed: seed_type.clone(), + watered: false, + growth_stage: 0, + }, + ), + ( + 2, + 0, + TileState::Occupied { + seed: seed_type.clone(), + watered: true, + growth_stage: 2, // Max + }, + ), + ]; + + let mut app = setup_growth_app(3, 1, &initial_states); + + app.world_mut().write_message(NextPhaseMessage); + let _ = app.world_mut().run_system_once(handle_continue); + let grid = app.world().resource::(); + + // Check (0,0) + let t1 = grid.get_tile((0, 0)).unwrap(); + let s1 = app.world().entity(t1).get::().unwrap(); + match s1 { + TileState::Occupied { + watered, + growth_stage, + .. + } => { + assert_eq!(*growth_stage, 1, "(0,0) should grow to stage 1"); + assert_eq!(*watered, false, "(0,0) should be unwatered"); + } + _ => panic!("Invalid state at (0,0)"), + } + + // Check (1,0) + let t2 = grid.get_tile((1, 0)).unwrap(); + let s2 = app.world().entity(t2).get::().unwrap(); + match s2 { + TileState::Occupied { + watered, + growth_stage, + .. + } => { + assert_eq!(*growth_stage, 0, "(1,0) should stay at stage 0"); + assert_eq!(*watered, false, "(1,0) should be unwatered"); + } + _ => panic!("Invalid state at (1,0)"), + } + + // Check (2,0) + let t3 = grid.get_tile((2, 0)).unwrap(); + let s3 = app.world().entity(t3).get::().unwrap(); + match s3 { + TileState::Occupied { + watered, + growth_stage, + .. + } => { + assert_eq!(*growth_stage, 2, "(2,0) should stay at stage 2 (max)"); + assert_eq!(*watered, false, "(2,0) should be unwatered"); + } + _ => panic!("Invalid state at (2,0)"), + } +}