Skip to content
This repository was archived by the owner on Jul 3, 2022. It is now read-only.

Commit f1a9c9f

Browse files
authored
Merge pull request #22 from RoelAdriaans/feature/add-chapter-9-controlflow
Add a few more test cases
2 parents dc04f0d + c1f0930 commit f1a9c9f

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

tests/test_control.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from yaplox.parser import Parser
2+
from yaplox.scanner import Scanner
13
from yaplox.yaplox import Yaplox
24

35

@@ -220,3 +222,99 @@ def test_for_expression_init(self, capsys):
220222
expected_str_output = "\n".join([str(n) for n in range(6)]) + "\n"
221223

222224
assert captured.out == expected_str_output
225+
226+
def test_for_parser(self, mocker):
227+
""" Test that we parse the for loop correctly """
228+
229+
source = "for(var a = 0; ; a = a + 1) {}"
230+
231+
on_scanner_error_mock = mocker.MagicMock()
232+
on_parser_error_mock = mocker.MagicMock()
233+
234+
scanner = Scanner(source, on_error=on_scanner_error_mock)
235+
tokens = scanner.scan_tokens()
236+
parser = Parser(tokens, on_token_error=on_parser_error_mock)
237+
statements = parser.parse()
238+
239+
assert statements
240+
# Because the condition is missing, it must alway be true:
241+
assert statements[0].statements[1].condition.value is True
242+
243+
assert not on_scanner_error_mock.called
244+
assert not on_parser_error_mock.called
245+
246+
def test_for_invalid_for_loop_parser(self, mocker):
247+
""" Test that we parse the for loop correctly """
248+
249+
source = "for (var a = 0; a <= 5; a = a + 1) {}"
250+
left_missing = source.replace("(", "")
251+
right_missing = source.replace(")", "")
252+
253+
on_scanner_error_mock = mocker.MagicMock()
254+
on_parser_error_mock = mocker.MagicMock()
255+
256+
scanner = Scanner(source, on_error=on_scanner_error_mock)
257+
tokens = scanner.scan_tokens()
258+
parser = Parser(tokens, on_token_error=on_parser_error_mock)
259+
statements = parser.parse()
260+
261+
assert statements
262+
assert not on_scanner_error_mock.called
263+
assert not on_parser_error_mock.called
264+
265+
# Test a invalid statement, missing (
266+
on_scanner_error_mock = mocker.MagicMock()
267+
on_parser_error_mock = mocker.MagicMock()
268+
scanner = Scanner(left_missing, on_error=on_scanner_error_mock)
269+
tokens = scanner.scan_tokens()
270+
parser = Parser(tokens, on_token_error=on_parser_error_mock)
271+
parser.parse()
272+
273+
assert not on_scanner_error_mock.called
274+
assert on_parser_error_mock.called
275+
assert "Expect '(' after 'for'" in str(on_parser_error_mock.call_args_list[0])
276+
277+
# Test a invalid statement, missing )
278+
on_scanner_error_mock = mocker.MagicMock()
279+
on_parser_error_mock = mocker.MagicMock()
280+
scanner = Scanner(right_missing, on_error=on_scanner_error_mock)
281+
tokens = scanner.scan_tokens()
282+
parser = Parser(tokens, on_token_error=on_parser_error_mock)
283+
parser.parse()
284+
285+
assert not on_scanner_error_mock.called
286+
assert on_parser_error_mock.called
287+
assert "Expect ')' after for clauses" in str(
288+
on_parser_error_mock.call_args_list[0]
289+
)
290+
291+
def test_for_missing_increment(self, capsys):
292+
""" Missing increment should still work """
293+
source = [
294+
"for(var a = 0; a <= 5;) {",
295+
" print a;",
296+
" a = a + 1;" "}",
297+
]
298+
source = "\n".join(source)
299+
yaplox = Yaplox()
300+
yaplox.run(source)
301+
302+
assert not yaplox.had_error
303+
assert not yaplox.had_runtime_error
304+
305+
captured = capsys.readouterr()
306+
expected_str_output = "\n".join([str(n) for n in range(6)]) + "\n"
307+
308+
assert captured.out == expected_str_output
309+
310+
# But the trailing ; must be present
311+
source = source.replace("5;)", "5)")
312+
yaplox = Yaplox()
313+
yaplox.run(source)
314+
315+
assert yaplox.had_error
316+
assert not yaplox.had_runtime_error
317+
318+
captured = capsys.readouterr()
319+
320+
assert "Expect ';' after loop condition." in captured.err

0 commit comments

Comments
 (0)