From 48b3f475b2095ec3c98536721e3b425d696367f6 Mon Sep 17 00:00:00 2001 From: demenik Date: Wed, 3 Dec 2025 22:33:53 +0100 Subject: [PATCH] test: Add crop harvesting tests --- tests/harvest.rs | 221 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 tests/harvest.rs diff --git a/tests/harvest.rs b/tests/harvest.rs new file mode 100644 index 0000000..675ad5a --- /dev/null +++ b/tests/harvest.rs @@ -0,0 +1,221 @@ +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::{Inventory, ItemStack, ItemType}; +use pomomon_garden::features::pom::actions::InteractionAction; +use pomomon_garden::prelude::*; + +fn setup_harvest_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()); + + // GameConfig + app.insert_resource(GameConfig { + berry_seeds: vec![BerrySeedConfig { + name: "TestSeed".into(), + cost: 1, + grants: 5, + slice: "".into(), + growth_stages: 2, + }], + ..Default::default() + }); + + // Inventory + app.init_resource::(); + + // Grid + 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 +} + +#[test] +fn test_harvest_fully_grown() { + let seed_type = ItemType::BerrySeed { + name: "TestSeed".into(), + }; + let initial_states = vec![( + 0, + 0, + TileState::Occupied { + seed: seed_type.clone(), + watered: false, + growth_stage: 2, // Max + withered: false, + dry_counter: 0, + }, + )]; + + let mut app = setup_harvest_app(1, 1, &initial_states); + + let _ = app.world_mut().run_system_once( + |mut commands: Commands, + grid: Res, + mut tile_query: Query<&mut TileState>, + mut inventory: ResMut, + mut item_stack_query: Query<&mut ItemStack>, + config: Res| { + InteractionAction::Harvest.execute( + (0, 0), + &grid, + &mut tile_query, + &mut inventory, + &mut item_stack_query, + &mut commands, + &config, + ); + }, + ); + + // Check Tile State -> Empty + // Wait for commands to apply + app.update(); + + let grid = app.world().resource::(); + let tile_entity = grid.get_tile((0, 0)).unwrap(); + let tile_state = app.world().entity(tile_entity).get::().unwrap(); + assert!(matches!(tile_state, TileState::Empty)); + + // Check Inventory -> 5 Berries + let inventory = app.world().resource::(); + assert_eq!(inventory.items.len(), 1); + let stack_entity = inventory.items[0]; + let stack = app.world().entity(stack_entity).get::().unwrap(); + assert_eq!(stack.item_type, ItemType::Berry); + assert_eq!(stack.amount, 5); +} + +#[test] +fn test_harvest_withered() { + let seed_type = ItemType::BerrySeed { + name: "TestSeed".into(), + }; + let initial_states = vec![( + 0, + 0, + TileState::Occupied { + seed: seed_type.clone(), + watered: false, + growth_stage: 1, + withered: true, // Withered + dry_counter: 0, + }, + )]; + + let mut app = setup_harvest_app(1, 1, &initial_states); + + let _ = app.world_mut().run_system_once( + |mut commands: Commands, + grid: Res, + mut tile_query: Query<&mut TileState>, + mut inventory: ResMut, + mut item_stack_query: Query<&mut ItemStack>, + config: Res| { + InteractionAction::Harvest.execute( + (0, 0), + &grid, + &mut tile_query, + &mut inventory, + &mut item_stack_query, + &mut commands, + &config, + ); + }, + ); + + app.update(); + + // Check Tile State -> Empty + let grid = app.world().resource::(); + let tile_entity = grid.get_tile((0, 0)).unwrap(); + let tile_state = app.world().entity(tile_entity).get::().unwrap(); + assert!(matches!(tile_state, TileState::Empty)); + + // Check Inventory -> Empty (no berries for withered) + let inventory = app.world().resource::(); + assert!(inventory.items.is_empty()); +} + +#[test] +fn test_cannot_harvest_growing() { + let seed_type = ItemType::BerrySeed { + name: "TestSeed".into(), + }; + let initial_states = vec![( + 0, + 0, + TileState::Occupied { + seed: seed_type.clone(), + watered: false, + growth_stage: 1, // Growing (Max is 2) + withered: false, + dry_counter: 0, + }, + )]; + + let mut app = setup_harvest_app(1, 1, &initial_states); + + let _ = app.world_mut().run_system_once( + |mut commands: Commands, + grid: Res, + mut tile_query: Query<&mut TileState>, + mut inventory: ResMut, + mut item_stack_query: Query<&mut ItemStack>, + config: Res| { + InteractionAction::Harvest.execute( + (0, 0), + &grid, + &mut tile_query, + &mut inventory, + &mut item_stack_query, + &mut commands, + &config, + ); + }, + ); + + app.update(); + + // Check Tile State -> Still Occupied + let grid = app.world().resource::(); + let tile_entity = grid.get_tile((0, 0)).unwrap(); + let tile_state = app.world().entity(tile_entity).get::().unwrap(); + match tile_state { + TileState::Occupied { growth_stage, .. } => { + assert_eq!(*growth_stage, 1); + } + _ => panic!("Should still be occupied"), + } + + // Check Inventory -> Empty + let inventory = app.world().resource::(); + assert!(inventory.items.is_empty()); +}