def test_split_6(self): """Split sixes if dealer's card is two through six.""" expected1 = True expected2 = False hand = cards.Hand([ cards.Card(6, 2), cards.Card(6, 1), ]) player = players.Player((hand, ), 'Graham') dhand = cards.Hand([ cards.Card(6, 3), cards.Card(10, 0, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, None) actual1 = willsplit.will_split_recommended(player, hand, g) self.assertEqual(expected1, actual1) hand = cards.Hand([ cards.Card(6, 2), cards.Card(6, 1), ]) player = players.Player((hand, ), 'Graham') dhand = cards.Hand([ cards.Card(7, 3), cards.Card(10, 0, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, None) actual2 = willsplit.will_split_recommended(player, hand, g) self.assertEqual(expected2, actual2)
def test__update_hand_split(self, mock_main): """If sent a split hand, _update_hand() should update the split row of the table. """ hands = [ cards.Hand([ cards.Card(11, 0), ]), cards.Hand([ cards.Card(11, 3), ]), ] player = players.Player(hands, name='spam', chips=100) player2 = players.Player(name='eggs', chips=100) new_data = [ [player, 100, 20, 'J♣', 'Splits hand.'], [' \u2514\u2500', '', 20, 'J♠ 5♣', 'Hits.'], [player2, 100, 20, '3♣ 4♣', 'Takes hand.'], ] exp = call().send(('update', new_data)) data = [ [player, 100, 20, 'J♣', 'Splits hand.'], [' \u2514\u2500', '', 20, 'J♠', 'Splits hand.'], [player2, 100, 20, '3♣ 4♣', 'Takes hand.'], ] ui = cli.TableUI() ui.ctlr.data = data ui.start() hands[1].append(cards.Card(5, 0)) ui._update_hand(player, hands[1], 'Hits.') act = mock_main.mock_calls[-1] ui.end() self.assertEqual(exp, act)
def test_has_decision_methods(self): """The players created by make_player() should have the decision methods for Players, such as will_hit and will_insure. """ # As long as no exception is raised, this test passes. phand = cards.Hand([ cards.Card(11, 3), cards.Card(1, 2), ]) dhand = cards.Hand([ cards.Card(11, 3), cards.Card(1, 2), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, None, None, 2) player = players.make_player() methods = [ player.will_hit, player.will_split, player.will_double_down, ] for method in methods: _ = method(phand, g) methods = [ player.will_buyin, player.will_insure, ] for method in methods: _ = method(g)
def test_cleanup(self, mock_main): """When called, cleanup() should clear the bet, hand, and event field of every row in the data table, then send it to the UI. """ hands = [ cards.Hand([ cards.Card(11, 0), ]), cards.Hand([ cards.Card(11, 3), ]), ] player = players.Player(hands, name='spam', chips=100) player2 = players.Player(hands, name='eggs', chips=100) new_data = [ [player, 100, '', '', ''], [player2, 100, '', '', ''], ] exp = call().send(('update', new_data)) data = [ [player, 100, 20, 'J♣', 'Splits hand.'], [' \u2514\u2500', '', 20, 'J♠', 'Splits hand.'], [player2, 100, 20, '3♣ 4♣', 'Takes hand.'], ] ui = cli.TableUI() ui.ctlr.data = data ui.start() ui.cleanup() act = mock_main.mock_calls[-1] self.assertEqual(exp, act)
def test__update_bet_split(self, mock_main): """When is_split is True, _update_bet should update the split row of the data table for the player. """ hands = [ cards.Hand([ cards.Card(11, 0), ]), cards.Hand([ cards.Card(11, 3), ]), ] player = players.Player(hands, name='spam', chips=100) player2 = players.Player(name='eggs', chips=100) new_data = [ [player, 100, 20, 'J♣', 'Splits hand.'], [' \u2514\u2500', '', 20, 'J♠', 'Loses.'], [player2, 100, 20, '3♣ 4♣', 'Takes hand.'], ] exp = call().send(('update', new_data)) data = [ [player, 100, 20, 'J♣', 'Splits hand.'], [' \u2514\u2500', '', '', 'J♠', ''], [player2, 100, 20, '3♣ 4♣', 'Takes hand.'], ] ui = cli.TableUI() ui.ctlr.data = data ui.start() ui._update_bet(player, 20, 'Loses.', split=True) act = mock_main.mock_calls[-1] ui.end() self.assertEqual(exp, act)
def test_fromdict_methods(self): """Given a dictionary as created by asdict(), fromdict() should deserialize the Player object. """ exp = MethodType hands = (cards.Hand(( cards.Card(11, 3), cards.Card(2, 1), )), ) value = { 'class': 'Player', 'chips': 200, 'hands': hands, 'insured': 0, 'name': 'spam', 'will_buyin': 'will_buyin_always', 'will_double_down': 'will_double_down_always', 'will_hit': 'will_hit_dealer', 'will_insure': 'will_insure_always', 'will_split': 'will_split_always', } methods = [key for key in value if key.startswith('will_')] player = players.Player.fromdict(value) for method in methods: act = getattr(player, method) self.assertIsInstance(act, exp)
def test_fromdict(self): """Given a dictionary as created by asdict(), fromdict() should deserialize the Player object. """ hands = (cards.Hand(( cards.Card(11, 3), cards.Card(2, 1), )), ) exp = players.Player(hands, 'spam', 200) exp.will_buyin = MethodType(players.will_buyin_always, exp) exp.will_double_down = MethodType(players.will_double_down_always, exp) exp.will_hit = MethodType(players.will_hit_dealer, exp) exp.will_insure = MethodType(players.will_insure_always, exp) exp.will_split = MethodType(players.will_split_always, exp) value = { 'class': 'Player', 'chips': 200, 'hands': hands, 'insured': 0, 'name': 'spam', 'will_buyin': 'will_buyin_always', 'will_double_down': 'will_double_down_always', 'will_hit': 'will_hit_dealer', 'will_insure': 'will_insure_always', 'will_split': 'will_split_always', } act = players.Player.fromdict(value) self.assertEqual(exp, act)
def test_serialize(self): """When called, serialize() should return the object serialized as a JSON string. """ hands = (cards.Hand(( cards.Card(11, 3), cards.Card(2, 1), )), ) exp = json.dumps({ 'class': 'Player', 'chips': 200, 'hands': (hands[0].serialize(), ), 'insured': 0, 'name': 'spam', 'will_buyin': 'will_buyin_always', 'will_double_down': 'will_double_down_always', 'will_hit': 'will_hit_dealer', 'will_insure': 'will_insure_always', 'will_split': 'will_split_always', }) player = players.Player(hands, 'spam', 200) player.will_buyin = MethodType(players.will_buyin_always, player) player.will_double_down = MethodType(players.will_double_down_always, player) player.will_hit = MethodType(players.will_hit_dealer, player) player.will_insure = MethodType(players.will_insure_always, player) player.will_split = MethodType(players.will_split_always, player) act = player.serialize() self.assertEqual(exp, act)
def test_hand_updates(self, mock_update): """The methods tested should send _update_hand a player, hand, and event text for display to the user. """ player = players.Player(name='spam') hand = cards.Hand([ cards.Card(11, 3), cards.Card(1, 0), ]) events = [ 'Dealt hand.', 'Flip.', 'Hit.', 'Stand.', ] exp = [call(player, hand, event) for event in events] ui = cli.LogUI() ui.deal(player, hand) ui.flip(player, hand) ui.hit(player, hand) ui.stand(player, hand) act = mock_update.mock_calls self.assertListEqual(exp, act)
def test_fromdict_invalid_method(self): """Given a dictionary as created by asdict(), fromdict() should deserialize the Player object. """ exp = ValueError hands = (cards.Hand(( cards.Card(11, 3), cards.Card(2, 1), )), ) dict_ = { 'class': 'Player', 'chips': 200, 'hands': hands, 'insured': 0, 'name': 'spam', 'will_buyin': 'will_buyin_always', 'will_double_down': 'will_double_down_always', 'will_hit': 'will_hit_dealer', 'will_insure': 'will_insure_always', 'will_split': 'will_split_always', } methkeys = [key for key in dict_ if key.startswith('will_')] test = 'spam' for key in methkeys: test_dict = copy(dict_) test_dict[key] = test with self.assertRaises(exp): act = players.Player.fromdict(test_dict)
def test__asdict(self): """When called, asdict() should serialize the object to a dictionary. """ hands = (cards.Hand(( cards.Card(11, 3), cards.Card(2, 1), )), ) exp = { 'class': 'Player', 'chips': 200, 'hands': hands, 'insured': 0, 'name': 'spam', 'will_buyin': 'will_buyin_always', 'will_double_down': 'will_double_down_always', 'will_hit': 'will_hit_dealer', 'will_insure': 'will_insure_always', 'will_split': 'will_split_always', } player = players.Player(hands, 'spam', 200) player.will_buyin = MethodType(players.will_buyin_always, player) player.will_double_down = MethodType(players.will_double_down_always, player) player.will_hit = MethodType(players.will_hit_dealer, player) player.will_insure = MethodType(players.will_insure_always, player) player.will_split = MethodType(players.will_split_always, player) act = player._asdict() self.assertEqual(exp, act)
def test_serialize(self): """When called, serialize() should return the object serialized as a JSON string. """ exp = json.dumps({ 'class': 'Hand', '_iter_index': 0, 'cards': [ '["Card", 11, "clubs", true]', '["Card", 12, "clubs", true]', '["Card", 13, "clubs", true]', ], 'doubled_down': False, }) cardlist = [ cards.Card(11, 0, True), cards.Card(12, 0, True), cards.Card(13, 0, True), ] hand = cards.Hand(cardlist) act = hand.serialize() self.assertEqual(exp, act)
def test_hand_updates(self, mock_update_hand, _): """The tested methods should call the _update_hand() method with the player, hand, and event text. """ player = players.Player(name='spam', chips=100) hand = cards.Hand([ cards.Card(11, 0), cards.Card(10, 3), ]) handstr = str(hand) exp = [ call(player, hand, 'Takes hand.'), call(player, hand, 'Flips card.'), call(player, hand, 'Hits.'), call(player, hand, 'Stands.'), ] data = [ [player, 80, 20, '', ''], ] ui = cli.TableUI() ui.ctlr.data = data ui.start() ui.deal(player, hand) ui.flip(player, hand) ui.hit(player, hand) ui.stand(player, hand) act = mock_update_hand.mock_calls[-4:] ui.end() self.assertEqual(exp, act)
def test_always_true(self): """will_double_down_always() will always return True.""" g = game.Engine() h = cards.Hand() p = players.Player() actual = willdoubledown.will_double_down_always(p, h, g) self.assertTrue(actual)
def test_always_true(self): """will_split_always() should return True.""" hand = cards.Hand() player = players.Player((hand, ), 'John Cleese') player.will_split = partial(willsplit.will_split_always, None) actual = player.will_split(hand, None) self.assertTrue(actual)
def test_never_double_down(self): """will_double_down_never should always return False.""" expected = False phand = cards.Hand([ cards.Card(4, 0), cards.Card(6, 0), ]) player = players.Player((phand, ), 'Terry') dhand = cards.Hand([ cards.Card(11, 0), cards.Card(8, 3, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, None) actual = willdoubledown.will_double_down_never(player, phand, g) self.assertEqual(expected, actual)
def test_stand(self): """If the situation doesn't match the above criteria, stand.""" expected = False phand = cards.Hand([ cards.Card(10, 1), cards.Card(11, 2), ]) player = players.Player((phand, ), 'John') dhand = cards.Hand([ cards.Card(5, 1), cards.Card(2, 3, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, 20) actual = willhit.will_hit_recommended(None, phand, g) self.assertEqual(expected, actual)
def test_double_down_if_11(self): """If the player's hand is 11, player should double down.""" expected = True phand = cards.Hand([ cards.Card(5, 0), cards.Card(6, 0), ]) player = players.Player((phand, ), 'Terry') dhand = cards.Hand([ cards.Card(11, 0), cards.Card(8, 3), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, None) actual = willdoubledown.will_double_down_recommended(player, phand, g) self.assertEqual(expected, actual)
def test_stand(self): """will_hit_never() should never return True.""" expected = False phand = cards.Hand([ cards.Card(10, 1), cards.Card(11, 2), ]) player = players.Player((phand, ), 'John') dhand = cards.Hand([ cards.Card(5, 1), cards.Card(2, 3, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, 20) actual = willhit.will_hit_never(None, phand, g) self.assertEqual(expected, actual)
def test_split_ace_or_8(self): """Always split aces or eights.""" expected = True hand = cards.Hand([ cards.Card(1, 2), cards.Card(1, 1), ]) player = players.Player((hand, ), 'Graham') dhand = cards.Hand([ cards.Card(7, 3), cards.Card(10, 0, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, None) actual = willsplit.will_split_recommended(player, hand, g) self.assertEqual(expected, actual)
def test_never_split(self): """will_split_never() should return False.""" expected = False hand = cards.Hand([ cards.Card(10, 2), cards.Card(10, 1), ]) player = players.Player((hand, ), 'Graham') dhand = cards.Hand([ cards.Card(7, 3), cards.Card(10, 0, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, None) actual = willsplit.will_split_never(player, hand, g) self.assertEqual(expected, actual)
def test_split_4_5_or_8(self): """Never split fours, fives, or eights.""" expected = False hand = cards.Hand([ cards.Card(10, 2), cards.Card(10, 1), ]) player = players.Player((hand, ), 'Graham') dhand = cards.Hand([ cards.Card(7, 3), cards.Card(10, 0, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, None) actual = willsplit.will_split_recommended(player, hand, g) self.assertEqual(expected, actual)
def test_hit_on_less_than_17(self): """If the score of the hand is less than 17, will_hit_dealer() should return true. """ expected = willhit.HIT h1 = cards.Hand([ cards.Card(11, 0), cards.Card(6, 2), ]) h2 = cards.Hand([ cards.Card(2, 1), cards.Card(2, 3), cards.Card(8, 1), ]) actual_h1 = willhit.will_hit_dealer(None, h1) actual_h2 = willhit.will_hit_dealer(None, h2) self.assertEqual(expected, actual_h1)
def test_can_split_true(self): """can_split() should return true if the hand can be split.""" cardlist = [ cards.Card(10, 0), cards.Card(10, 2), ] h = cards.Hand(cardlist) actual = h.can_split() self.assertTrue(actual)
def test_valid(self): """Given a valid value, validate_handtuple should normalize and validate it then return the normalized value. """ exp = ( cards.Hand(( cards.Card(11, 3), cards.Card(1, 1), )), cards.Hand(( cards.Card(3, 1), cards.Card(5, 1), )), ) value = list(exp) act = cards.validate_handtuple(None, value) self.assertEqual(exp, act)
def test_do_not_hit_soft_19(self): """If the player's hand is a soft 19, don't hit.""" expected = False phand = cards.Hand([ cards.Card(1, 1), cards.Card(6, 2), cards.Card(2, 2), ]) player = players.Player((phand, ), 'John') dhand = cards.Hand([ cards.Card(2, 1), cards.Card(2, 3, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, 20) actual = willhit.will_hit_recommended(None, phand, g) self.assertEqual(expected, actual)
def test_always_zero(self): """will_double_down_always() will always return the maximum bet, which is half of the game's buy in.""" expected = 10 h = cards.Hand() p = players.Player() g = game.Engine(None, None, (p, ), None, 20) actual = willinsure.will_insure_always(p, g) self.assertEqual(expected, actual)
def test_stand_on_17_plus(self): """If the score of the hand is 17 or greater, will_hit_dealer() should return False. """ expected = willhit.STAND h1 = cards.Hand([ cards.Card(11, 0), cards.Card(7, 2), ]) h2 = cards.Hand([ cards.Card(12, 1), cards.Card(2, 3), cards.Card(8, 1), ]) actual_h1 = willhit.will_hit_dealer(None, h1) actual_h2 = willhit.will_hit_dealer(None, h2) self.assertEqual(expected, actual_h1) self.assertEqual(expected, actual_h2)
def test_double_down_on_10(self): """If player's hand is 10 and the dealer's card is a 9 or less, the player should double down. """ expected = True phand = cards.Hand([ cards.Card(4, 0), cards.Card(6, 0), ]) player = players.Player((phand, ), 'Terry') dhand = cards.Hand([ cards.Card(9, 0), cards.Card(8, 3, cards.DOWN), ]) dealer = players.Dealer((dhand, ), 'Dealer') g = game.Engine(None, dealer, (player, ), None, None) actual = willdoubledown.will_double_down_recommended(player, phand, g) self.assertEqual(expected, actual)
def test_append(self): """Given a Card object, append() should append that card to cards. """ expected = self.cardlist() h = cards.Hand(expected[:2]) h.append(expected[2]) actual = h.cards self.assertEqual(expected, actual)