from gridedit import ( cell_column, cell_line, edit, h_segment_column, wall_column_left_of, wall_line_above, ) from dojo.board import Board, build_board from dojo.grid import parse_grid from dojo.validate import Report, validate def validate_text(text: str) -> Report: return validate(build_board(parse_grid(text))) def test_fixture_board_has_no_errors(board: Board) -> None: report = validate(board) assert report.errors == [] def test_fixture_stats(board: Board) -> None: stats = validate(board).stats assert stats is not None assert stats.playable_squares == 4 * (64 - 9 - 4) assert stats.square_counts == { ".": 172, "?": 4, "A": 8, "F": 4, "K": 4, "P": 4, "T": 8, } assert stats.dojo_entrances == 4 assert stats.tunnel_pairs == 4 assert stats.dojo_distance == (10, 10, 10, 10) def test_tatami_share_outside_target_is_a_warning(board: Board) -> None: report = validate(board) assert any("Tatami share 84%" in w for w in report.warnings) def test_wall_inside_dojo(quadrant_text: str) -> None: text = edit(quadrant_text, wall_line_above(7), h_segment_column(6), "---") report = validate_text(text) assert "wall inside the Dojo between (6, 6) and (7, 6)" in report.errors def test_dojo_without_entrance(quadrant_text: str) -> None: text = edit(quadrant_text, wall_line_above(6), h_segment_column(7), "---") report = validate_text(text) assert "quadrant 0 has no Dojo entrance" in report.errors def test_safe_room_with_one_exit(quadrant_text: str) -> None: text = edit(quadrant_text, cell_line(1), wall_column_left_of(3), "|") report = validate_text(text) assert "Safe Room of quadrant 0: 1 exits, rules require 2" in report.errors def test_safe_room_exits_on_the_same_side(quadrant_text: str) -> None: text = edit(quadrant_text, cell_line(1), wall_column_left_of(3), "|") text = edit(text, cell_line(0), wall_column_left_of(3), " ") text = edit(text, wall_line_above(3), h_segment_column(1), "---") text = edit(text, cell_line(2), wall_column_left_of(3), " ") report = validate_text(text) assert "Safe Room of quadrant 0: both exits face E" in report.errors def test_safe_room_used_as_a_shortcut(quadrant_text: str) -> None: text = edit(quadrant_text, cell_line(3), wall_column_left_of(2), "|") report = validate_text(text) assert any("Safe Room of quadrant 0: is a shortcut, 4 steps" in e for e in report.errors) def test_safe_room_must_contain_the_corner(quadrant_text: str) -> None: text = edit(quadrant_text, cell_line(0), cell_column(0), ".") report = validate_text(text) assert "Safe Room of quadrant 0: does not contain the board corner (0, 0)" in report.errors assert "Safe Room of quadrant 0: 8 cells, rules expect 9" in report.warnings def test_enclosed_square_is_unreachable(quadrant_text: str) -> None: text = edit(quadrant_text, wall_line_above(4), h_segment_column(5), "---") text = edit(text, wall_line_above(5), h_segment_column(5), "---") text = edit(text, cell_line(4), wall_column_left_of(5), "|") text = edit(text, cell_line(4), wall_column_left_of(6), "|") report = validate_text(text) assert any( e.startswith("4 squares cannot be walked to from the Safe Room of quadrant 0: (4, 5)") for e in report.errors )