def test_expected(self):
        low_straight_hand = Hand(
            [
                Ace(Suit.Spades),
                Two(Suit.Clubs),
                Three(Suit.Hearts),
                Four(Suit.Spades),
                Five(Suit.Diamonds)
            ]
        )

        self.assertTrue(StraightVerifier.verify_hand_ranking(low_straight_hand))

        high_straight_hand = Hand(
            [
                Ace(Suit.Spades),
                Jack(Suit.Diamonds),
                King(Suit.Clubs),
                Ten(Suit.Hearts),
                Queen(Suit.Clubs)
            ]
        )

        self.assertTrue(StraightVerifier.verify_hand_ranking(high_straight_hand))

        straight_flush_hand = Hand(
            [
                Ace(Suit.Spades),
                Jack(Suit.Spades),
                King(Suit.Spades),
                Ten(Suit.Spades),
                Queen(Suit.Spades)
            ]
        )

        self.assertTrue(StraightVerifier.verify_hand_ranking(straight_flush_hand))

        almost_straight_hand = Hand(
            [
                Two(Suit.Spades),
                Jack(Suit.Spades),
                King(Suit.Spades),
                Ten(Suit.Spades),
                Queen(Suit.Spades)
            ]
        )

        self.assertFalse(StraightVerifier.verify_hand_ranking(almost_straight_hand))
 def calculate_hand_ranking(hand):
     if StraightFlushVerifier.verify_hand_ranking(hand):
         return StraightFlushCalculator.calculate_hand_ranking(hand)
     else:
         if FourOfAKindVerifier.verify_hand_ranking(hand):
             return FourOfAKindCalculator.calculate_hand_ranking(hand)
         else:
             if FullHouseVerifier.verify_hand_ranking(hand):
                 return FullHouseCalculator.calculate_hand_ranking(hand)
             else:
                 if FlushVerifier.verify_hand_ranking(hand):
                     return FlushCalculator.calculate_hand_ranking(hand)
                 else:
                     if StraightVerifier.verify_hand_ranking(hand):
                         return StraightCalculator.calculate_hand_ranking(hand)
                     else:
                         if ThreeOfAKindVerifier.verify_hand_ranking(hand):
                             return ThreeOfAKindCalculator.calculate_hand_ranking(hand)
                         else:
                             if TwoPairVerifier.verify_hand_ranking(hand):
                                 return TwoPairCalculator.calculate_hand_ranking(hand)
                             else:
                                 if OnePairVerifier.verify_hand_ranking(hand):
                                     return OnePairCalculator.calculate_hand_ranking(hand)
                                 else:
                                     if HighCardVerifier.verify_hand_ranking(hand):
                                         return HighCardCalculator.calculate_hand_ranking(hand)
                                     else:
                                         raise RuntimeError("unknown hand ranking")
 def calculate_hand_ranking(hand):
     if StraightVerifier.verify_hand_ranking(hand) and not StraightFlushVerifier.verify_hand_ranking(hand):
         # Check for low straight case
         if any(isinstance(card, Ace) for card in hand.cards) and any(isinstance(card, Two) for card in hand.cards) and any(isinstance(card, Three) for card in hand.cards) and any(isinstance(card, Four) for card in hand.cards) and any(isinstance(card, Five) for card in hand.cards):
             high_value = [card for card in hand.cards if isinstance(card, Five)][0].value
             return Straight(high_value)
         high_value = sorted([card.value for card in hand.cards], reverse=True)[0]
         return Straight(high_value)
     else:
         raise RuntimeError("hand is not straight")