sudoku-solver/tests.py

265 lines
7.4 KiB
Python
Raw Normal View History

2019-11-30 15:21:33 +01:00
"""All tests for the Sudoku Solver."""
import unittest
import copy
from main import iterate_board
from board import Board
2019-11-30 15:21:33 +01:00
from square import Square
class TestMain(unittest.TestCase):
"""TestCase for the main file."""
def test_iterate_over_various_board_difficulties(self):
"""Run the solver on different boards."""
strings = [(
".2..785..\n"
"4...52...\n"
"..1..3.2.\n"
".....1...\n"
"7348.526.\n"
"2.9.67..5\n"
".687..3.9\n"
"342.1.7..\n"
"19..86..2\n"
), (
"..1..6435\n"
".....1...\n"
".5.47.98.\n"
"..2.8.7.9\n"
"..87..612\n"
".64.1..5.\n"
"91.3428.7\n"
".27....9.\n"
"6.3.9.5..\n"
), (
".....6...\n"
"..2.35.8.\n"
"....2..13\n"
".2....19.\n"
"93....7..\n"
"5....4...\n"
"1......7.\n"
".7...142.\n"
".9.4.3...\n"
), (
"...82....\n"
"...6.9..1\n"
"9.4..1...\n"
".9.7..28.\n"
".......57\n"
"7.5......\n"
".78962..5\n"
".2..8.7.3\n"
".6..74.2.\n"
), (
"4......1.\n"
".15.4.6..\n"
".....7...\n"
"...21...8\n"
"...734..2\n"
".3..8....\n"
"8.19...45\n"
".4....7..\n"
"2....3...\n"
), (
"3........\n"
".6...791.\n"
".....325.\n"
".19.645..\n"
".......6.\n"
".85......\n"
"...8.....\n"
"..1..97..\n"
"47..5....\n"
)]
for string in strings[:-4]:
while '.' in string:
new_string = iterate_board(string)
self.assertNotEqual(new_string, string)
string = new_string
class TestBoard(unittest.TestCase):
"""TestCase for Board."""
def setUp(self):
self.string = (
".2..785..\n"
"4...52...\n"
"..1..3.2.\n"
".....1...\n"
"7348.526.\n"
"2.9.67..5\n"
".687..3.9\n"
"342.1.7..\n"
"19..86..2\n"
)
2019-12-02 17:34:39 +01:00
self.board = Board(self.string, debug=False)
def test_lines_are_correctly_initialized(self):
"""There should be 9 lines, each a set of its values."""
self.assertIsInstance(self.board.lines, list)
self.assertEqual(len(self.board.lines), 9)
for line in self.board.lines:
self.assertIsInstance(line, set)
self.assertNotEqual(len(line), 0)
def test_columns_are_correctly_initialized(self):
"""There should be 9 columns, each a set of its values."""
self.assertIsInstance(self.board.columns, list)
self.assertEqual(len(self.board.columns), 9)
for column in self.board.columns:
self.assertIsInstance(column, set)
self.assertNotEqual(len(column), 0)
def test_grids_are_correctly_initialized(self):
"""There should be 9 grids, each a set of its values."""
self.assertIsInstance(self.board.grids, list)
self.assertEqual(len(self.board.grids), 9)
for grid in self.board.grids:
self.assertIsInstance(grid, set)
self.assertNotEqual(len(grid), 0)
def test_squares_are_correctly_initialized(self):
2019-12-02 17:34:39 +01:00
"""There should be 81 squares, each a Square object."""
self.assertIsInstance(self.board.squares, list)
2019-12-02 17:34:39 +01:00
self.assertEqual(len(self.board.squares), 81)
for square in self.board.squares:
self.assertIsInstance(square, Square)
self.assertIsInstance(square.values, set)
self.assertLess(len(square.values), 2)
def test_compute_possible_values(self):
"""For each square, values are added if the square was empty.
If the square was not empty, it had only one value. Values should not
be added if the square was not empty.
"""
empty_squares = 0
squares_with_one_value = 0
for square in self.board.squares:
if len(square.values) == 0:
empty_squares += 1
# We already tested that if len(square.values) != 0 it must be 1
else:
squares_with_one_value += 1
old_squares = copy.deepcopy(self.board.squares)
2019-12-02 17:34:39 +01:00
self.board.compute_possible_values()
new_squares = copy.deepcopy(self.board.squares)
self.assertEqual(len(old_squares), 81)
self.assertEqual(len(new_squares), 81)
2019-12-02 17:34:39 +01:00
for i in range(81):
if len(old_squares[i].values) != 1:
self.assertLess(
len(old_squares[i].values), len(new_squares[i].values)
)
else:
self.assertEqual(
len(old_squares[i].values), len(new_squares[i].values)
)
squares_with_more_than_one_value = 0
2019-12-02 17:34:39 +01:00
for square in self.board.squares:
self.assertGreater(len(square.values), 0)
if len(square.values) > 1:
squares_with_more_than_one_value += 1
# Maybe only one value was computed.
self.assertLessEqual(
squares_with_more_than_one_value, empty_squares
)
2019-12-03 09:06:16 +01:00
def test_compute_obligated(self):
"""Method works."""
def test_update_board(self):
"""Updated board is consistent with board.string."""
2019-12-02 17:34:39 +01:00
old_string: str = self.board.string
2019-12-02 17:34:39 +01:00
self.board.update_board()
self.assertEqual(old_string, self.board.string)
2019-12-02 17:34:39 +01:00
old_string = old_string.replace('\n', '')
self.assertEqual(len(old_string), 81)
for square_nb, square in enumerate(self.board.squares):
if len(square.values) == 1:
self.assertEqual(
str(square.values)[2:-2],
old_string[square_nb]
)
def test_update_string(self):
"""Updated board.string is consistent with board."""
old_string: str = self.board.string
2019-12-03 09:06:16 +01:00
self.board.update_string()
self.assertEqual(len(self.string), 90)
self.assertEqual(len(old_string), 90)
self.assertEqual(len(self.board.string), 90)
empty_squares = 0
2019-12-03 09:06:16 +01:00
for square in self.board.squares:
if len(square.values) != 1:
empty_squares += 1
self.assertEqual(empty_squares, self.board.string.count('.'))
2019-11-30 15:21:33 +01:00
class TestSquare(unittest.TestCase):
"""TestCase for Square."""
2019-11-30 15:21:33 +01:00
def setUp(self):
content = '.'
self.board = [
Square(line, column, content)
for line in range(9)
for column in range(9)
]
self.assertEqual(len(self.board), 81)
def test_grid_is_correctly_computed(self):
"""Square.grid is correctly computed for all values."""
correct_grids = (
"000111222"
"000111222"
"000111222"
"333444555"
"333444555"
"333444555"
"666777888"
"666777888"
"666777888"
)
for i, square in enumerate(self.board):
2019-12-02 17:34:39 +01:00
self.assertEqual(square.grid, int(correct_grids[i]))
2019-11-30 15:21:33 +01:00
if __name__ == '__main__':
unittest.main()