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_withering_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::(); app.insert_resource(CurrentPhase(Phase::Finished { completed_phase: Box::new(Phase::Focus { duration: 25.0 }), })); app.insert_resource(GameConfig { berry_seeds: vec![BerrySeedConfig { name: "TestSeed".into(), cost: 1, grants: 1, slice: "".into(), growth_stages: 5, }], ..Default::default() }); 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_withering_progression() { let seed_type = ItemType::BerrySeed { name: "TestSeed".into(), }; // Start with a fresh plant let initial_states = vec![( 0, 0, TileState::Occupied { seed: seed_type.clone(), watered: false, growth_stage: 0, withered: false, dry_counter: 0, }, )]; let mut app = setup_withering_app(1, 1, &initial_states); // --- Phase 1: Not watered --- app.world_mut().write_message(NextPhaseMessage); let _ = app.world_mut().run_system_once(handle_continue); let t = app.world().resource::().get_tile((0, 0)).unwrap(); let s = app.world().entity(t).get::().unwrap(); match s { TileState::Occupied { withered, dry_counter, .. } => { assert_eq!( *dry_counter, 1, "Dry counter should be 1 after 1st dry phase" ); assert_eq!(*withered, false, "Should not be withered yet"); } _ => panic!("Invalid state"), } // --- Phase 2: Not watered -> Wither --- // Reset phase to trigger update again app.insert_resource(CurrentPhase(Phase::Finished { completed_phase: Box::new(Phase::Focus { duration: 25.0 }), })); app.world_mut().write_message(NextPhaseMessage); let _ = app.world_mut().run_system_once(handle_continue); let s = app.world().entity(t).get::().unwrap(); match s { TileState::Occupied { withered, dry_counter, .. } => { assert_eq!(*dry_counter, 2, "Dry counter should be 2"); assert_eq!(*withered, true, "Should be withered now"); } _ => panic!("Invalid state"), } // --- Phase 3: Watered -> Withered persists --- // Manually water it (simulate user action) if let Some(mut s_mut) = app.world_mut().get_mut::(t) { match *s_mut { TileState::Occupied { ref mut watered, .. } => *watered = true, _ => (), } } // Run phase app.insert_resource(CurrentPhase(Phase::Finished { completed_phase: Box::new(Phase::Focus { duration: 25.0 }), })); app.world_mut().write_message(NextPhaseMessage); let _ = app.world_mut().run_system_once(handle_continue); let s = app.world().entity(t).get::().unwrap(); match s { TileState::Occupied { growth_stage, withered, dry_counter, .. } => { assert_eq!(*dry_counter, 0, "Watering should reset dry counter"); assert_eq!(*withered, true, "Should still be withered"); assert_eq!(*growth_stage, 0, "Should not grow if withered"); } _ => panic!("Invalid state"), } }