diff --git a/calculator/calculator.py b/calculator/calculator.py index a45531eb9cb9f91282b16c38b3ce0f7007c95065..980a8c3bdd300276486a5fa34574fddaf755b9b3 100644 --- a/calculator/calculator.py +++ b/calculator/calculator.py @@ -1,7 +1,6 @@ """ This Calculator holds the logic for the calculator. """ -import pytest from calculator.operators import Operator, STANDARD_OPERATORS from calculator.expression import Token, Term, Expression, TermExpression, OperatorExpression @@ -65,55 +64,3 @@ class Calculator: def __call__(self, expression: str) -> Term: return self.parse(self.tokenize(expression))() - - -@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 diff --git a/calculator/expression.py b/calculator/expression.py index a4106d02598ee724f931d166a077d688154fbec0..b46f44a5679497951ea41da432b93ae63476f952 100644 --- a/calculator/expression.py +++ b/calculator/expression.py @@ -42,37 +42,3 @@ class TermExpression: Expression: type = Union[OperatorExpression, TermExpression] - - -def test_single_term(): - """ - Test the TermExpression class. - """ - expression = TermExpression(42) - assert repr(expression) == '42' - assert expression() == 42 - - -def test_single_operator(): - """ - Test the OperatorExpression class. - """ - add = Operator('+', 1, lambda a, b: a + b) - expression = OperatorExpression(add, TermExpression(1), TermExpression(2)) - assert repr(expression) == '(1 + 2)' - assert expression() == 3 - - -def test_complex_expression(): - """ - Test a complex expression. - """ - add = Operator('+', 1, lambda a, b: a + b) - multiply = Operator('*', 2, lambda a, b: a * b) - expression = OperatorExpression( - multiply, - OperatorExpression(add, TermExpression(1), TermExpression(2)), - TermExpression(3) - ) - assert repr(expression) == '((1 + 2) * 3)' - assert expression() == 9 diff --git a/calculator/operators.py b/calculator/operators.py index 0e995ca10269611afd4276142e16e7f5ab4f6daf..8da0d85ed561f26108755cd1b3709280f3cee336 100644 --- a/calculator/operators.py +++ b/calculator/operators.py @@ -1,8 +1,6 @@ """ Operator module contains the Operator class and a list of standard operators. """ - - class Operator: """ Operator class is a binary operator with a symbol, a precedence and an evaluation function. @@ -26,11 +24,3 @@ STANDARD_OPERATORS = { '*': Operator('×', 2, lambda a, b: a * b), '/': Operator('/', 2, lambda a, b: a / b), } - -def test_operator(): - """ - Test the Operator class. - """ - modulo = Operator('%', 1, lambda a, b: a % b) - assert repr(modulo) == '%' - assert modulo(15, 4) == 3 diff --git a/calculator/test_calculator.py b/calculator/test_calculator.py new file mode 100644 index 0000000000000000000000000000000000000000..8f56766743df0446d2c72f771e16724486b7fd80 --- /dev/null +++ b/calculator/test_calculator.py @@ -0,0 +1,58 @@ +""" +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 diff --git a/calculator/test_expression.py b/calculator/test_expression.py new file mode 100644 index 0000000000000000000000000000000000000000..04b96836310d4575f45fb97872e954b0bc1a186f --- /dev/null +++ b/calculator/test_expression.py @@ -0,0 +1,38 @@ +""" +Test module for expression module. +""" +from calculator.expression import TermExpression, OperatorExpression +from calculator.operators import Operator + +def test_single_term(): + """ + Test the TermExpression class. + """ + expression = TermExpression(42) + assert repr(expression) == '42' + assert expression() == 42 + + +def test_single_operator(): + """ + Test the OperatorExpression class. + """ + add = Operator('+', 1, lambda a, b: a + b) + expression = OperatorExpression(add, TermExpression(1), TermExpression(2)) + assert repr(expression) == '(1 + 2)' + assert expression() == 3 + + +def test_complex_expression(): + """ + Test a complex expression. + """ + add = Operator('+', 1, lambda a, b: a + b) + multiply = Operator('*', 2, lambda a, b: a * b) + expression = OperatorExpression( + multiply, + OperatorExpression(add, TermExpression(1), TermExpression(2)), + TermExpression(3) + ) + assert repr(expression) == '((1 + 2) * 3)' + assert expression() == 9 diff --git a/calculator/test_operators.py b/calculator/test_operators.py new file mode 100644 index 0000000000000000000000000000000000000000..657a7219e9de7d7a04f79209f12bb40ae8268bcb --- /dev/null +++ b/calculator/test_operators.py @@ -0,0 +1,13 @@ +""" +Test module for the operator module. +""" +from calculator.operators import Operator + + +def test_operator(): + """ + Test the Operator class. + """ + modulo = Operator('%', 1, lambda a, b: a % b) + assert repr(modulo) == '%' + assert modulo(15, 4) == 3