""" Test module for the calculator module. """ import pytest from calculator.calculator import Calculator from calculator.operators import Operator @pytest.fixture(scope="module", name="setup") def fixture_setup(): """ Setup the test suite, by instantiating the calculator and the operators. """ plus = Operator('+', 1, lambda a, b: a + b) minus = Operator('-', 1, lambda a, b: a - b) times = Operator('*', 2, lambda a, b: a * b) divide = Operator('/', 2, lambda a, b: a / b) calculator = Calculator( operators={'+': plus, '-': minus, '*': times, '/': divide}) yield plus, minus, times, divide, calculator def test_tokenizer(setup): """ Test the tokenizer. """ plus, minus, times, divide, calc = setup assert calc.tokenize("1 + 2") == [1.0, plus, 2.0] assert calc.tokenize("1 + 2 * 3") == [1.0, plus, 2.0, times, 3.0] assert calc.tokenize( "1 + 2 * 3 / 4") == [1.0, plus, 2.0, times, 3.0, divide, 4.0] assert calc.tokenize( "1 + 2 * 3 / 4 - 5") == [1.0, plus, 2.0, times, 3.0, divide, 4.0, minus, 5.0] def test_parser(setup): """ Test the parser. """ _, _, _, _, calc = setup assert repr(calc.parse(calc.tokenize("1 + 2"))) == '(1.0 + 2.0)' assert repr(calc.parse(calc.tokenize("1 + 2 * 3")) ) == '(1.0 + (2.0 * 3.0))' assert repr(calc.parse(calc.tokenize( "1 + 2 * 3 / 4"))) == '(1.0 + ((2.0 * 3.0) / 4.0))' assert repr(calc.parse(calc.tokenize( "1 + 2 * 3 / 4 - 5"))) == '((1.0 + ((2.0 * 3.0) / 4.0)) - 5.0)' def test_evaluation(setup): """ Test the evaluation. """ _, _, _, _, calc = setup assert calc("1 + 2") == 3 assert calc("1 + 2 * 3") == 7 assert calc("1 + 2 * 3 / 4") == 2.5 assert calc("1 + 2 * 3 / 4 - 5") == -2.5