75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
import pytest
|
|
import sys
|
|
import os
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
from slic.utils.eval import *
|
|
|
|
# Valid expressions
|
|
@pytest.mark.parametrize("expr, expected", [
|
|
("1 + 2", 3),
|
|
("4 - 2", 2),
|
|
("3 * 5", 15),
|
|
("10 / 2", 5.0),
|
|
("10 % 3", 1),
|
|
("-5", -5),
|
|
("+7", 7),
|
|
("1 + 2 * 3", 7),
|
|
("(1 + 2) * 3", 9),
|
|
("-(-3)", 3),
|
|
("-2 + 4 * 2", 6),
|
|
("(4 + 5) * (6 - 1)", 45),
|
|
("(((3)))", 3),
|
|
("-(-(-2))", -2),
|
|
("3 + +4", 7),
|
|
("3 + -4", -1),
|
|
("True + 1", 2),
|
|
("string", "string"),
|
|
("1e1000 * 1e1000", inf),
|
|
("'a' + 'b'", "ab") # string concatenation supported !!!
|
|
])
|
|
def test_arithmetic_eval_valid(expr, expected):
|
|
assert arithmetic_eval(expr) == expected
|
|
|
|
# Expressions with unsupported operations or node types
|
|
@pytest.mark.parametrize("expr", [
|
|
"2 ** 3", # power operator not supported
|
|
"3 << 1", # bitwise shift not supported
|
|
"1 < 2", # comparison not supported
|
|
"abs(3)", # function call not supported
|
|
"a + 2", # undefined variable
|
|
"[1, 2] + [3]", # lists not supported
|
|
"{1: 2}", # dicts not supported
|
|
])
|
|
def test_arithmetic_eval_raises(expr):
|
|
with pytest.raises(ArithmeticEvalError):
|
|
arithmetic_eval(expr)
|
|
|
|
# Expressions that are syntactically valid but cause Python runtime errors
|
|
@pytest.mark.parametrize("expr, exception", [
|
|
("1 / 0", ZeroDivisionError),
|
|
("10 % 0", ZeroDivisionError),
|
|
])
|
|
def test_arithmetic_eval_runtime_errors(expr, exception):
|
|
with pytest.raises(exception):
|
|
arithmetic_eval(expr)
|
|
|
|
# forgiving_eval: returns original expression string on error
|
|
@pytest.mark.parametrize("expr, expected", [
|
|
("1 + 2", 3),
|
|
("bad + 2", "bad + 2"),
|
|
("1 / 0", "1 / 0"),
|
|
("2 ** 10", "2 ** 10"),
|
|
])
|
|
def test_forgiving_eval(expr, expected):
|
|
assert forgiving_eval(expr) == expected
|
|
|
|
# defaulting_eval: returns provided default value on error
|
|
@pytest.mark.parametrize("expr, default, expected", [
|
|
("3 * 4", 0, 12),
|
|
("invalid + 1", 99, 99),
|
|
("1 / 0", -1, -1),
|
|
("2 ** 10", 42, 42),
|
|
])
|
|
def test_defaulting_eval(expr, default, expected):
|
|
assert defaulting_eval(expr, default=default) == expected
|