#[cfg(test)]
mod tests {
use super::super::*;
#[test]
fn test_duplicate_indices_behavior() {
let cfg = basic_config();
let mut cards = create_set_cards(
Rank::Ace,
&[Suit::Clubs, Suit::Diamonds, Suit::Hearts],
cfg.clone(),
);
let indices = vec![0, 1, 1];
let result = Meld::new(&mut cards, &indices);
match result {
Ok(meld) => {
println!("Duplicate indices created meld: {meld:?}");
}
Err(e) => {
println!("Duplicate indices failed with: {e:?}");
}
}
}
#[test]
fn test_empty_hand_layoff() {
let cfg = basic_config();
let mut cards = create_set_cards(
Rank::King,
&[Suit::Clubs, Suit::Diamonds, Suit::Hearts],
cfg.clone(),
);
let indices = vec![0, 1, 2];
let mut set = Set::new(&mut cards, &indices).unwrap();
let mut empty_hand: Vec<Card> = vec![];
let result = set.layoff_card(&mut empty_hand, 0);
assert!(matches!(result, Err(MeldError::InvalidCardIndex)));
}
#[test]
fn test_single_card_hand_layoff() {
let cfg = basic_config();
let mut cards = create_set_cards(
Rank::Jack,
&[Suit::Clubs, Suit::Diamonds, Suit::Hearts],
cfg.clone(),
);
let indices = vec![0, 1, 2];
let mut set = Set::new(&mut cards, &indices).unwrap();
let mut single_card_hand = vec![create_card(Rank::Jack, Suit::Spades, cfg.clone())];
let result = set.layoff_card(&mut single_card_hand, 0);
assert!(result.is_ok());
assert!(single_card_hand.is_empty()); }
#[test]
fn test_large_indices_vector() {
let cfg = basic_config();
let mut cards: Vec<Card> = (0..10)
.map(|i| {
create_card(
Rank::Ace,
if i % 2 == 0 {
Suit::Clubs
} else {
Suit::Diamonds
},
cfg.clone(),
)
})
.collect();
let indices: Vec<usize> = (0..8).collect();
let result = Set::new(&mut cards, &indices);
match result {
Ok(set) => assert_eq!(set.cards().len(), 8),
Err(e) => println!("Large set creation failed: {e:?}"),
}
}
#[test]
fn test_out_of_order_run_indices() {
let cfg = basic_config();
let mut cards = vec![
create_card(Rank::Seven, Suit::Hearts, cfg.clone()),
create_card(Rank::Five, Suit::Hearts, cfg.clone()),
create_card(Rank::Six, Suit::Hearts, cfg.clone()),
create_card(Rank::Eight, Suit::Hearts, cfg.clone()),
];
let indices = vec![1, 2, 0, 3];
let result = Run::new(&mut cards, &indices);
assert!(result.is_ok());
if let Ok(run) = result {
assert_eq!(run.cards().len(), 4);
}
}
#[test]
fn test_ace_edge_cases_in_runs() {
let cfg = basic_config();
let mut low_ace_cards = vec![
create_card(Rank::Ace, Suit::Clubs, cfg.clone()),
create_card(Rank::Two, Suit::Clubs, cfg.clone()),
create_card(Rank::Three, Suit::Clubs, cfg.clone()),
];
let indices = vec![0, 1, 2];
let low_result = Run::new(&mut low_ace_cards, &indices);
let mut high_ace_cards = vec![
create_card(Rank::Queen, Suit::Spades, cfg.clone()),
create_card(Rank::King, Suit::Spades, cfg.clone()),
create_card(Rank::Ace, Suit::Spades, cfg.clone()),
];
let indices = vec![0, 1, 2];
let high_result = Run::new(&mut high_ace_cards, &indices);
println!("Ace-low run result: {low_result:?}");
println!("Ace-high run result: {high_result:?}");
let mut wraparound_cards = vec![
create_card(Rank::King, Suit::Diamonds, cfg.clone()),
create_card(Rank::Ace, Suit::Diamonds, cfg.clone()),
create_card(Rank::Two, Suit::Diamonds, cfg.clone()),
];
let indices = vec![0, 1, 2];
let wraparound_result = Run::new(&mut wraparound_cards, &indices);
assert!(wraparound_result.is_err());
}
#[test]
fn test_minimum_meld_sizes() {
let cfg = basic_config();
let mut set_cards = create_set_cards(
Rank::Four,
&[Suit::Clubs, Suit::Diamonds, Suit::Hearts],
cfg.clone(),
);
let indices = vec![0, 1, 2];
let result = Set::new(&mut set_cards, &indices);
assert!(result.is_ok());
let mut run_cards = vec![
create_card(Rank::Nine, Suit::Spades, cfg.clone()),
create_card(Rank::Ten, Suit::Spades, cfg.clone()),
create_card(Rank::Jack, Suit::Spades, cfg.clone()),
];
let indices = vec![0, 1, 2];
let result = Run::new(&mut run_cards, &indices);
assert!(result.is_ok());
}
#[test]
fn test_layoff_index_exactly_at_boundary() {
let cfg = basic_config();
let mut cards = create_set_cards(
Rank::Ten,
&[Suit::Clubs, Suit::Diamonds, Suit::Hearts],
cfg.clone(),
);
let indices = vec![0, 1, 2];
let mut set = Set::new(&mut cards, &indices).unwrap();
let mut layoff_hand = vec![create_card(Rank::Ten, Suit::Spades, cfg.clone())];
let result = set.layoff_card(&mut layoff_hand, 0);
assert!(result.is_ok());
let mut another_hand = vec![create_card(Rank::Ten, Suit::Hearts, cfg.clone())];
let result = set.layoff_card(&mut another_hand, 1);
assert!(matches!(result, Err(MeldError::InvalidCardIndex)));
}
#[test]
fn test_meld_with_identical_cards() {
let cfg = basic_config();
let mut cards = vec![
create_card(Rank::Five, Suit::Hearts, cfg.clone()),
create_card(Rank::Five, Suit::Hearts, cfg.clone()),
create_card(Rank::Five, Suit::Hearts, cfg.clone()),
];
let indices = vec![0, 1, 2];
let result = Set::new(&mut cards, &indices);
match result {
Ok(set) => {
assert_eq!(set.cards().len(), 3);
println!("Identical cards formed valid set");
}
Err(e) => println!("Identical cards failed: {e:?}"),
}
}
#[test]
fn test_mixed_deck_configs() {
let cfg1 = basic_config();
let cfg2 = Arc::new(DeckConfig::new());
let mut cards = vec![
create_card(Rank::Seven, Suit::Clubs, cfg1.clone()),
create_card(Rank::Seven, Suit::Diamonds, cfg2.clone()), create_card(Rank::Seven, Suit::Hearts, cfg1.clone()),
];
let indices = vec![0, 1, 2];
let result = Set::new(&mut cards, &indices);
match result {
Ok(_) => println!("Mixed configs allowed"),
Err(e) => println!("Mixed configs rejected: {e:?}"),
}
}
}