Skip to content

Commit 4180f24

Browse files
dvermdyawpitch
authored andcommitted
forth: add test template (exercism#2115)
* forth: add test template Resolves: exercism#1949 * forth: restore Exception diversity (exercism#1949)
1 parent 355336d commit 4180f24

File tree

2 files changed

+99
-178
lines changed

2 files changed

+99
-178
lines changed

‎exercises/forth/.meta/template.j2‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{%- extends"master_template.j2" -%}
2+
{%setimports = ["evaluate", "StackUnderflowError"] %}
3+
4+
{%macrotest_case(case) -%}
5+
def test_{{case["description"] | to_snake }}(self):
6+
{%- ifcaseiserror_case%}
7+
{%- ifcase["expected"]["error"] == "divide by zero"%}
8+
#{{case["expected"]["error"] }}
9+
with self.assertRaisesWithMessage(ZeroDivisionError):
10+
{%- else%}
11+
{%- if"stack"incase["expected"]["error"] %}
12+
with self.assertRaisesWithMessage(StackUnderflowError):
13+
{%- else%}
14+
with self.assertRaisesWithMessage(ValueError):
15+
{%- endif%}
16+
{%- endif%}
17+
{{case["property"] }}({{case["input"]["instructions"] }})
18+
{%- else%}
19+
self.assertEqual({{case["property"] }}({{case["input"]["instructions"] }}),{{case["expected"] }})
20+
{%- endif%}
21+
{%- endmacro%}

‎exercises/forth/forth_test.py‎

Lines changed: 78 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -2,299 +2,199 @@
22

33
fromforthimportevaluate, StackUnderflowError
44

5-
65
# Tests adapted from `problem-specifications//canonical-data.json` @ v1.7.1
76

8-
classForthUtilities(unittest.TestCase):
9-
# Utility functions
10-
defassertRaisesWithMessage(self, exception):
11-
returnself.assertRaisesRegex(exception, r".+")
127

8+
classForthTest(unittest.TestCase):
9+
10+
# parsing and numbers
1311

14-
classForthParsingTest(ForthUtilities):
15-
deftest_numbers_just_get_pushed_to_stack(self):
16-
input_data= ["1 2 3 4 5"]
17-
expected= [1, 2, 3, 4, 5]
18-
self.assertEqual(evaluate(input_data), expected)
12+
deftest_numbers_just_get_pushed_onto_the_stack(self):
13+
self.assertEqual(evaluate(["1 2 3 4 5"]), [1, 2, 3, 4, 5])
1914

15+
# addition
2016

21-
classForthAdditionTest(ForthUtilities):
2217
deftest_can_add_two_numbers(self):
23-
input_data= ["1 2 +"]
24-
expected= [3]
25-
self.assertEqual(evaluate(input_data), expected)
18+
self.assertEqual(evaluate(["1 2 +"]), [3])
2619

2720
deftest_errors_if_there_is_nothing_on_the_stack(self):
28-
input_data= ["+"]
2921
withself.assertRaisesWithMessage(StackUnderflowError):
30-
evaluate(input_data)
22+
evaluate(["+"])
3123

3224
deftest_errors_if_there_is_only_one_value_on_the_stack(self):
33-
input_data= ["1 +"]
3425
withself.assertRaisesWithMessage(StackUnderflowError):
35-
evaluate(input_data)
26+
evaluate(["1 +"])
3627

28+
# subtraction
3729

38-
classForthSubtractionTest(ForthUtilities):
3930
deftest_can_subtract_two_numbers(self):
40-
input_data= ["3 4 -"]
41-
expected= [-1]
42-
self.assertEqual(evaluate(input_data), expected)
31+
self.assertEqual(evaluate(["3 4 -"]), [-1])
4332

4433
deftest_errors_if_there_is_nothing_on_the_stack(self):
45-
input_data= ["-"]
4634
withself.assertRaisesWithMessage(StackUnderflowError):
47-
evaluate(input_data)
35+
evaluate(["-"])
4836

4937
deftest_errors_if_there_is_only_one_value_on_the_stack(self):
50-
input_data= ["1 -"]
5138
withself.assertRaisesWithMessage(StackUnderflowError):
52-
evaluate(input_data)
39+
evaluate(["1 -"])
5340

41+
# multiplication
5442

55-
classForthMultiplicationTest(ForthUtilities):
5643
deftest_can_multiply_two_numbers(self):
57-
input_data= ["2 4 *"]
58-
expected= [8]
59-
self.assertEqual(evaluate(input_data), expected)
44+
self.assertEqual(evaluate(["2 4 *"]), [8])
6045

6146
deftest_errors_if_there_is_nothing_on_the_stack(self):
62-
input_data= ["*"]
6347
withself.assertRaisesWithMessage(StackUnderflowError):
64-
evaluate(input_data)
48+
evaluate(["*"])
6549

6650
deftest_errors_if_there_is_only_one_value_on_the_stack(self):
67-
input_data= ["1 *"]
6851
withself.assertRaisesWithMessage(StackUnderflowError):
69-
evaluate(input_data)
52+
evaluate(["1 *"])
7053

54+
# division
7155

72-
classForthDivisionTest(ForthUtilities):
7356
deftest_can_divide_two_numbers(self):
74-
input_data= ["12 3 /"]
75-
expected= [4]
76-
self.assertEqual(evaluate(input_data), expected)
57+
self.assertEqual(evaluate(["12 3 /"]), [4])
7758

7859
deftest_performs_integer_division(self):
79-
input_data= ["8 3 /"]
80-
expected= [2]
81-
self.assertEqual(evaluate(input_data), expected)
60+
self.assertEqual(evaluate(["8 3 /"]), [2])
8261

8362
deftest_errors_if_dividing_by_zero(self):
84-
input_data= ["4 0 /"]
63+
# divide by zero
8564
withself.assertRaisesWithMessage(ZeroDivisionError):
86-
evaluate(input_data)
65+
evaluate(["4 0 /"])
8766

8867
deftest_errors_if_there_is_nothing_on_the_stack(self):
89-
input_data= ["/"]
9068
withself.assertRaisesWithMessage(StackUnderflowError):
91-
evaluate(input_data)
69+
evaluate(["/"])
9270

9371
deftest_errors_if_there_is_only_one_value_on_the_stack(self):
94-
input_data= ["1 /"]
9572
withself.assertRaisesWithMessage(StackUnderflowError):
96-
evaluate(input_data)
73+
evaluate(["1 /"])
9774

75+
# combined arithmetic
9876

99-
classForthCombinedArithmeticTest(ForthUtilities):
10077
deftest_addition_and_subtraction(self):
101-
input_data= ["1 2 + 4 -"]
102-
expected= [-1]
103-
self.assertEqual(evaluate(input_data), expected)
78+
self.assertEqual(evaluate(["1 2 + 4 -"]), [-1])
10479

10580
deftest_multiplication_and_division(self):
106-
input_data= ["2 4 * 3 /"]
107-
expected= [2]
108-
self.assertEqual(evaluate(input_data), expected)
81+
self.assertEqual(evaluate(["2 4 * 3 /"]), [2])
10982

83+
# dup
11084

111-
classForthDupTest(ForthUtilities):
11285
deftest_copies_a_value_on_the_stack(self):
113-
input_data= ["1 dup"]
114-
expected= [1, 1]
115-
self.assertEqual(evaluate(input_data), expected)
86+
self.assertEqual(evaluate(["1 dup"]), [1, 1])
11687

11788
deftest_copies_the_top_value_on_the_stack(self):
118-
input_data= ["1 2 dup"]
119-
expected= [1, 2, 2]
120-
self.assertEqual(evaluate(input_data), expected)
89+
self.assertEqual(evaluate(["1 2 dup"]), [1, 2, 2])
12190

12291
deftest_errors_if_there_is_nothing_on_the_stack(self):
123-
input_data= ["dup"]
12492
withself.assertRaisesWithMessage(StackUnderflowError):
125-
evaluate(input_data)
93+
evaluate(["dup"])
12694

95+
# drop
12796

128-
classForthDropTest(ForthUtilities):
12997
deftest_removes_the_top_value_on_the_stack_if_it_is_the_only_one(self):
130-
input_data= ["1 drop"]
131-
expected= []
132-
self.assertEqual(evaluate(input_data), expected)
98+
self.assertEqual(evaluate(["1 drop"]), [])
13399

134-
deftest_removes_the_top_value_on_the_stack_if_it_not_the_only_one(self):
135-
input_data= ["3 4 drop"]
136-
expected= [3]
137-
self.assertEqual(evaluate(input_data), expected)
100+
deftest_removes_the_top_value_on_the_stack_if_it_is_not_the_only_one(self):
101+
self.assertEqual(evaluate(["1 2 drop"]), [1])
138102

139103
deftest_errors_if_there_is_nothing_on_the_stack(self):
140-
input_data= ["drop"]
141104
withself.assertRaisesWithMessage(StackUnderflowError):
142-
evaluate(input_data)
105+
evaluate(["drop"])
143106

107+
# swap
144108

145-
classForthSwapTest(ForthUtilities):
146-
deftest_swaps_only_two_values_on_stack(self):
147-
input_data= ["1 2 swap"]
148-
expected= [2, 1]
149-
self.assertEqual(evaluate(input_data), expected)
109+
deftest_swaps_the_top_two_values_on_the_stack_if_they_are_the_only_ones(self):
110+
self.assertEqual(evaluate(["1 2 swap"]), [2, 1])
150111

151-
deftest_swaps_two_two_values_on_stack(self):
152-
input_data= ["1 2 3 swap"]
153-
expected= [1, 3, 2]
154-
self.assertEqual(evaluate(input_data), expected)
112+
deftest_swaps_the_top_two_values_on_the_stack_if_they_are_not_the_only_ones(self):
113+
self.assertEqual(evaluate(["1 2 3 swap"]), [1, 3, 2])
155114

156115
deftest_errors_if_there_is_nothing_on_the_stack(self):
157-
input_data= ["swap"]
158116
withself.assertRaisesWithMessage(StackUnderflowError):
159-
evaluate(input_data)
117+
evaluate(["swap"])
160118

161119
deftest_errors_if_there_is_only_one_value_on_the_stack(self):
162-
input_data= ["1 swap"]
163120
withself.assertRaisesWithMessage(StackUnderflowError):
164-
evaluate(input_data)
121+
evaluate(["1 swap"])
165122

123+
# over
166124

167-
classForthOverTest(ForthUtilities):
168125
deftest_copies_the_second_element_if_there_are_only_two(self):
169-
input_data= ["1 2 over"]
170-
expected= [1, 2, 1]
171-
self.assertEqual(evaluate(input_data), expected)
126+
self.assertEqual(evaluate(["1 2 over"]), [1, 2, 1])
172127

173128
deftest_copies_the_second_element_if_there_are_more_than_two(self):
174-
input_data= ["1 2 3 over"]
175-
expected= [1, 2, 3, 2]
176-
self.assertEqual(evaluate(input_data), expected)
129+
self.assertEqual(evaluate(["1 2 3 over"]), [1, 2, 3, 2])
177130

178131
deftest_errors_if_there_is_nothing_on_the_stack(self):
179-
input_data= ["over"]
180132
withself.assertRaisesWithMessage(StackUnderflowError):
181-
evaluate(input_data)
133+
evaluate(["over"])
182134

183135
deftest_errors_if_there_is_only_one_value_on_the_stack(self):
184-
input_data= ["1 over"]
185136
withself.assertRaisesWithMessage(StackUnderflowError):
186-
evaluate(input_data)
137+
evaluate(["1 over"])
187138

139+
# user-defined words
188140

189-
classForthUserDefinedWordsTest(ForthUtilities):
190141
deftest_can_consist_of_built_in_words(self):
191-
input_data= [
192-
": dup-twice dup dup ;",
193-
"1 dup-twice"
194-
]
195-
expected= [1, 1, 1]
196-
self.assertEqual(evaluate(input_data), expected)
142+
self.assertEqual(evaluate([": dup-twice dup dup ;", "1 dup-twice"]), [1, 1, 1])
197143

198144
deftest_execute_in_the_right_order(self):
199-
input_data= [
200-
": countup 1 2 3 ;",
201-
"countup"
202-
]
203-
expected= [1, 2, 3]
204-
self.assertEqual(evaluate(input_data), expected)
145+
self.assertEqual(evaluate([": countup 1 2 3 ;", "countup"]), [1, 2, 3])
205146

206147
deftest_can_override_other_user_defined_words(self):
207-
input_data= [
208-
": foo dup ;",
209-
": foo dup dup ;",
210-
"1 foo"
211-
]
212-
expected= [1, 1, 1]
213-
self.assertEqual(evaluate(input_data), expected)
148+
self.assertEqual(
149+
evaluate([": foo dup ;", ": foo dup dup ;", "1 foo"]), [1, 1, 1]
150+
)
214151

215152
deftest_can_override_built_in_words(self):
216-
input_data= [
217-
": swap dup ;",
218-
"1 swap"
219-
]
220-
expected= [1, 1]
221-
self.assertEqual(evaluate(input_data), expected)
153+
self.assertEqual(evaluate([": swap dup ;", "1 swap"]), [1, 1])
222154

223155
deftest_can_override_built_in_operators(self):
224-
input_data= [
225-
": + * ;",
226-
"3 4 +"
227-
]
228-
expected= [12]
229-
self.assertEqual(evaluate(input_data), expected)
230-
231-
deftest_can_use_different_words_with_same_name(self):
232-
input_data= [
233-
": foo 5 ;",
234-
": bar foo ;",
235-
": foo 6 ;",
236-
"bar foo"
237-
]
238-
expected= [5, 6]
239-
self.assertEqual(evaluate(input_data), expected)
240-
241-
deftest_can_define_word_that_uses_word_with_same_name(self):
242-
input_data= [
243-
": foo 10 ;",
244-
": foo foo 1 + ;",
245-
"foo"
246-
]
247-
expected= [11]
248-
self.assertEqual(evaluate(input_data), expected)
156+
self.assertEqual(evaluate([": + * ;", "3 4 +"]), [12])
157+
158+
deftest_can_use_different_words_with_the_same_name(self):
159+
self.assertEqual(
160+
evaluate([": foo 5 ;", ": bar foo ;", ": foo 6 ;", "bar foo"]), [5, 6]
161+
)
162+
163+
deftest_can_define_word_that_uses_word_with_the_same_name(self):
164+
self.assertEqual(evaluate([": foo 10 ;", ": foo foo 1 + ;", "foo"]), [11])
249165

250166
deftest_cannot_redefine_numbers(self):
251-
input_data= [": 1 2 ;"]
252167
withself.assertRaisesWithMessage(ValueError):
253-
evaluate(input_data)
168+
evaluate([": 1 2 ;"])
254169

255170
deftest_errors_if_executing_a_non_existent_word(self):
256-
input_data= ["foo"]
257171
withself.assertRaisesWithMessage(ValueError):
258-
evaluate(input_data)
172+
evaluate(["foo"])
259173

174+
# case-insensitivity
260175

261-
classForthCaseInsensitivityTest(ForthUtilities):
262176
deftest_dup_is_case_insensitive(self):
263-
input_data= ["1 DUP Dup dup"]
264-
expected= [1, 1, 1, 1]
265-
self.assertEqual(evaluate(input_data), expected)
177+
self.assertEqual(evaluate(["1 DUP Dup dup"]), [1, 1, 1, 1])
266178

267179
deftest_drop_is_case_insensitive(self):
268-
input_data= ["1 2 3 4 DROP Drop drop"]
269-
expected= [1]
270-
self.assertEqual(evaluate(input_data), expected)
180+
self.assertEqual(evaluate(["1 2 3 4 DROP Drop drop"]), [1])
271181

272182
deftest_swap_is_case_insensitive(self):
273-
input_data= ["1 2 SWAP 3 Swap 4 swap"]
274-
expected= [2, 3, 4, 1]
275-
self.assertEqual(evaluate(input_data), expected)
183+
self.assertEqual(evaluate(["1 2 SWAP 3 Swap 4 swap"]), [2, 3, 4, 1])
276184

277185
deftest_over_is_case_insensitive(self):
278-
input_data= ["1 2 OVER Over over"]
279-
expected= [1, 2, 1, 2, 1]
280-
self.assertEqual(evaluate(input_data), expected)
186+
self.assertEqual(evaluate(["1 2 OVER Over over"]), [1, 2, 1, 2, 1])
281187

282188
deftest_user_defined_words_are_case_insensitive(self):
283-
input_data= [
284-
": foo dup ;",
285-
"1 FOO Foo foo"
286-
]
287-
expected= [1, 1, 1, 1]
288-
self.assertEqual(evaluate(input_data), expected)
189+
self.assertEqual(evaluate([": foo dup ;", "1 FOO Foo foo"]), [1, 1, 1, 1])
289190

290191
deftest_definitions_are_case_insensitive(self):
291-
input_data= [
292-
": SWAP DUP Dup dup ;",
293-
"1 swap"
294-
]
295-
expected= [1, 1, 1, 1]
296-
self.assertEqual(evaluate(input_data), expected)
192+
self.assertEqual(evaluate([": SWAP DUP Dup dup ;", "1 swap"]), [1, 1, 1, 1])
193+
194+
# Utility functions
195+
defassertRaisesWithMessage(self, exception):
196+
returnself.assertRaisesRegex(exception, r".+")
297197

298198

299-
if__name__=='__main__':
199+
if__name__=="__main__":
300200
unittest.main()

0 commit comments

Comments
(0)