use kings_eunuch::hand_building::{HandRank, Hand, Card}; // Helper function to create a Hand from card strings fn make_evaluated_hand(rank: HandRank, cards: &[&str]) -> Hand { let card_vec: Vec = cards .iter() .map(|card_str| Card::str_to_card(card_str).unwrap()) .collect(); Hand::new(rank, card_vec) } // ===== DIFFERENT HAND RANKS ===== #[test] fn test_straight_flush_beats_quads() { let sf = make_evaluated_hand(HandRank::StraightFlush, &["9h", "8h", "7h", "6h", "5h"]); let quads = make_evaluated_hand(HandRank::Quads, &["Ah", "Ad", "As", "Ac", "Kh"]); assert!(sf > quads, "Straight flush should beat quads"); assert!(quads < sf, "Quads should lose to straight flush"); } #[test] fn test_quads_beats_full_house() { let quads = make_evaluated_hand(HandRank::Quads, &["3h", "3d", "3s", "3c", "2h"]); let fh = make_evaluated_hand(HandRank::FullHouse, &["Ah", "Ad", "As", "Kc", "Kh"]); assert!(quads > fh, "Quads should beat full house"); } #[test] fn test_full_house_beats_flush() { let fh = make_evaluated_hand(HandRank::FullHouse, &["7h", "7d", "7s", "2c", "2h"]); let flush = make_evaluated_hand(HandRank::Flush, &["Ah", "Kh", "Qh", "Jh", "9h"]); assert!(fh > flush, "Full house should beat flush"); } #[test] fn test_flush_beats_straight() { let flush = make_evaluated_hand(HandRank::Flush, &["9h", "7h", "6h", "4h", "2h"]); let straight = make_evaluated_hand(HandRank::Straight, &["Ah", "Kd", "Qs", "Jc", "Th"]); assert!(flush > straight, "Flush should beat straight"); } #[test] fn test_straight_beats_trips() { let straight = make_evaluated_hand(HandRank::Straight, &["5h", "4d", "3s", "2c", "Ah"]); let trips = make_evaluated_hand(HandRank::Trips, &["Ah", "Ad", "As", "Kc", "Qh"]); assert!(straight > trips, "Straight should beat trips"); } #[test] fn test_trips_beats_two_pair() { let trips = make_evaluated_hand(HandRank::Trips, &["3h", "3d", "3s", "2c", "2h"]); let two_pair = make_evaluated_hand(HandRank::TwoPair, &["Ah", "As", "Kd", "Kc", "Qh"]); assert!(trips > two_pair, "Trips should beat two pair"); } #[test] fn test_two_pair_beats_pair() { let two_pair = make_evaluated_hand(HandRank::TwoPair, &["3h", "3d", "2s", "2c", "Ah"]); let pair = make_evaluated_hand(HandRank::OnePair, &["Ah", "As", "Kd", "Qc", "Jh"]); assert!(two_pair > pair, "Two pair should beat one pair"); } #[test] fn test_pair_beats_high_card() { let pair = make_evaluated_hand(HandRank::OnePair, &["2h", "2d", "3s", "4c", "5h"]); let high_card = make_evaluated_hand(HandRank::HighCard, &["Ah", "Ks", "Qd", "Jc", "9h"]); assert!(pair > high_card, "One pair should beat high card"); } // ===== SAME HAND RANK COMPARISONS ===== #[test] fn test_straight_flush_high_card_wins() { let nine_high = make_evaluated_hand(HandRank::StraightFlush, &["9h", "8h", "7h", "6h", "5h"]); let eight_high = make_evaluated_hand(HandRank::StraightFlush, &["8d", "7d", "6d", "5d", "4d"]); assert!(nine_high > eight_high, "9-high straight flush should beat 8-high"); } #[test] fn test_quads_same_rank_kicker_matters() { let quads_king_kicker = make_evaluated_hand(HandRank::Quads, &["Ah", "Ad", "As", "Ac", "Kh"]); let quads_queen_kicker = make_evaluated_hand(HandRank::Quads, &["Ah", "As", "Ad", "Ac", "Qh"]); assert!(quads_king_kicker > quads_queen_kicker, "Aces with King kicker should beat Aces with Queen kicker"); } #[test] fn test_quads_different_rank() { let aces = make_evaluated_hand(HandRank::Quads, &["Ah", "Ad", "As", "Ac", "2h"]); let kings = make_evaluated_hand(HandRank::Quads, &["Kh", "Kd", "Ks", "Kc", "Ah"]); assert!(aces > kings, "Quad aces should beat quad kings"); } #[test] fn test_full_house_trips_matter_most() { let aces_over_twos = make_evaluated_hand(HandRank::FullHouse, &["Ah", "Ad", "As", "2c", "2h"]); let kings_over_aces = make_evaluated_hand(HandRank::FullHouse, &["Kh", "Kd", "Ks", "Ac", "Ah"]); assert!(aces_over_twos > kings_over_aces, "Aces full should beat Kings full"); } #[test] fn test_full_house_same_trips_pair_tiebreak() { let aces_over_kings = make_evaluated_hand(HandRank::FullHouse, &["Ah", "Ad", "As", "Kc", "Kh"]); let aces_over_queens = make_evaluated_hand(HandRank::FullHouse, &["Ah", "Ad", "As", "Qc", "Qh"]); assert!(aces_over_kings > aces_over_queens, "Aces over Kings should beat Aces over Queens"); } #[test] fn test_flush_high_card_comparison() { let ace_high = make_evaluated_hand(HandRank::Flush, &["Ah", "Kh", "Qh", "Jh", "9h"]); let ace_king_queen_jack_eight = make_evaluated_hand(HandRank::Flush, &["Ad", "Kd", "Qd", "Jd", "8d"]); assert!(ace_high > ace_king_queen_jack_eight, "A-K-Q-J-9 flush should beat A-K-Q-J-8 flush"); } #[test] fn test_straight_high_card_matters() { let broadway = make_evaluated_hand(HandRank::Straight, &["Ah", "Kd", "Qs", "Jc", "Th"]); let nine_high = make_evaluated_hand(HandRank::Straight, &["9h", "8d", "7s", "6c", "5h"]); assert!(broadway > nine_high, "Broadway should beat 9-high straight"); } #[test] fn test_wheel_is_lowest_straight() { let six_high = make_evaluated_hand(HandRank::Straight, &["6h", "5d", "4s", "3c", "2h"]); let wheel = make_evaluated_hand(HandRank::Straight, &["5h", "4d", "3s", "2c", "Ah"]); assert!(six_high > wheel, "6-high straight should beat wheel (5-high)"); } #[test] fn test_trips_higher_rank_wins() { let aces = make_evaluated_hand(HandRank::Trips, &["Ah", "Ad", "As", "Kc", "Qh"]); let kings = make_evaluated_hand(HandRank::Trips, &["Kh", "Kd", "Ks", "Ac", "Qh"]); assert!(aces > kings, "Trip aces should beat trip kings"); } #[test] fn test_trips_same_rank_kicker_tiebreak() { let trips_ace_king = make_evaluated_hand(HandRank::Trips, &["7h", "7d", "7s", "Ac", "Kh"]); let trips_ace_queen = make_evaluated_hand(HandRank::Trips, &["7h", "7d", "7s", "Ac", "Qh"]); assert!(trips_ace_king > trips_ace_queen, "Trips with A-K kickers should beat trips with A-Q kickers"); } #[test] fn test_two_pair_high_pair_matters_most() { let aces_and_twos = make_evaluated_hand(HandRank::TwoPair, &["Ah", "As", "2d", "2c", "3h"]); let kings_and_queens = make_evaluated_hand(HandRank::TwoPair, &["Kh", "Ks", "Qd", "Qc", "Ah"]); assert!(aces_and_twos > kings_and_queens, "Aces and twos should beat Kings and Queens"); } #[test] fn test_two_pair_same_high_pair_low_pair_matters() { let aces_and_kings = make_evaluated_hand(HandRank::TwoPair, &["Ah", "As", "Kd", "Kc", "2h"]); let aces_and_queens = make_evaluated_hand(HandRank::TwoPair, &["Ah", "As", "Qd", "Qc", "Kh"]); assert!(aces_and_kings > aces_and_queens, "Aces and Kings should beat Aces and Queens"); } #[test] fn test_two_pair_same_pairs_kicker_matters() { let kicker_king = make_evaluated_hand(HandRank::TwoPair, &["Ah", "As", "Kd", "Kc", "Qh"]); let kicker_jack = make_evaluated_hand(HandRank::TwoPair, &["Ah", "As", "Kd", "Kc", "Jh"]); assert!(kicker_king > kicker_jack, "Same two pair, King kicker should beat Jack kicker"); } #[test] fn test_pair_higher_pair_wins() { let aces = make_evaluated_hand(HandRank::OnePair, &["Ah", "As", "Kd", "Qc", "Jh"]); let kings = make_evaluated_hand(HandRank::OnePair, &["Kh", "Ks", "Ad", "Qc", "Jh"]); assert!(aces > kings, "Pair of Aces should beat pair of Kings"); } #[test] fn test_pair_same_pair_kickers_matter() { let pair_with_akq = make_evaluated_hand(HandRank::OnePair, &["7h", "7s", "Ad", "Kc", "Qh"]); let pair_with_akj = make_evaluated_hand(HandRank::OnePair, &["7h", "7s", "Ad", "Kc", "Jh"]); assert!(pair_with_akq > pair_with_akj, "Pair with A-K-Q kickers should beat pair with A-K-J kickers"); } #[test] fn test_high_card_comparison() { let ace_high = make_evaluated_hand(HandRank::HighCard, &["Ah", "Ks", "Qd", "Jc", "9h"]); let ace_king_queen_jack_eight = make_evaluated_hand(HandRank::HighCard, &["Ah", "Ks", "Qd", "Jc", "8h"]); assert!(ace_high > ace_king_queen_jack_eight, "A-K-Q-J-9 should beat A-K-Q-J-8"); } #[test] fn test_high_card_second_card_matters() { let ace_king_high = make_evaluated_hand(HandRank::HighCard, &["Ah", "Ks", "Qd", "Jc", "9h"]); let ace_queen_high = make_evaluated_hand(HandRank::HighCard, &["Ah", "Qs", "Jd", "Tc", "9h"]); assert!(ace_king_high > ace_queen_high, "A-K high should beat A-Q high"); } // ===== EQUALITY TESTS ===== #[test] fn test_identical_hands_are_equal() { let hand1 = make_evaluated_hand(HandRank::Flush, &["Ah", "Kh", "Qh", "Jh", "9h"]); let hand2 = make_evaluated_hand(HandRank::Flush, &["Ad", "Kd", "Qd", "Jd", "9d"]); assert_eq!(hand1.cmp(&hand2), std::cmp::Ordering::Equal, "Same rank and cards should be equal"); }