Skip to content

Commit 36c2df7

Browse files
yawpitchcmccandless
authored andcommitted
forth: reinstate seperate classes (#2149)
* forth: reinstate seperate classes The template removed seperate classes per major case, resulting in several tests with duplicate names and therefore an incomplete test suite. This reinstates the distinct classes. Fixes #2148 * forth: minor black issue Was accidentally running on a later version of Black than the one specified in our requirements-generator.txt.
1 parent 60cb5a4 commit 36c2df7

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

exercises/forth/.meta/template.j2

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
{%- extends "master_template.j2" -%}
1+
{%- import "generator_macros.j2" as macros with context -%}
22
{% set imports = ["evaluate", "StackUnderflowError"] %}
3+
{{ macros.header(imports=imports, ignore=ignore) }}
34

45
{% macro test_case(case) -%}
56
def test_{{ case["description"] | to_snake }}(self):
@@ -19,3 +20,19 @@
1920
self.assertEqual({{ case["property"] }}({{ case["input"]["instructions"] }}), {{ case["expected"] }})
2021
{%- endif %}
2122
{%- endmacro %}
23+
24+
{%- macro superclass() -%}
25+
{{ exercise | camel_case }}Test
26+
{%- endmacro -%}
27+
28+
class {{ superclass() }}(unittest.TestCase):
29+
{{ macros.utility() }}
30+
31+
{% for case in cases -%}
32+
class {{ case["description"] | camel_case }}Test({{ superclass() }}):
33+
{% for subcase in case["cases"] -%}
34+
{{ test_case(subcase) }}
35+
{% endfor %}
36+
{% endfor %}
37+
38+
{{ macros.footer() }}

exercises/forth/forth_test.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@
66

77

88
class ForthTest(unittest.TestCase):
9+
# Utility functions
10+
def assertRaisesWithMessage(self, exception):
11+
return self.assertRaisesRegex(exception, r".+")
912

10-
# parsing and numbers
1113

14+
class ParsingAndNumbersTest(ForthTest):
1215
def test_numbers_just_get_pushed_onto_the_stack(self):
1316
self.assertEqual(evaluate(["1 2 3 4 5"]), [1, 2, 3, 4, 5])
1417

15-
# addition
1618

19+
class AdditionTest(ForthTest):
1720
def test_can_add_two_numbers(self):
1821
self.assertEqual(evaluate(["1 2 +"]), [3])
1922

@@ -25,8 +28,8 @@ def test_errors_if_there_is_only_one_value_on_the_stack(self):
2528
with self.assertRaisesWithMessage(StackUnderflowError):
2629
evaluate(["1 +"])
2730

28-
# subtraction
2931

32+
class SubtractionTest(ForthTest):
3033
def test_can_subtract_two_numbers(self):
3134
self.assertEqual(evaluate(["3 4 -"]), [-1])
3235

@@ -38,8 +41,8 @@ def test_errors_if_there_is_only_one_value_on_the_stack(self):
3841
with self.assertRaisesWithMessage(StackUnderflowError):
3942
evaluate(["1 -"])
4043

41-
# multiplication
4244

45+
class MultiplicationTest(ForthTest):
4346
def test_can_multiply_two_numbers(self):
4447
self.assertEqual(evaluate(["2 4 *"]), [8])
4548

@@ -51,8 +54,8 @@ def test_errors_if_there_is_only_one_value_on_the_stack(self):
5154
with self.assertRaisesWithMessage(StackUnderflowError):
5255
evaluate(["1 *"])
5356

54-
# division
5557

58+
class DivisionTest(ForthTest):
5659
def test_can_divide_two_numbers(self):
5760
self.assertEqual(evaluate(["12 3 /"]), [4])
5861

@@ -72,16 +75,16 @@ def test_errors_if_there_is_only_one_value_on_the_stack(self):
7275
with self.assertRaisesWithMessage(StackUnderflowError):
7376
evaluate(["1 /"])
7477

75-
# combined arithmetic
7678

79+
class CombinedArithmeticTest(ForthTest):
7780
def test_addition_and_subtraction(self):
7881
self.assertEqual(evaluate(["1 2 + 4 -"]), [-1])
7982

8083
def test_multiplication_and_division(self):
8184
self.assertEqual(evaluate(["2 4 * 3 /"]), [2])
8285

83-
# dup
8486

87+
class DupTest(ForthTest):
8588
def test_copies_a_value_on_the_stack(self):
8689
self.assertEqual(evaluate(["1 dup"]), [1, 1])
8790

@@ -92,8 +95,8 @@ def test_errors_if_there_is_nothing_on_the_stack(self):
9295
with self.assertRaisesWithMessage(StackUnderflowError):
9396
evaluate(["dup"])
9497

95-
# drop
9698

99+
class DropTest(ForthTest):
97100
def test_removes_the_top_value_on_the_stack_if_it_is_the_only_one(self):
98101
self.assertEqual(evaluate(["1 drop"]), [])
99102

@@ -104,8 +107,8 @@ def test_errors_if_there_is_nothing_on_the_stack(self):
104107
with self.assertRaisesWithMessage(StackUnderflowError):
105108
evaluate(["drop"])
106109

107-
# swap
108110

111+
class SwapTest(ForthTest):
109112
def test_swaps_the_top_two_values_on_the_stack_if_they_are_the_only_ones(self):
110113
self.assertEqual(evaluate(["1 2 swap"]), [2, 1])
111114

@@ -120,8 +123,8 @@ def test_errors_if_there_is_only_one_value_on_the_stack(self):
120123
with self.assertRaisesWithMessage(StackUnderflowError):
121124
evaluate(["1 swap"])
122125

123-
# over
124126

127+
class OverTest(ForthTest):
125128
def test_copies_the_second_element_if_there_are_only_two(self):
126129
self.assertEqual(evaluate(["1 2 over"]), [1, 2, 1])
127130

@@ -136,8 +139,8 @@ def test_errors_if_there_is_only_one_value_on_the_stack(self):
136139
with self.assertRaisesWithMessage(StackUnderflowError):
137140
evaluate(["1 over"])
138141

139-
# user-defined words
140142

143+
class UserDefinedWordsTest(ForthTest):
141144
def test_can_consist_of_built_in_words(self):
142145
self.assertEqual(evaluate([": dup-twice dup dup ;", "1 dup-twice"]), [1, 1, 1])
143146

@@ -171,8 +174,8 @@ def test_errors_if_executing_a_non_existent_word(self):
171174
with self.assertRaisesWithMessage(ValueError):
172175
evaluate(["foo"])
173176

174-
# case-insensitivity
175177

178+
class CaseInsensitivityTest(ForthTest):
176179
def test_dup_is_case_insensitive(self):
177180
self.assertEqual(evaluate(["1 DUP Dup dup"]), [1, 1, 1, 1])
178181

0 commit comments

Comments
 (0)