diff --git a/solitaire_engine/src/input_plugin.rs b/solitaire_engine/src/input_plugin.rs index b8c07ff..ec8006c 100644 --- a/solitaire_engine/src/input_plugin.rs +++ b/solitaire_engine/src/input_plugin.rs @@ -1829,7 +1829,7 @@ const _VEC3_REFERENCED: Option = None; mod tests { use super::*; use crate::layout::compute_layout; - use solitaire_core::{Foundation, Tableau}; + use solitaire_core::{Deck, Foundation, Rank, Suit, Tableau}; use solitaire_core::{DrawStockConfig, game_state::GameState}; fn clear_test_piles(game: &mut GameState) { @@ -1910,6 +1910,44 @@ mod tests { assert_eq!(result.2.len(), 1); } + #[test] + fn find_draggable_picks_waste_top_with_multiple_cards() { + // Reproduces the reported "drags the wrong waste card" bug: with several + // cards in the waste, clicking the visible top must pick the actual top + // (last index), not the buffer card underneath it. + let mut game = GameState::new(42, DrawStockConfig::DrawOne); + let layout = compute_layout(Vec2::new(1280.0, 800.0), 0.0, 0.0, true); + clear_test_piles(&mut game); + let waste = vec![Card::new(Deck::Deck1, Suit::Clubs, Rank::Two), + Card::new(Deck::Deck1, Suit::Hearts, Rank::Five), + Card::new(Deck::Deck1, Suit::Spades, Rank::Nine)]; + game.set_test_waste_cards(waste.clone()); + + let top_index = waste.len() - 1; // 2 = the visible top + let top_pos = card_position(&game, &layout, &KlondikePile::Stock, top_index); + let result = find_draggable_at(top_pos, &game, &layout).expect("waste top is draggable"); + assert_eq!(result.0, KlondikePile::Stock, "origin is the waste pile"); + assert_eq!(result.1, top_index, "picks the top index, not the buffer"); + assert_eq!(result.2, vec![waste[top_index].clone()], "drags the top card only"); + } + + #[test] + fn find_draggable_picks_lone_waste_card() { + // "can't play the first card in the stock" — a waste of one card must + // still be draggable. + let mut game = GameState::new(42, DrawStockConfig::DrawOne); + let layout = compute_layout(Vec2::new(1280.0, 800.0), 0.0, 0.0, true); + clear_test_piles(&mut game); + let card = Card::new(Deck::Deck1, Suit::Diamonds, Rank::Ace); + game.set_test_waste_cards(vec![card.clone()]); + + let pos = card_position(&game, &layout, &KlondikePile::Stock, 0); + let result = find_draggable_at(pos, &game, &layout).expect("lone waste card is draggable"); + assert_eq!(result.0, KlondikePile::Stock); + assert_eq!(result.1, 0); + assert_eq!(result.2, vec![card]); + } + #[test] fn find_draggable_skips_face_down_cards() { let game = GameState::new(42, DrawStockConfig::DrawOne);