Add tests

This commit is contained in:
Stone_Red
2025-12-22 16:46:08 +01:00
parent fc5e2afaac
commit 488c274dcd
3 changed files with 413 additions and 1 deletions
+274
View File
@@ -0,0 +1,274 @@
package main
import (
"reflect"
"testing"
)
func TestNewHand(t *testing.T) {
tests := []struct {
input string
expected *Hand
expectedErr bool
}{
{
input: "H2 S3 C4 D5 H6",
expected: &Hand{Cards: []Card{
{Suit: "H", Value: 2},
{Suit: "S", Value: 3},
{Suit: "C", Value: 4},
{Suit: "D", Value: 5},
{Suit: "H", Value: 6},
}},
expectedErr: false,
},
{
input: "CT CJ CQ CK CA",
expected: &Hand{Cards: []Card{
{Suit: "C", Value: 10},
{Suit: "C", Value: 11},
{Suit: "C", Value: 12},
{Suit: "C", Value: 13},
{Suit: "C", Value: 14},
}},
expectedErr: false,
},
{
input: "Invalid Input",
expected: nil,
expectedErr: true,
},
{
input: "H2 S3 C4 D5", // Not 5 cards
expected: nil,
expectedErr: true,
},
{
input: "H2 S3 C4 D5 Hx", // Invalid card value
expected: nil,
expectedErr: true,
},
}
for _, tt := range tests {
hand, err := NewHand(tt.input)
if (err != nil) != tt.expectedErr {
t.Errorf("NewHand(%q) error = %v, expectedErr %v", tt.input, err, tt.expectedErr)
continue
}
if !tt.expectedErr && !reflect.DeepEqual(hand, tt.expected) {
t.Errorf("NewHand(%q) got = %v, want %v", tt.input, hand, tt.expected)
}
}
}
func TestEvaluateHandValues(t *testing.T) {
tests := []struct {
name string
input string
expected HandCategory
}{
{"Royal Flush", "CT CJ CQ CK CA", RoyalFlush},
{"Straight Flush", "D8 D9 DT DJ DQ", StraightFlush},
{"Four of a Kind", "HT SA ST DT CT", FourOfAKind},
{"Full House", "H2 SQ C2 D2 CQ", FullHouse},
{"Flush", "HK HQ H2 H4 H5", Flush},
{"Straight", "H3 S7 H5 D6 C4", Straight},
{"Three of a Kind", "H2 SQ S2 D2 CK", ThreeOfAKind},
{"Two Pair", "H5 SQ C5 DT CT", TwoPair},
{"Pair", "H3 S8 H5 D8 CA", Pair},
{"High Card", "H3 S8 H5 D4 CA", HighCard},
{"Straight Wheel", "H4 S5 HA D3 C2", Straight},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
hand, err := NewHand(tt.input)
if err != nil {
t.Fatalf("Failed to create hand for %s: %v", tt.input, err)
}
result := hand.Evaluate()
if result.Category != tt.expected {
t.Errorf("Hand: %s, Expected %s, got %s", tt.input, handNames[tt.expected], handNames[result.Category])
}
})
}
}
func TestCompareHands(t *testing.T) {
tests := []struct {
name string
hand1 string
hand2 string
expected int // 1 if hand1 wins, 2 if hand2 wins, 0 for tie
}{
{"Royal Flush vs Straight Flush", "CT CJ CQ CK CA", "D8 D9 DT DJ DQ", 1},
{"Straight Flush vs Four of a Kind", "D8 D9 DT DJ DQ", "HT SA ST DT CT", 1},
{"Four of a Kind vs Full House", "HT SA ST DT CT", "H2 SQ C2 D2 CQ", 1},
{"Full House vs Flush", "H2 SQ C2 D2 CQ", "HK HQ H2 H4 H5", 1},
{"Flush vs Straight", "HK HQ H2 H4 H5", "H3 S7 H5 D6 C4", 1},
{"Straight vs Three of a Kind", "H3 S7 H5 D6 C4", "H2 SQ S2 D2 CK", 1},
{"Three of a Kind vs Two Pair", "H2 SQ S2 D2 CK", "H5 SQ C5 DT CT", 1},
{"Two Pair vs Pair", "H5 SQ C5 DT CT", "H3 S8 H5 D8 CA", 1},
{"Pair vs High Card", "H3 S8 H5 D8 CA", "H3 S8 H5 D4 C2", 1},
{"Tie - Same Royal Flush", "CT CJ CQ CK CA", "CT CJ CQ CK CA", 0},
{"Tie - Same Straight Flush", "D8 D9 DT DJ DQ", "D8 D9 DT DJ DQ", 0},
{"Tie - Higher Straight Flush", "S8 S9 ST SJ SQ", "D8 D9 DT DJ DQ", 0},
{"Tie - Four of a Kind (higher value)", "HA SA DA CA H2", "HK SK DK CK H2", 1},
{"Tie - Four of a Kind (same value, higher kicker)", "HA SA DA CA H3", "HA SA DA CA H2", 1},
{"Tie - Full House (higher trips)", "HA SA DA H2 C2", "HK SK DK H2 C2", 1},
{"Tie - Full House (same trips, higher pair)", "HA SA DA H3 C3", "HA SA DA H2 C2", 1},
{"Tie - Flush (higher card)", "HA H9 H8 H7 H5", "HA H9 H8 H7 H4", 1},
{"Tie - Straight (higher card)", "S9 ST SJ SQ SK", "S8 S9 ST SJ SQ", 1},
{"Tie - Three of a Kind (higher trips)", "HA SA DA H3 C4", "HK SK DK H3 C4", 1},
{"Tie - Three of a Kind (same trips, higher kicker)", "HA SA DA H5 C4", "HA SA DA H3 C2", 1},
{"Tie - Two Pair (higher top pair)", "HA SA H2 C2 DK", "HK SK H2 C2 DA", 1},
{"Tie - Two Pair (same top pair, higher second pair)", "HA SA H3 C3 DK", "HA SA H2 C2 DK", 1},
{"Tie - Two Pair (same pairs, higher kicker)", "HA SA H2 C2 DQ", "HA SA H2 C2 DJ", 1},
{"Tie - Pair (higher pair)", "HA SA H2 C3 D4", "HK SK H2 C3 D4", 1},
{"Tie - Pair (same pair, higher kicker)", "HA SA H5 C3 D4", "HA SA H4 C2 D5", 1},
{"Tie - High Card (higher card)", "HA SK CJ D9 H7", "HQ SK CJ D9 H7", 1},
{"Tie - High Card (all equal)", "HA SK CJ D9 H7", "HA SK CJ D9 H7", 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
hand1, err1 := NewHand(tt.hand1)
hand2, err2 := NewHand(tt.hand2)
if err1 != nil || err2 != nil {
t.Fatalf("Failed to create hands: %v, %v", err1, err2)
}
result := hand1.Compare(hand2)
if result != tt.expected {
t.Errorf("CompareHands(%s, %s) Expected %d, got %d", tt.hand1, tt.hand2, tt.expected, result)
}
})
}
}
func TestFindBestHand(t *testing.T) {
tests := []struct {
name string
sevenCards []Card
expected *Hand
expectedErr bool
}{
{
name: "Royal Flush from 7 cards",
sevenCards: []Card{
{Suit: "C", Value: 2}, {Suit: "C", Value: 10}, {Suit: "C", Value: 11}, {Suit: "C", Value: 12},
{Suit: "C", Value: 13}, {Suit: "C", Value: 14}, {Suit: "H", Value: 7},
},
expected: &Hand{Cards: []Card{{Suit: "C", Value: 14}, {Suit: "C", Value: 13}, {Suit: "C", Value: 12}, {Suit: "C", Value: 11}, {Suit: "C", Value: 10}}},
expectedErr: false,
},
{
name: "Straight Flush from 7 cards",
sevenCards: []Card{
{Suit: "D", Value: 8}, {Suit: "D", Value: 9}, {Suit: "D", Value: 10}, {Suit: "D", Value: 11},
{Suit: "D", Value: 12}, {Suit: "S", Value: 5}, {Suit: "C", Value: 2},
},
expected: &Hand{Cards: []Card{{Suit: "D", Value: 12}, {Suit: "D", Value: 11}, {Suit: "D", Value: 10}, {Suit: "D", Value: 9}, {Suit: "D", Value: 8}}},
expectedErr: false,
},
{
name: "Four of a Kind from 7 cards",
sevenCards: []Card{
{Suit: "H", Value: 10}, {Suit: "S", Value: 10}, {Suit: "D", Value: 10}, {Suit: "C", Value: 10},
{Suit: "H", Value: 2}, {Suit: "S", Value: 3}, {Suit: "D", Value: 4},
},
expected: &Hand{Cards: []Card{{Suit: "H", Value: 10}, {Suit: "S", Value: 10}, {Suit: "D", Value: 10}, {Suit: "C", Value: 10}, {Suit: "D", Value: 4}}},
expectedErr: false,
},
{
name: "Full House from 7 cards",
sevenCards: []Card{
{Suit: "H", Value: 2}, {Suit: "S", Value: 2}, {Suit: "D", Value: 2}, {Suit: "C", Value: 3},
{Suit: "H", Value: 3}, {Suit: "S", Value: 7}, {Suit: "D", Value: 8},
},
expected: &Hand{Cards: []Card{{Suit: "H", Value: 3}, {Suit: "C", Value: 3}, {Suit: "H", Value: 2}, {Suit: "S", Value: 2}, {Suit: "D", Value: 2}}},
expectedErr: false,
},
{
name: "Flush from 7 cards",
sevenCards: []Card{
{Suit: "H", Value: 14}, {Suit: "H", Value: 12}, {Suit: "H", Value: 10}, {Suit: "H", Value: 8},
{Suit: "H", Value: 6}, {Suit: "S", Value: 5}, {Suit: "D", Value: 4},
},
expected: &Hand{Cards: []Card{{Suit: "H", Value: 14}, {Suit: "H", Value: 12}, {Suit: "H", Value: 10}, {Suit: "H", Value: 8}, {Suit: "H", Value: 6}}},
expectedErr: false,
},
{
name: "Straight from 7 cards",
sevenCards: []Card{
{Suit: "H", Value: 5}, {Suit: "S", Value: 6}, {Suit: "C", Value: 7}, {Suit: "D", Value: 8},
{Suit: "H", Value: 9}, {Suit: "S", Value: 2}, {Suit: "C", Value: 3},
},
expected: &Hand{Cards: []Card{{Suit: "H", Value: 9}, {Suit: "D", Value: 8}, {Suit: "C", Value: 7}, {Suit: "S", Value: 6}, {Suit: "H", Value: 5}}},
expectedErr: false,
},
{
name: "Three of a Kind from 7 cards",
sevenCards: []Card{
{Suit: "H", Value: 2}, {Suit: "S", Value: 2}, {Suit: "D", Value: 2}, {Suit: "C", Value: 7},
{Suit: "H", Value: 8}, {Suit: "S", Value: 9}, {Suit: "D", Value: 10},
},
expected: &Hand{Cards: []Card{{Suit: "D", Value: 10}, {Suit: "S", Value: 9}, {Suit: "H", Value: 8}, {Suit: "H", Value: 2}, {Suit: "S", Value: 2}, {Suit: "D", Value: 2}}},
expectedErr: false, // expected cards will be sorted by value inside Evaluate()
},
{
name: "High Card from 7 cards",
sevenCards: []Card{
{Suit: "H", Value: 2}, {Suit: "S", Value: 4}, {Suit: "C", Value: 6}, {Suit: "D", Value: 8},
{Suit: "H", Value: 10}, {Suit: "S", Value: 3}, {Suit: "C", Value: 5},
},
expected: &Hand{Cards: []Card{{Suit: "C", Value: 6}, {Suit: "C", Value: 5}, {Suit: "S", Value: 4}, {Suit: "S", Value: 3}, {Suit: "H", Value: 2}}},
expectedErr: false,
},
{
name: "Invalid number of cards (less than 7)",
sevenCards: []Card{
{Suit: "H", Value: 2}, {Suit: "S", Value: 4}, {Suit: "C", Value: 6}, {Suit: "D", Value: 8},
{Suit: "H", Value: 10}, {Suit: "S", Value: 3},
},
expected: nil,
expectedErr: true,
},
{
name: "Invalid number of cards (more than 7)",
sevenCards: []Card{
{Suit: "H", Value: 2}, {Suit: "S", Value: 4}, {Suit: "C", Value: 6}, {Suit: "D", Value: 8},
{Suit: "H", Value: 10}, {Suit: "S", Value: 3}, {Suit: "C", Value: 5}, {Suit: "D", Value: 7},
},
expected: nil,
expectedErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
hand, err := FindBestHand(tt.sevenCards)
if (err != nil) != tt.expectedErr {
t.Errorf("FindBestHand() error = %v, expectedErr %v", err, tt.expectedErr)
return
}
if !tt.expectedErr {
// The order of cards in the expected hand might not exactly match due to sorting,
// so we compare the evaluated categories and tie-breakers.
if hand == nil {
t.Fatalf("FindBestHand() returned nil hand for valid input")
}
expectedHandResult := (&Hand{Cards: tt.expected.Cards}).Evaluate()
actualHandResult := hand.Evaluate()
if expectedHandResult.Category != actualHandResult.Category {
t.Errorf("FindBestHand() for %s: expected category %s, got %s", tt.name, handNames[expectedHandResult.Category], handNames[actualHandResult.Category])
}
if !reflect.DeepEqual(expectedHandResult.TieBreakers, actualHandResult.TieBreakers) {
t.Errorf("FindBestHand() for %s: expected tie-breakers %v, got %v", tt.name, expectedHandResult.TieBreakers, actualHandResult.TieBreakers)
}
}
})
}
}