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

Commit

Permalink
Merge pull request #22 from RoelAdriaans/feature/add-chapter-9-contro…
Browse files Browse the repository at this point in the history
…lflow

Add a few more test cases
  • Loading branch information
RoelAdriaans authored Sep 5, 2020
2 parents dc04f0d + c1f0930 commit f1a9c9f
Showing 1 changed file with 98 additions and 0 deletions.
98 changes: 98 additions & 0 deletions tests/test_control.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from yaplox.parser import Parser
from yaplox.scanner import Scanner
from yaplox.yaplox import Yaplox


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

assert captured.out == expected_str_output

def test_for_parser(self, mocker):
""" Test that we parse the for loop correctly """

source = "for(var a = 0; ; a = a + 1) {}"

on_scanner_error_mock = mocker.MagicMock()
on_parser_error_mock = mocker.MagicMock()

scanner = Scanner(source, on_error=on_scanner_error_mock)
tokens = scanner.scan_tokens()
parser = Parser(tokens, on_token_error=on_parser_error_mock)
statements = parser.parse()

assert statements
# Because the condition is missing, it must alway be true:
assert statements[0].statements[1].condition.value is True

assert not on_scanner_error_mock.called
assert not on_parser_error_mock.called

def test_for_invalid_for_loop_parser(self, mocker):
""" Test that we parse the for loop correctly """

source = "for (var a = 0; a <= 5; a = a + 1) {}"
left_missing = source.replace("(", "")
right_missing = source.replace(")", "")

on_scanner_error_mock = mocker.MagicMock()
on_parser_error_mock = mocker.MagicMock()

scanner = Scanner(source, on_error=on_scanner_error_mock)
tokens = scanner.scan_tokens()
parser = Parser(tokens, on_token_error=on_parser_error_mock)
statements = parser.parse()

assert statements
assert not on_scanner_error_mock.called
assert not on_parser_error_mock.called

# Test a invalid statement, missing (
on_scanner_error_mock = mocker.MagicMock()
on_parser_error_mock = mocker.MagicMock()
scanner = Scanner(left_missing, on_error=on_scanner_error_mock)
tokens = scanner.scan_tokens()
parser = Parser(tokens, on_token_error=on_parser_error_mock)
parser.parse()

assert not on_scanner_error_mock.called
assert on_parser_error_mock.called
assert "Expect '(' after 'for'" in str(on_parser_error_mock.call_args_list[0])

# Test a invalid statement, missing )
on_scanner_error_mock = mocker.MagicMock()
on_parser_error_mock = mocker.MagicMock()
scanner = Scanner(right_missing, on_error=on_scanner_error_mock)
tokens = scanner.scan_tokens()
parser = Parser(tokens, on_token_error=on_parser_error_mock)
parser.parse()

assert not on_scanner_error_mock.called
assert on_parser_error_mock.called
assert "Expect ')' after for clauses" in str(
on_parser_error_mock.call_args_list[0]
)

def test_for_missing_increment(self, capsys):
""" Missing increment should still work """
source = [
"for(var a = 0; a <= 5;) {",
" print a;",
" a = a + 1;" "}",
]
source = "\n".join(source)
yaplox = Yaplox()
yaplox.run(source)

assert not yaplox.had_error
assert not yaplox.had_runtime_error

captured = capsys.readouterr()
expected_str_output = "\n".join([str(n) for n in range(6)]) + "\n"

assert captured.out == expected_str_output

# But the trailing ; must be present
source = source.replace("5;)", "5)")
yaplox = Yaplox()
yaplox.run(source)

assert yaplox.had_error
assert not yaplox.had_runtime_error

captured = capsys.readouterr()

assert "Expect ';' after loop condition." in captured.err

0 comments on commit f1a9c9f

Please sign in to comment.