From c0fe222832fa83ab61b0f0922959423f05c2ddca Mon Sep 17 00:00:00 2001 From: Cameron Blankenbuehler Date: Tue, 30 May 2023 19:35:23 -0400 Subject: [PATCH] Add tests for parsing board input files --- boggler/boggler_utils.py | 26 +++++++- tests/boards/4x4_between_whitespace.board | 4 ++ tests/boards/4x4_blank_lines.board | 9 +++ tests/boards/4x4_clean.board | 4 ++ tests/boards/4x4_inconsistent_width.board | 4 ++ tests/boards/4x4_leading_whitespace.board | 4 ++ tests/boards/4x4_trailing_whitespace.board | 4 ++ tests/boards/4x4_wrong_size.board | 4 ++ tests/test_read_boards.py | 69 ++++++++++++++++++++++ 9 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 tests/boards/4x4_between_whitespace.board create mode 100644 tests/boards/4x4_blank_lines.board create mode 100644 tests/boards/4x4_clean.board create mode 100644 tests/boards/4x4_inconsistent_width.board create mode 100644 tests/boards/4x4_leading_whitespace.board create mode 100644 tests/boards/4x4_trailing_whitespace.board create mode 100644 tests/boards/4x4_wrong_size.board create mode 100644 tests/test_read_boards.py diff --git a/boggler/boggler_utils.py b/boggler/boggler_utils.py index 4966a34..b39d8c8 100755 --- a/boggler/boggler_utils.py +++ b/boggler/boggler_utils.py @@ -406,10 +406,32 @@ def read_wordlist(file): with open(file, 'r', encoding='utf-8') as file: return file.read().split() +class BadBoardFormat(Exception): + pass + def read_boggle_file(file): - '''Return list of rows from Boggle board csv file''' + '''Return list of rows from Boggle board csv file + + The size of the board is determined by the width (number of comma-separated values) + of the first (non-empty) line in the file. + + ''' with open(file, 'r', encoding='utf-8') as file: - return [x.rstrip().split(',') for x in file.readlines()] + board = [] + + board.append([x.strip() for x in file.readline().split(",")]) + board_size = len(board[0]) + for line in file.readlines(): + if line.strip() == "": + raise BadBoardFormat("board files must contain no blank lines") + + row = [x.strip() for x in line.strip().split(',')] + if len(row) != board_size: + raise BadBoardFormat("the length of each row must be the same") + + board.append(row) + + return board def find_paths_by_word(board_letters, dictionary_path, max_len): '''Return list of paths by word''' diff --git a/tests/boards/4x4_between_whitespace.board b/tests/boards/4x4_between_whitespace.board new file mode 100644 index 0000000..31f1576 --- /dev/null +++ b/tests/boards/4x4_between_whitespace.board @@ -0,0 +1,4 @@ +u, n,r ,e +qu, n,i, l +i ,s,h, a +s ,e , l,b \ No newline at end of file diff --git a/tests/boards/4x4_blank_lines.board b/tests/boards/4x4_blank_lines.board new file mode 100644 index 0000000..a4f9326 --- /dev/null +++ b/tests/boards/4x4_blank_lines.board @@ -0,0 +1,9 @@ + + +u,n,r,e +qu,n,i,l +i,s,h,a + +s,e,l,b + + diff --git a/tests/boards/4x4_clean.board b/tests/boards/4x4_clean.board new file mode 100644 index 0000000..13463fd --- /dev/null +++ b/tests/boards/4x4_clean.board @@ -0,0 +1,4 @@ +u,n,r,e +qu,n,i,l +i,s,h,a +s,e,l,b \ No newline at end of file diff --git a/tests/boards/4x4_inconsistent_width.board b/tests/boards/4x4_inconsistent_width.board new file mode 100644 index 0000000..fa5b665 --- /dev/null +++ b/tests/boards/4x4_inconsistent_width.board @@ -0,0 +1,4 @@ +u,n,r,e,a,i +qu,n,i,l +i,s,h,a,j +s,e,l \ No newline at end of file diff --git a/tests/boards/4x4_leading_whitespace.board b/tests/boards/4x4_leading_whitespace.board new file mode 100644 index 0000000..31b278a --- /dev/null +++ b/tests/boards/4x4_leading_whitespace.board @@ -0,0 +1,4 @@ + u,n,r,e + qu,n,i,l + i,s,h,a +s,e,l,b \ No newline at end of file diff --git a/tests/boards/4x4_trailing_whitespace.board b/tests/boards/4x4_trailing_whitespace.board new file mode 100644 index 0000000..6ca5e70 --- /dev/null +++ b/tests/boards/4x4_trailing_whitespace.board @@ -0,0 +1,4 @@ +u,n,r,e +qu,n,i,l +i,s,h,a +s,e,l,b \ No newline at end of file diff --git a/tests/boards/4x4_wrong_size.board b/tests/boards/4x4_wrong_size.board new file mode 100644 index 0000000..d11d146 --- /dev/null +++ b/tests/boards/4x4_wrong_size.board @@ -0,0 +1,4 @@ +u,n,r,e,b +qu,n,i,l +i,s,h,a,g,i +s,e,l,b \ No newline at end of file diff --git a/tests/test_read_boards.py b/tests/test_read_boards.py new file mode 100644 index 0000000..6af6e3e --- /dev/null +++ b/tests/test_read_boards.py @@ -0,0 +1,69 @@ +from pathlib import Path +import pytest +from boggler.boggler_utils import read_boggle_file, BadBoardFormat + +boards_path = Path(Path(__file__).parent.resolve()) + +@pytest.fixture(name="expected_board_4x4") +def fixture_expected_board_4x4(): + return [ + ['u', 'n', 'r', 'e'], + ['qu', 'n', 'i', 'l'], + ['i', 's', 'h', 'a'], + ['s', 'e', 'l', 'b'] + ] + +# Boards with clean input +@pytest.fixture(name="clean_4x4_path") +def fixture_clean_4x4_path(): + return Path(boards_path, "./boards/4x4_clean.board") + +def test_clean_4x4_board(expected_board_4x4, clean_4x4_path): + assert expected_board_4x4 == read_boggle_file(clean_4x4_path) + + +# Boards with leading whitespace +@pytest.fixture(name="leading_whitespace_4x4_path") +def fixture_leading_whitespace_4x4_path(): + return Path(boards_path, "./boards/4x4_leading_whitespace.board") + +def test_leading_whitespace_4x4_board(expected_board_4x4, leading_whitespace_4x4_path): + assert expected_board_4x4 == read_boggle_file(leading_whitespace_4x4_path) + + +# Boards with between whitespace +@pytest.fixture(name="between_whitespace_4x4_path") +def fixture_between_whitespace_4x4_path(): + return Path(boards_path, "./boards/4x4_between_whitespace.board") + +def test_between_whitespace_4x4_board(expected_board_4x4, between_whitespace_4x4_path): + assert expected_board_4x4 == read_boggle_file(between_whitespace_4x4_path) + + +# Boards with trailing whitespace +@pytest.fixture(name="trailing_whitespace_4x4_path") +def fixture_trailing_whitespace_4x4_path(): + return Path(boards_path, "./boards/4x4_trailing_whitespace.board") + +def test_trailing_whitespace_4x4_board(expected_board_4x4, trailing_whitespace_4x4_path): + assert expected_board_4x4 == read_boggle_file(trailing_whitespace_4x4_path) + + +# Boards with blank lines +@pytest.fixture(name="blank_lines_4x4_path") +def fixture_blank_lines_4x4_path(): + return Path(boards_path, "./boards/4x4_blank_lines.board") + +def test_blank_lines_4x4_board(blank_lines_4x4_path): + with pytest.raises(BadBoardFormat, match="must contain no blank lines"): + read_boggle_file(blank_lines_4x4_path) + + +# Boards with inconsistent width lines +@pytest.fixture(name="inconsistent_width_4x4_path") +def fixture_inconsistent_width_4x4_path(): + return Path(boards_path, "./boards/4x4_inconsistent_width.board") + +def test_inconsistent_width_4x4_board(inconsistent_width_4x4_path): + with pytest.raises(BadBoardFormat, match="length of each row must be the same"): + read_boggle_file(inconsistent_width_4x4_path)