This commit is contained in:
2025-09-23 09:59:55 +08:00
commit 674a7b16b7
16 changed files with 1413 additions and 0 deletions

144
run_tests.py Normal file
View File

@@ -0,0 +1,144 @@
#!/usr/bin/env python3
"""
Simple test runner without pytest dependency
"""
import sys
import traceback
from poker.card import Card, Rank, Suit
from poker.hand_evaluator import HandEvaluator
from poker.hand_ranking import HandType
def test_basic_card_functionality():
"""Test basic card functionality"""
print("Testing Card functionality...")
# Test card creation and string representation
card = Card(Rank.ACE, Suit.SPADES)
assert str(card) == "As", f"Expected 'As', got '{str(card)}'"
# Test card parsing
parsed_card = Card.from_string("Kh")
assert parsed_card.rank == Rank.KING
assert parsed_card.suit == Suit.HEARTS
# Test card comparison
ace = Card(Rank.ACE, Suit.SPADES)
king = Card(Rank.KING, Suit.HEARTS)
assert king < ace, "King should be less than Ace"
print("✓ Card tests passed")
def test_hand_parsing():
"""Test hand parsing from string"""
print("Testing hand parsing...")
cards = Card.parse_cards("AsKs AhAdAc6s7s")
assert len(cards) == 7, f"Expected 7 cards, got {len(cards)}"
assert str(cards[0]) == "As"
assert str(cards[6]) == "7s"
print("✓ Hand parsing tests passed")
def test_hand_evaluation_examples():
"""Test hand evaluation with known examples"""
print("Testing hand evaluation...")
test_cases = [
("AsKs AhAdAc6s7s", "Quad(A)", HandType.FOUR_OF_A_KIND),
("AhKhQhJhTh2c3c", "Royal Flush", HandType.ROYAL_FLUSH), # Royal flush has its own type
("2h3h4h5h6h7s8s", "Straight Flush(6 high)", HandType.STRAIGHT_FLUSH),
("AsAhAd KsKh6s7s", "Full House(A over K)", HandType.FULL_HOUSE),
("AhKh6h4h2h7s8s", "Flush(A high)", HandType.FLUSH),
("AsTsJhQdKh7s8s", "Straight(A high)", HandType.STRAIGHT),
("AsAhAd6s7h8s9s", "Three of a Kind(A)", HandType.THREE_OF_A_KIND),
("AsAh6d6s7h8c9s", "Two Pair(A and 6)", HandType.TWO_PAIR), # Changed to avoid straight
("AsAh6d7c8h9cJd", "Pair(A)", HandType.ONE_PAIR), # Changed to avoid straight
("As6h7d8s9hJdQc", "High Card(A)", HandType.HIGH_CARD), # Changed to avoid straight
]
for cards_str, expected_str, expected_type in test_cases:
ranking = HandEvaluator.evaluate_from_input(cards_str)
actual_str = str(ranking)
assert ranking.hand_type == expected_type, f"Wrong hand type for {cards_str}: expected {expected_type}, got {ranking.hand_type}"
assert actual_str == expected_str, f"Wrong string for {cards_str}: expected '{expected_str}', got '{actual_str}'"
print("✓ Hand evaluation tests passed")
def test_wheel_straight():
"""Test A-2-3-4-5 straight (wheel)"""
print("Testing wheel straight...")
cards_str = "As2h3d4c5h7s8s"
ranking = HandEvaluator.evaluate_from_input(cards_str)
assert ranking.hand_type == HandType.STRAIGHT
assert ranking.key_ranks[0] == Rank.FIVE, "In wheel straight, 5 should be the high card"
assert str(ranking) == "Straight(5 high)"
print("✓ Wheel straight test passed")
def test_error_handling():
"""Test error handling"""
print("Testing error handling...")
# Test invalid card string
try:
Card.from_string("Xx")
assert False, "Should have raised ValueError for invalid card"
except ValueError:
pass # Expected
# Test wrong number of cards
try:
HandEvaluator.evaluate_from_input("AsKh")
assert False, "Should have raised ValueError for wrong number of cards"
except ValueError:
pass # Expected
print("✓ Error handling tests passed")
def run_all_tests():
"""Run all tests"""
print("Running poker hand evaluation tests...\n")
test_functions = [
test_basic_card_functionality,
test_hand_parsing,
test_hand_evaluation_examples,
test_wheel_straight,
test_error_handling,
]
passed = 0
failed = 0
for test_func in test_functions:
try:
test_func()
passed += 1
except Exception as e:
print(f"{test_func.__name__} FAILED: {e}")
traceback.print_exc()
failed += 1
print(f"\nTest Results: {passed} passed, {failed} failed")
if failed > 0:
print("Some tests failed!")
return False
else:
print("All tests passed! 🎉")
return True
if __name__ == "__main__":
success = run_all_tests()
sys.exit(0 if success else 1)