use bevy::ecs::system::RunSystemOnce; use pomomon_garden::features::config::components::GameConfig; use pomomon_garden::features::grid::components::{Grid, TileState}; use pomomon_garden::features::inventory::components::{Inventory, ItemStack, ItemType}; use pomomon_garden::prelude::*; mod common; use common::setup_app; #[test] fn test_shovel_expansion() { let mut app = setup_app( 5, 5, &[(2, 2, TileState::Empty)], // (2,2) is Empty, making it a "claimed" neighbor vec![(ItemType::Shovel, 1)], // One shovel in inventory None, ); let target_pos = (2, 3); // Unclaimed tile next to (2,2), not on edge of 5x5 grid let _ = app.world_mut().run_system_once( move | grid: Res, mut tile_states: Query<&mut TileState>, mut inventory: ResMut, mut item_stack_query: Query<&mut ItemStack>, mut commands: Commands, _game_config: Res // Not directly used but required by signature | { let (x, y) = target_pos; let tile_entity = match grid.get_tile((x, y)) { Ok(entity) => entity, Err(_) => panic!("Clicked outside grid at {:?}", (x,y)), }; // Mimic the edge check from interact_click if x == 0 || x == grid.width - 1 || y == 0 || y == grid.height - 1 { panic!("Should not return early due to edge check for {:?} in a 5x5 grid", target_pos); } let neighbors = [ (x + 1, y), (x.saturating_sub(1), y), (x, y + 1), (x, y.saturating_sub(1)), ]; let mut has_claimed_neighbor = false; for (nx, ny) in neighbors.iter() { if *nx < grid.width && *ny < grid.height { if let Ok(neighbor_entity) = grid.get_tile((*nx, *ny)) { if let Ok(neighbor_state) = tile_states.get(neighbor_entity) { if !matches!(*neighbor_state, TileState::Unclaimed) { has_claimed_neighbor = true; break; } } } } } assert!(has_claimed_neighbor, "Target tile {:?} should have a claimed neighbor", target_pos); let mut tile_state = match tile_states.get_mut(tile_entity) { Ok(state) => state, Err(_) => panic!("Failed to get mutable tile state for {:?}", target_pos), }; assert!(matches!(*tile_state, TileState::Unclaimed), "Target tile {:?} should be Unclaimed initially, but was {:?}", target_pos, tile_state); // Execute the expansion if inventory.update_item_stack( &mut commands, &mut item_stack_query, ItemType::Shovel, -1, ) { *tile_state = TileState::Empty; } else { panic!("Shovel not consumed or not found in inventory"); } }, ); app.update(); // Apply commands // Assert Tile State let grid = app.world().resource::(); let tile_entity = grid.get_tile(target_pos).unwrap(); let tile_state = app.world().entity(tile_entity).get::().unwrap(); assert!( matches!(*tile_state, TileState::Empty), "Tile (1,2) should be Empty after expansion, but was {:?}", tile_state ); // Assert Inventory let inventory = app.world().resource::(); let shovel_stack = inventory.items.iter().find_map(|&entity| { let stack = app.world().entity(entity).get::()?; if stack.item_type == ItemType::Shovel { Some(stack) } else { None } }); assert!( shovel_stack.is_none() || shovel_stack.unwrap().amount == 0, "Shovel should have been consumed, found {:?}", shovel_stack ); }