def setUp(self): self._disk_1 = Disk(1) self._disk_2 = Disk(2) self._disk_3 = Disk(3) self._disk_4 = Disk(4) self._peg_b = self._create_peg_b() self._peg_c = self._create_peg_c() self._game = Game()
#!/usr/bin/env python3 import sys from tower_of_hanoi import Game def print_peg(peg): print('{0}: {1}'.format(peg.name(), ' - '.join([str(disk.size()) for disk in peg.disks()]))) def print_pegs(pegs): print('==========') for peg in sorted(pegs, key=lambda peg: peg.name()): print_peg(peg) if len(sys.argv) != 2: print('Usage: {0} <disk_count>'.format(sys.argv[0])) sys,exit(1) disk_count = int(sys.argv[1]) assert disk_count > 0 game = Game() peg_a = game.create_peg('A', disk_count) peg_b = game.create_peg('B') peg_c = game.create_peg('C') print_pegs([peg_a, peg_b, peg_c]) # display initial state game.move(disk_count, peg_a, peg_c, peg_b, print_pegs)
class GameTestCase(unittest.TestCase): def _create_peg_a(self, disks): return Peg('a', disks) def _create_peg_b(self, disks=[]): return Peg('b', disks) def _create_peg_c(self, disks=[]): return Peg('c', disks) def setUp(self): self._disk_1 = Disk(1) self._disk_2 = Disk(2) self._disk_3 = Disk(3) self._disk_4 = Disk(4) self._peg_b = self._create_peg_b() self._peg_c = self._create_peg_c() self._game = Game() def test__create_peg__returns_peg_with_specified_name(self): name = 'name' peg = self._game.create_peg(name) self.assertEqual(name, peg.name()) def test__create_peg__when_disk_count_is_0__returns_empty_peg(self): peg = self._game.create_peg('name', 0) self.assertEqual([], peg.disks()) def test__create_peg__when_disk_count_is_1__returns_peg_with_1_disk(self): peg = self._game.create_peg('name', 1) self.assertEqual([self._disk_1], peg.disks()) def test__create_peg__when_disk_count_is_3__returns_peg_with_3_disks_in_ascending_order_from_top(self): peg = self._game.create_peg('name', 3) self.assertEqual([self._disk_3, self._disk_2, self._disk_1], peg.disks()) def test__move__when_disk_count_is_1__invokes_callback_after_each_move(self): move_spy = mock.Mock() peg_a = self._create_peg_a([self._disk_1]) self._game.move(1, peg_a, self._peg_c, self._peg_b, move_spy) expected_move_spy_call_args_list = [ mock.call([ self._create_peg_a([]), self._create_peg_c([self._disk_1]), self._create_peg_b([]) ]) ] self.assertEqual(expected_move_spy_call_args_list, move_spy.call_args_list) def test__move__when_disk_count_is_1__moves_disks_from_peg_a_to_peg_c(self): peg_a = self._create_peg_a([self._disk_1]) new_peg_a, new_peg_c, new_peg_b = self._game.move(1, peg_a, self._peg_c, self._peg_b) self.assertEqual(self._create_peg_a([]), new_peg_a) self.assertEqual(self._create_peg_b([]), new_peg_b) self.assertEqual(self._create_peg_c([self._disk_1]), new_peg_c) def test__move__when_disk_count_is_2__invokes_callback_after_each_move(self): move_spy = mock.Mock() peg_a = self._create_peg_a([self._disk_2, self._disk_1]) self._game.move(2, peg_a, self._peg_c, self._peg_b, move_spy) expected_move_spy_call_args_list = [ mock.call([ self._create_peg_a([self._disk_2]), self._create_peg_b([self._disk_1]), self._create_peg_c([]) ]), mock.call([ self._create_peg_a([]), self._create_peg_c([self._disk_2]), self._create_peg_b([self._disk_1]) ]), mock.call([ self._create_peg_b([]), self._create_peg_c([self._disk_2, self._disk_1]), self._create_peg_a([]) ]) ] self.assertSequenceEqual(expected_move_spy_call_args_list, move_spy.call_args_list) def test__move__when_disk_count_is_2__moves_disks_from_peg_a_to_peg_c(self): peg_a = self._create_peg_a([self._disk_2, self._disk_1]) new_peg_a, new_peg_c, new_peg_b = self._game.move(2, peg_a, self._peg_c, self._peg_b) self.assertEqual(self._create_peg_a([]), new_peg_a) self.assertEqual(self._create_peg_b([]), new_peg_b) self.assertEqual(self._create_peg_c([self._disk_2, self._disk_1]), new_peg_c) def test__move__when_disk_count_is_3__moves_disks_from_peg_a_to_peg_c(self): peg_a = self._create_peg_a([self._disk_3, self._disk_2, self._disk_1]) new_peg_a, new_peg_c, new_peg_b = self._game.move(3, peg_a, self._peg_c, self._peg_b) self.assertEqual(self._create_peg_a([]), new_peg_a) self.assertEqual(self._create_peg_b([]), new_peg_b) self.assertEqual(self._create_peg_c([self._disk_3, self._disk_2, self._disk_1]), new_peg_c) def test__move__when_disk_count_is_4__moves_disks_from_peg_a_to_peg_c(self): peg_a = self._create_peg_a([self._disk_4, self._disk_3, self._disk_2, self._disk_1]) new_peg_a, new_peg_c, new_peg_b = self._game.move(4, peg_a, self._peg_c, self._peg_b) self.assertEqual(self._create_peg_a([]), new_peg_a) self.assertEqual(self._create_peg_b([]), new_peg_b) self.assertEqual(self._create_peg_c([self._disk_4, self._disk_3, self._disk_2, self._disk_1]), new_peg_c) def test__move__when_disk_count_exceeds_source_peg_disk_count__raises_exception(self): peg_a = self._create_peg_a([self._disk_1]) with self.assertRaises(Exception): self._game.move(2, peg_a, self._peg_c, self._peg_b)
class GameTestCase(unittest.TestCase): class _MoveSpy(mock.Mock): ''' A test spy that can be passed as the `callback` parameter of the `Game.move` method. Because `Peg`s are mutable, we must copy the peg arguments during each call instead of storing them directly. Otherwise, all calls will reflect the final state of the pegs. ''' def _mock_call(self, *args, **kwargs): import copy args_copy = copy.deepcopy(args) kwargs_copy = copy.deepcopy(kwargs) return super()._mock_call(*args_copy, **kwargs_copy) def _create_peg_a(self, disks): return Peg('a', disks) def _create_peg_b(self, disks=[]): return Peg('b', disks) def _create_peg_c(self, disks=[]): return Peg('c', disks) def setUp(self): self._disk_1 = Disk(1) self._disk_2 = Disk(2) self._disk_3 = Disk(3) self._disk_4 = Disk(4) self._peg_b = self._create_peg_b() self._peg_c = self._create_peg_c() self._game = Game() def test__create_peg__returns_peg_with_specified_name(self): name = 'name' peg = self._game.create_peg(name) self.assertEqual(name, peg.name()) def test__create_peg__when_disk_count_is_0__returns_empty_peg(self): peg = self._game.create_peg('name', 0) self.assertEqual([], peg.disks()) def test__create_peg__when_disk_count_is_1__returns_peg_with_1_disk(self): peg = self._game.create_peg('name', 1) self.assertEqual([self._disk_1], peg.disks()) def test__create_peg__when_disk_count_is_3__returns_peg_with_3_disks_in_ascending_order_from_top(self): peg = self._game.create_peg('name', 3) self.assertEqual([self._disk_3, self._disk_2, self._disk_1], peg.disks()) def test__move__when_disk_count_is_1__invokes_callback_after_each_move(self): move_spy = GameTestCase._MoveSpy() peg_a = self._create_peg_a([self._disk_1]) self._game.move(1, peg_a, self._peg_c, self._peg_b, move_spy) expected_move_spy_call_args_list = [ mock.call([ self._create_peg_a([]), self._create_peg_c([self._disk_1]), self._create_peg_b([]) ]) ] self.assertEqual(expected_move_spy_call_args_list, move_spy.call_args_list) def test__move__when_disk_count_is_1__moves_disks_from_peg_a_to_peg_c(self): peg_a = self._create_peg_a([self._disk_1]) self._game.move(1, peg_a, self._peg_c, self._peg_b) self.assertEqual(self._create_peg_a([]), peg_a) self.assertEqual(self._create_peg_b([]), self._peg_b) self.assertEqual(self._create_peg_c([self._disk_1]), self._peg_c) def test__move__when_disk_count_is_2__invokes_callback_after_each_move(self): move_spy = GameTestCase._MoveSpy() peg_a = self._create_peg_a([self._disk_2, self._disk_1]) self._game.move(2, peg_a, self._peg_c, self._peg_b, move_spy) expected_move_spy_call_args_list = [ mock.call([ self._create_peg_a([self._disk_2]), self._create_peg_b([self._disk_1]), self._create_peg_c([]) ]), mock.call([ self._create_peg_a([]), self._create_peg_c([self._disk_2]), self._create_peg_b([self._disk_1]) ]), mock.call([ self._create_peg_b([]), self._create_peg_c([self._disk_2, self._disk_1]), self._create_peg_a([]) ]) ] self.assertEqual(expected_move_spy_call_args_list, move_spy.call_args_list) def test__move__when_disk_count_is_2__moves_disks_from_peg_a_to_peg_c(self): peg_a = self._create_peg_a([self._disk_2, self._disk_1]) self._game.move(2, peg_a, self._peg_c, self._peg_b) self.assertEqual(self._create_peg_a([]), peg_a) self.assertEqual(self._create_peg_b([]), self._peg_b) self.assertEqual(self._create_peg_c([self._disk_2, self._disk_1]), self._peg_c) def test__move__when_disk_count_is_3__moves_disks_from_peg_a_to_peg_c(self): peg_a = self._create_peg_a([self._disk_3, self._disk_2, self._disk_1]) self._game.move(3, peg_a, self._peg_c, self._peg_b) self.assertEqual(self._create_peg_a([]), peg_a) self.assertEqual(self._create_peg_b([]), self._peg_b) self.assertEqual(self._create_peg_c([self._disk_3, self._disk_2, self._disk_1]), self._peg_c) def test__move__when_disk_count_is_4__moves_disks_from_peg_a_to_peg_c(self): peg_a = self._create_peg_a([self._disk_4, self._disk_3, self._disk_2, self._disk_1]) self._game.move(4, peg_a, self._peg_c, self._peg_b) self.assertEqual(self._create_peg_a([]), peg_a) self.assertEqual(self._create_peg_b([]), self._peg_b) self.assertEqual(self._create_peg_c([self._disk_4, self._disk_3, self._disk_2, self._disk_1]), self._peg_c) def test__move__when_disk_count_exceeds_source_peg_disk_count__raises_exception(self): peg_a = self._create_peg_a([self._disk_1]) with self.assertRaises(Exception): self._game.move(2, peg_a, self._peg_c, self._peg_b)