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_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_joins(self, mock_main): """When given a player, joins() should add the player to the data table in the first empty row. """ player = players.Player(name='spam', chips=100) player2 = players.Player(name='eggs', chips=100) new_data1 = [ [player, 100, '', '', 'Sits down.'], ['', '', '', '', ''], ] new_data2 = [ [player, 100, '', '', 'Sits down.'], [player2, 100, '', '', 'Sits down.'], ] exp_call = [ call().send(('update', new_data1)), call().send(('update', new_data2)), ] data = [ ['', '', '', '', ''], ['', '', '', '', ''], ] ui = cli.TableUI() ui.ctlr.data = data ui.start() ui.joins(player) ui.ctlr.data = new_data1 ui.joins(player2) act_call = mock_main.mock_calls[-2:] ui.end() self.assertEqual(exp_call, act_call) self.assertNotEqual(new_data2, new_data1)
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_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__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__update_event(self, mock_main): """_update_event should send an event to the UI loop that a player has had an event occur. The data sent in that event should be a copy of the table in the termui.Table object. """ player = players.Player(name='spam', chips=80) msg = 'Walks away.' new_data = [ [player, 80, '', '', msg], ] exp = call().send(('update', new_data)) unexp_data = [ [player, 80, '', '', ''], ] ui = cli.TableUI() ui.ctlr.data = unexp_data ui.start() ui._update_event(player, msg) act = mock_main.mock_calls[-1] ui.end() self.assertEqual(exp, act) # Since termui.Table determines what fields to update based # on differences between it's data table and the data table # it's sent, it's very important that the changes made to # the data table output by _update_bet() are not yet seen in # the data table held by termui.Table. # # If this test fails, it's likely because you aren't copying # the rows of self.ctrl.data. You are referencing them. self.assertNotEqual(unexp_data[0][4], 'Takes hand.')
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_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_insured(self): """Player objects should initialize the insured attribute to zero. """ expected = 0 player = players.Player() actual = player.insured self.assertEqual(expected, 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___str__(self): """__str__() should return the name of the Player object.""" expected = 'Spam' p = players.Player(name=expected) actual = p.__str__() self.assertEqual(expected, actual)
def test_always_true(self): """will_buyin_always() will always return True.""" g = game.Engine() p = players.Player() p.will_buyin = partial(willbuyin.will_buyin_always, None) actual = p.will_buyin(g) self.assertTrue(actual)
def test_chips(self): """If passed a number of chips, that number should be stored in the chips attribute. """ expected = 200 p = players.Player(chips=expected) actual = p.chips self.assertEqual(expected, actual)
def test_valid(self): """Given a Player object, validate_player() should return it.""" exp = players.Player(name='spam') class Eggs: msg = '{}' act = players.validate_player_or_none(Eggs(), exp) self.assertEqual(exp, act)
def test_name(self): """If passed a name, the name attribute should be initialized with that name. """ expected = 'Spam' p = players.Player(name=expected) actual = p.name self.assertEqual(expected, actual)
def test_is_will_hit(self): """A will_hit function should accept a Player, a Hand, and a Game objects. """ player = players.Player() hand = cards.Hand([ cards.Card(11, 0), cards.Card(11, 3), ]) g = game.Engine() _ = willhit.will_hit_dealer(player, hand, g)
def test___format__(self): """__format__() should return as though it was called on the value of the name attribute. """ tmp = '{:<6}' expected = tmp.format('spam') p = players.Player(name='spam') actual = tmp.format(p) 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_parameters(self): """Functions that follow the will_buyin protocol should accept the following parameter: game. """ player = players.Player() g = game.Engine() player.will_buyin = partial(willbuyin.will_buyin_always, None) player.will_buyin(game) # The test was that no exception was raised when will_buyin # was called. self.assertTrue(True)
def test_parameters(self): """Functions that follow the will_double_down protocol should accept the following parameters: self, hand, game. """ player = players.Player() hand = cards.Hand() g = game.Engine() _ = willdoubledown.will_double_down_always(player, hand, game) # The test was that no exception was raised when will_buyin # was called. self.assertTrue(True)
def test_parameters(self): """Functions that follow the will_insure protocol should accept the following parameters: self, game. """ player = players.Player() hand = cards.Hand() g = game.Engine() _ = willinsure.will_insure_never(player, g) # The test was that no exception was raised when will_buyin # was called. self.assertTrue(True)
def test__update_event(self): """Given a player and an event, _update_event() should report that event to the user. """ player = players.Player(name='spam') event = 'Joins.' exp = self.tmp.format(player, event, '') ui = cli.LogUI() with capture() as (out, err): ui._update_event(player, event) act = out.getvalue() self.assertEqual(exp, act)
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 = False phand = cards.Hand([ cards.Card(4, 0), cards.Card(5, 0), ]) player = players.Player((phand, ), 'Terry') dhand = cards.Hand([ cards.Card(1, 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) expected = False phand = cards.Hand([ cards.Card(4, 0), cards.Card(5, 0), ]) player = players.Player((phand, ), 'Terry') dhand = cards.Hand([ cards.Card(7, 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_leaves(self, mock_main): """When given a player, leaves() should announce the player is leaving and remove the player from the data table. In order to avoid the row in the UI just going blank, this call will edit self.ctlr.data directly. """ player = players.Player(name='spam', chips=100) player2 = players.Player(name='eggs', chips=100) new_data = [ [player, '', '', '', 'Walks away.'], [player2, 100, '', '', 'Sits down.'], ] exp_call = call().send(('update', new_data)) exp_data = [ ['', '', '', '', 'Walks away.'], [player2, 100, '', '', 'Sits down.'], ] data = [ [player, 100, '', '', 'Sits down.'], [player2, 100, '', '', 'Sits down.'], ] ui = cli.TableUI() ui.ctlr.data = data def update_data(ctlr, data): ctlr.data = data mock_main.side_effect = update_data(ui.ctlr, [r[:] for r in new_data]) ui.start() ui.leaves(player) act_call = mock_main.mock_calls[-1] act_data = ui.ctlr.data ui.end() self.assertEqual(exp_call, act_call) self.assertEqual(exp_data, act_data)
def test_splits(self, mock_main): """When given a player and a bet, splits() should add a row to the data table for the split hand, update it with the relevant information, and 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, 20, 'J♣', 'Splits hand.'], [' \u2514\u2500', '', 20, 'J♠', ''], [player2, 100, 20, '3♣ 4♣', 'Takes hand.'], ] exp_call = call().send(('update', new_data)) unexp_len = len(new_data) data = [ [player, 100, 20, 'J♣ J♠', 'Takes hand.'], [player2, 100, 20, '3♣ 4♣', 'Takes hand.'], ] ui = cli.TableUI() ui.ctlr.data = data ui.start() ui.splits(player, 20) act_call = mock_main.mock_calls[-1] act_len = len(data) ui.end() self.assertEqual(exp_call, act_call) self.assertNotEqual(unexp_len, act_len)
def test_paramters(self): """Functions that follow the will_split protocol should accept the following parameters: hand, player, dealer, playerlist. """ hand = cards.Hand() player = players.Player((hand, ), 'John Cleese') g = game.Engine() method = MethodType(willsplit.will_split_always, player) player.will_split = partial(willsplit.will_split_always, None) player.will_split(hand, g) # The test was that no exception was raised when will_split # was called. self.assertTrue(True)