aboutsummaryrefslogtreecommitdiff
path: root/tests/test_rank.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_rank.py')
-rw-r--r--tests/test_rank.py446
1 files changed, 446 insertions, 0 deletions
diff --git a/tests/test_rank.py b/tests/test_rank.py
new file mode 100644
index 0000000..f504a3e
--- /dev/null
+++ b/tests/test_rank.py
@@ -0,0 +1,446 @@
+from itertools import cycle
+
+import pytest
+
+from poker.constants import Suit, Value
+from poker.models import Card, Hand
+from poker.rank.hands import (
+ _is_flush,
+ _is_straight,
+ is_flush,
+ is_four_of_a_kind,
+ is_full_house,
+ is_pair,
+ is_royal_flush,
+ is_straight,
+ is_straight_flush,
+ is_three_of_a_kind,
+ is_two_pair,
+)
+from tests.conftest import Factory
+
+
+@pytest.mark.parametrize(
+ "suits,expected",
+ [
+ ([Suit.CLUBS, Suit.DIAMONDS, Suit.SPADES, Suit.HEARTS, Suit.CLUBS], False),
+ ([Suit.CLUBS, Suit.CLUBS, Suit.CLUBS, Suit.CLUBS, Suit.CLUBS], True),
+ ],
+ ids=[
+ "non-unique",
+ "unique",
+ ],
+)
+def test__is_flush(
+ card_factory: Factory[Card], suits: list[Suit], expected: bool
+) -> None:
+ result = _is_flush([card_factory(suit=suit) for suit in suits])
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "values,expected",
+ [
+ ([Value.TWO, Value.TWO, Value.THREE, Value.FOUR, Value.FIVE], False),
+ ([Value.THREE, Value.TWO, Value.ACE, Value.TEN, Value.KING], False),
+ ([Value.ACE, Value.TWO, Value.THREE, Value.FOUR, Value.FIVE], True),
+ ([Value.ACE, Value.KING, Value.TEN, Value.JACK, Value.QUEEN], True),
+ ([Value.THREE, Value.FIVE, Value.TWO, Value.FOUR, Value.SIX], True),
+ ],
+ ids=[
+ "non-unique",
+ "not-flush",
+ "low-ace",
+ "high-ace",
+ "middle-flush",
+ ],
+)
+def test__is_straight(
+ card_factory: Factory[Card], values: list[Value], expected: bool
+) -> None:
+ suits = cycle(Suit)
+ result = _is_straight(
+ [card_factory(suit=suit, value=value) for suit, value in zip(suits, values)]
+ )
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "values,different_suits,expected",
+ [
+ ([Value.TWO, Value.TEN, Value.THREE, Value.FOUR, Value.FIVE], False, False),
+ ([Value.ACE, Value.KING, Value.TEN, Value.JACK, Value.QUEEN], False, True),
+ ([Value.ACE, Value.KING, Value.TEN, Value.JACK, Value.QUEEN], True, False),
+ ],
+ ids=[
+ "not-flush",
+ "royal-flush",
+ "flush-not-royal",
+ ],
+)
+def test_is_royal_flush(
+ card_factory: Factory[Card],
+ values: list[Value],
+ different_suits: bool,
+ expected: bool,
+) -> None:
+ suits = cycle(Suit)
+
+ if different_suits:
+ result = is_royal_flush(
+ Hand(
+ cards=[
+ card_factory(suit=suit, value=value)
+ for suit, value in zip(suits, values)
+ ]
+ )
+ )
+ else:
+ result = is_royal_flush(
+ Hand(cards=[card_factory(value=value) for value in values])
+ )
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "values,different_suits,expected",
+ [
+ ([Value.TWO, Value.THREE, Value.FOUR, Value.FIVE, Value.SIX], True, False),
+ ([Value.TWO, Value.THREE, Value.FIVE, Value.SIX, Value.TEN], False, False),
+ ([Value.TWO, Value.THREE, Value.FOUR, Value.FIVE, Value.SIX], False, True),
+ ],
+ ids=[
+ "straight-only",
+ "flush-only",
+ "straight-flush",
+ ],
+)
+def test_is_straight_flush(
+ card_factory: Factory[Card],
+ values: list[Value],
+ different_suits: bool,
+ expected: bool,
+) -> None:
+ suits = cycle(Suit)
+
+ if different_suits:
+ result = is_straight_flush(
+ Hand(
+ cards=[
+ card_factory(suit=suit, value=value)
+ for suit, value in zip(suits, values)
+ ]
+ )
+ )
+ else:
+ result = is_straight_flush(
+ Hand(cards=[card_factory(value=value) for value in values])
+ )
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "cards,expected",
+ [
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.TWO),
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ ],
+ True,
+ ),
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TEN),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.TWO),
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ ],
+ False,
+ ),
+ ],
+ ids=[
+ "four-of-a-kind",
+ "not-four-of-a-kind",
+ ],
+)
+def test_is_four_of_a_kind(cards: list[Card], expected: bool) -> None:
+ result = is_four_of_a_kind(Hand(cards=cards))
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "cards,expected",
+ [
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.THREE),
+ ],
+ True,
+ ),
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.TWO),
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ ],
+ False,
+ ),
+ ],
+ ids=[
+ "full-house",
+ "not-full-house",
+ ],
+)
+def test_is_full_house(cards: list[Card], expected: bool) -> None:
+ result = is_full_house(Hand(cards=cards))
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "values,different_suits,expected",
+ [
+ ([Value.TWO, Value.THREE, Value.FOUR, Value.FIVE, Value.SIX], True, False),
+ ([Value.TWO, Value.THREE, Value.FIVE, Value.SIX, Value.TEN], False, True),
+ ([Value.TWO, Value.THREE, Value.FOUR, Value.FIVE, Value.SIX], False, False),
+ ],
+ ids=[
+ "straight-only",
+ "flush-only",
+ "straight-flush",
+ ],
+)
+def test_is_flush(
+ card_factory: Factory[Card],
+ values: list[Value],
+ different_suits: bool,
+ expected: bool,
+) -> None:
+ suits = cycle(Suit)
+
+ if different_suits:
+ result = is_flush(
+ Hand(
+ cards=[
+ card_factory(suit=suit, value=value)
+ for suit, value in zip(suits, values)
+ ]
+ )
+ )
+ else:
+ result = is_flush(Hand(cards=[card_factory(value=value) for value in values]))
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "values,different_suits,expected",
+ [
+ ([Value.TWO, Value.THREE, Value.FOUR, Value.FIVE, Value.SIX], True, True),
+ ([Value.TWO, Value.THREE, Value.FIVE, Value.SIX, Value.TEN], False, False),
+ ([Value.TWO, Value.THREE, Value.FOUR, Value.FIVE, Value.SIX], False, False),
+ ],
+ ids=[
+ "straight-only",
+ "flush-only",
+ "straight-flush",
+ ],
+)
+def test_is_straight(
+ card_factory: Factory[Card],
+ values: list[Value],
+ different_suits: bool,
+ expected: bool,
+) -> None:
+ suits = cycle(Suit)
+
+ if different_suits:
+ result = is_straight(
+ Hand(
+ cards=[
+ card_factory(suit=suit, value=value)
+ for suit, value in zip(suits, values)
+ ]
+ )
+ )
+ else:
+ result = is_straight(
+ Hand(cards=[card_factory(value=value) for value in values])
+ )
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "cards,expected",
+ [
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.THREE),
+ ],
+ False,
+ ),
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.ACE),
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ ],
+ True,
+ ),
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TEN),
+ Card(suit=Suit.SPADES, value=Value.ACE),
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ ],
+ False,
+ ),
+ ],
+ ids=["full-house", "three-of-a-kind", "not-three-of-a-kind"],
+)
+def test_is_three_of_a_kind(cards: list[Card], expected: bool) -> None:
+ result = is_three_of_a_kind(Hand(cards=cards))
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "cards,expected",
+ [
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.THREE),
+ Card(suit=Suit.DIAMONDS, value=Value.THREE),
+ ],
+ False,
+ ),
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.ACE),
+ Card(suit=Suit.SPADES, value=Value.ACE),
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ ],
+ True,
+ ),
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.ACE),
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ ],
+ False,
+ ),
+ ],
+ ids=["full-house", "two-pair", "three-of-a-kind"],
+)
+def test_is_two_pair(cards: list[Card], expected: bool) -> None:
+ result = is_two_pair(Hand(cards=cards))
+
+ if expected:
+ assert result
+ else:
+ assert not result
+
+
+@pytest.mark.parametrize(
+ "cards,expected",
+ [
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.TWO),
+ Card(suit=Suit.SPADES, value=Value.THREE),
+ Card(suit=Suit.DIAMONDS, value=Value.THREE),
+ ],
+ False,
+ ),
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.ACE),
+ Card(suit=Suit.SPADES, value=Value.ACE),
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ ],
+ False,
+ ),
+ (
+ [
+ Card(suit=Suit.CLUBS, value=Value.TWO),
+ Card(suit=Suit.DIAMONDS, value=Value.TWO),
+ Card(suit=Suit.HEARTS, value=Value.KING),
+ Card(suit=Suit.SPADES, value=Value.ACE),
+ Card(suit=Suit.CLUBS, value=Value.THREE),
+ ],
+ True,
+ ),
+ ],
+ ids=["full-house", "two-pair", "pair"],
+)
+def test_is_pair(cards: list[Card], expected: bool) -> None:
+ result = is_pair(Hand(cards=cards))
+
+ if expected:
+ assert result
+ else:
+ assert not result