#[cfg(test)]
mod tests {
use crate::cards::{
card::Card,
deck::DeckConfig,
meld::{Meldable, Set},
suit_rank::{Rank, Suit},
};
use std::collections::HashSet;
use std::sync::Arc;
#[test]
fn invalid_set_less_than_3_cards() {
let cfg = Arc::new(DeckConfig::new());
let mut cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Spades,
deck_config: cfg.clone(),
},
];
let indices = vec![0, 1];
assert!(Set::new(&mut cards, &indices).is_err());
}
#[test]
fn invalid_set_different_ranks() {
let cfg = Arc::new(DeckConfig::new());
let mut cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Spades,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Two,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
];
let indices = vec![0, 1, 2];
assert!(Set::new(&mut cards, &indices).is_err());
}
#[test]
fn invalid_set_invalid_indices() {
let cfg = Arc::new(DeckConfig::new());
let mut cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone(),
},
];
let indices = vec![0, 1, 2, 3]; assert!(Set::new(&mut cards, &indices).is_err());
}
#[test]
fn valid_set() {
let cfg = Arc::new(DeckConfig::new());
let mut cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone(),
},
];
let backup_cards = cards.clone();
let indices = vec![0, 1, 2];
let set = Set::new(&mut cards, &indices);
assert!(cards.is_empty());
assert!(set.is_ok());
assert!(set.unwrap().cards() == &backup_cards);
}
#[test]
fn valid_set_wrong_order_indices() {
let cfg = Arc::new(DeckConfig::new());
let mut cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Spades,
deck_config: cfg.clone(),
},
];
let backup_cards = cards.clone();
let backup_cards_set = backup_cards.iter().collect();
let indices = vec![2, 0, 3, 1]; let set = Set::new(&mut cards, &indices);
assert!(cards.is_empty());
assert!(set.is_ok());
assert!(set.unwrap().cards().iter().collect::<HashSet<_>>() == backup_cards_set);
}
#[test]
fn valid_set_wildcard() {
let mut cfg = DeckConfig::new();
cfg.wildcard_rank = Some(Rank::Five);
let cfg = Arc::new(cfg);
let mut cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Five,
suit: Suit::Hearts,
deck_config: cfg.clone(),
}, ];
let backup_cards = cards.clone();
let indices = vec![0, 1, 2];
let set = Set::new(&mut cards, &indices);
assert!(set.is_ok());
assert!(cards.is_empty());
assert!(set.unwrap().cards() == &backup_cards);
}
#[test]
fn invalid_layoff_set() {
let cfg = Arc::new(DeckConfig::new());
let cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone(),
},
];
let indices = vec![0, 1, 2];
let mut set = Set::new(&mut cards.clone(), &indices).unwrap();
let mut layoff_card = vec![Card {
rank: Rank::Two,
suit: Suit::Clubs,
deck_config: cfg.clone(),
}];
assert!(set.layoff_card(&mut layoff_card, 0).is_err());
}
#[test]
fn valid_layoff_set() {
let cfg = Arc::new(DeckConfig::new());
let cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone(),
},
];
let indices = vec![0, 1, 2];
let mut set = Set::new(&mut cards.clone(), &indices).unwrap();
let mut layoff_card = vec![Card {
rank: Rank::Ace,
suit: Suit::Spades,
deck_config: cfg.clone(),
}];
assert!(set.layoff_card(&mut layoff_card, 0).is_ok());
assert!(layoff_card.is_empty());
assert!(
set.cards()
== &vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone()
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone()
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone()
},
Card {
rank: Rank::Ace,
suit: Suit::Spades,
deck_config: cfg.clone()
}
]
);
}
#[test]
fn valid_layoff_add_wildcard_set() {
let mut cfg = DeckConfig::new();
cfg.wildcard_rank = Some(Rank::Joker);
let cfg = Arc::new(cfg);
let cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone(),
},
];
let indices = vec![0, 1, 2];
let mut set = Set::new(&mut cards.clone(), &indices).unwrap();
let mut card = vec![Card {
rank: Rank::Joker,
suit: Suit::Joker,
deck_config: cfg.clone(),
}];
assert!(set.layoff_card(&mut card, 0).is_ok());
assert!(card.is_empty());
assert!(
set.cards()
== &vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone()
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone()
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone()
},
Card {
rank: Rank::Joker,
suit: Suit::Joker,
deck_config: cfg.clone()
}
]
);
}
#[test]
fn valid_layoff_replace_wildcard_set() {
let mut cfg = DeckConfig::new();
cfg.wildcard_rank = Some(Rank::Joker);
let cfg = Arc::new(cfg);
let cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Joker,
suit: Suit::Joker,
deck_config: cfg.clone(),
}, ];
let indices = vec![0, 1, 2, 3];
let mut set = Set::new(&mut cards.clone(), &indices).unwrap();
let mut card = vec![Card {
rank: Rank::Ace,
suit: Suit::Spades,
deck_config: cfg.clone(),
}];
assert!(set.layoff_card(&mut card, 0).is_ok());
assert!(
card == vec![Card {
rank: Rank::Joker,
suit: Suit::Joker,
deck_config: cfg.clone()
}]
);
assert!(
set.cards()
== &vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone()
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone()
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone()
},
Card {
rank: Rank::Ace,
suit: Suit::Spades,
deck_config: cfg.clone()
}
]
);
}
#[test]
fn valid_layoff_same_cards_set() {
let mut cfg = DeckConfig::new();
cfg.wildcard_rank = Some(Rank::Joker);
let cfg = Arc::new(cfg);
let cards = vec![
Card {
rank: Rank::Ace,
suit: Suit::Clubs,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Diamonds,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Hearts,
deck_config: cfg.clone(),
},
Card {
rank: Rank::Ace,
suit: Suit::Spades,
deck_config: cfg.clone(),
},
];
let mut layoff_cards = cards.clone();
let indices = vec![0, 1, 2, 3];
let mut set = Set::new(&mut cards.clone(), &indices).unwrap();
let mut set_cards = cards.clone();
set_cards.append(&mut cards.clone());
assert!(set.layoff_card(&mut layoff_cards, 0).is_ok()); assert!(set.layoff_card(&mut layoff_cards, 0).is_ok());
assert!(set.layoff_card(&mut layoff_cards, 0).is_ok());
assert!(set.layoff_card(&mut layoff_cards, 0).is_ok());
assert!(layoff_cards.is_empty());
assert!(set.cards() == &set_cards);
}
}