From bf83d7689aa4647f130ceca1867a5440da50da86 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Mon, 1 Nov 2021 11:39:06 -0700 Subject: [PATCH] Added error handling instruction append, added additional test cases, corrected JinJa2 template, and regenerated test cases. --- .../minesweeper/.docs/instructions.append.md | 18 +++++++++++++---- .../minesweeper/.meta/additional_tests.json | 4 ++-- .../practice/minesweeper/.meta/example.py | 6 +++--- .../practice/minesweeper/.meta/template.j2 | 5 +++-- .../practice/minesweeper/minesweeper_test.py | 20 +++++++++---------- 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/exercises/practice/minesweeper/.docs/instructions.append.md b/exercises/practice/minesweeper/.docs/instructions.append.md index dba03984..2e20d976 100644 --- a/exercises/practice/minesweeper/.docs/instructions.append.md +++ b/exercises/practice/minesweeper/.docs/instructions.append.md @@ -1,4 +1,14 @@ -# Implementation Notes -The board function must validate its input and raise a -ValueError with a *meaningful* error message if the -input turns out to be malformed. +# Instructions append + +## Exception messages + +Sometimes it is necessary to [raise an exception](https://docs.python.org/3/tutorial/errors.html#raising-exceptions). When you do this, you should always include a **meaningful error message** to indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. For situations where you know that the error source will be a certain type, you can choose to raise one of the [built in error types](https://docs.python.org/3/library/exceptions.html#base-classes), but should still include a meaningful message. + +This particular exercise requires that you use the [raise statement](https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement) to "throw" a `ValueError` when the `board()` function receives malformed input. The tests will only pass if you both `raise` the `exception` and include a message with it. + +To raise a `ValueError` with a message, write the message as an argument to the `exception` type: + +```python +# when the board receives malformed input +raise ValueError("The board is invalid with current input.") +``` diff --git a/exercises/practice/minesweeper/.meta/additional_tests.json b/exercises/practice/minesweeper/.meta/additional_tests.json index d0ca71eb..84e7e53f 100644 --- a/exercises/practice/minesweeper/.meta/additional_tests.json +++ b/exercises/practice/minesweeper/.meta/additional_tests.json @@ -38,7 +38,7 @@ " " ] }, - "expected": {"error": "The minefield must have a consistent length"} + "expected": {"error": "The board is invalid with current input."} }, { "description": "invalid char", @@ -46,7 +46,7 @@ "input": { "minefield": ["X * "] }, - "expected": {"error": "The minefield contains an invalid character"} + "expected": {"error": "The board is invalid with current input."} } ] diff --git a/exercises/practice/minesweeper/.meta/example.py b/exercises/practice/minesweeper/.meta/example.py index a8f558f3..53ff051b 100644 --- a/exercises/practice/minesweeper/.meta/example.py +++ b/exercises/practice/minesweeper/.meta/example.py @@ -1,5 +1,5 @@ def annotate(minefield): - if(minefield == []): + if not minefield: return [] verify_board(minefield) row_len = len(minefield[0]) @@ -30,11 +30,11 @@ def verify_board(minefield): # Rows with different lengths row_len = len(minefield[0]) if not all(len(row) == row_len for row in minefield): - raise ValueError("Invalid board") + raise ValueError("The board is invalid with current input.") # Unknown character in board character_set = set() for row in minefield: character_set.update(row) if character_set - set(' *'): - raise ValueError("Invalid board") + raise ValueError("The board is invalid with current input.") diff --git a/exercises/practice/minesweeper/.meta/template.j2 b/exercises/practice/minesweeper/.meta/template.j2 index 52014f0d..b34be795 100644 --- a/exercises/practice/minesweeper/.meta/template.j2 +++ b/exercises/practice/minesweeper/.meta/template.j2 @@ -14,10 +14,11 @@ class {{ exercise | camel_case }}Test(unittest.TestCase): {% for case in additional_cases -%} def test_{{ case["description"] | to_snake }}(self): {%- if case is error_case %} - with self.assertRaisesWithMessage(ValueError): + with self.assertRaises(ValueError) as err: {{ test_call(case) }} + self.assertEqual(type(err.exception), ValueError) + self.assertEqual(err.exception.args[0], "{{ case["expected"]["error"] }}") {%- else %} self.assertEqual({{- test_call(case) }}, {{ case["expected"] }}) {%- endif %} {% endfor %} -{{ macros.footer(True) }} diff --git a/exercises/practice/minesweeper/minesweeper_test.py b/exercises/practice/minesweeper/minesweeper_test.py index 3da8ef15..d5e6b78b 100644 --- a/exercises/practice/minesweeper/minesweeper_test.py +++ b/exercises/practice/minesweeper/minesweeper_test.py @@ -58,17 +58,17 @@ class MinesweeperTest(unittest.TestCase): ) def test_different_len(self): - with self.assertRaisesWithMessage(ValueError): + with self.assertRaises(ValueError) as err: annotate([" ", "* ", " "]) + self.assertEqual(type(err.exception), ValueError) + self.assertEqual( + err.exception.args[0], "The board is invalid with current input." + ) def test_invalid_char(self): - with self.assertRaisesWithMessage(ValueError): + with self.assertRaises(ValueError) as err: annotate(["X * "]) - - # Utility functions - def assertRaisesWithMessage(self, exception): - return self.assertRaisesRegex(exception, r".+") - - -if __name__ == "__main__": - unittest.main() + self.assertEqual(type(err.exception), ValueError) + self.assertEqual( + err.exception.args[0], "The board is invalid with current input." + )