import math import sys, os sys.path.insert(0, os.path.dirname(__file__)) from expr_eval import evaluate, EvalError def test_basic(): assert evaluate("2 + 3 * 4") == 14 assert evaluate("(2+3)*4") == 20 assert evaluate("10 / 3") == 10/3 assert evaluate("10 // 3") == 3 assert evaluate("10 % 3") == 1 def test_power_precedence(): # unary binds looser than ** (matches Python) assert evaluate("-2**2") == -4 assert evaluate("(-2)**2") == 4 assert evaluate("2**-2") == 0.25 assert evaluate("2**3**2") == 512 def test_unary(): assert evaluate("--5") == 5 assert evaluate("-(-3)") == 3 def test_funcs(): assert evaluate("sqrt(16)") == 4 assert abs(evaluate("sin(0)")) < 1e-12 assert evaluate("max(1,2,3)") == 3 assert evaluate("min(1,2,3)") == 1 assert evaluate("abs(-7)") == 7 def test_vars(): assert evaluate("x + pi", {"x": 3, "pi": math.pi}) == 3 + math.pi def test_errors(): for e in ["2 +", "1/0", "foo", "2 @ 3", "sqrt(-1)"]: try: evaluate(e) raise AssertionError(f"no error for {e!r}") except EvalError: pass if __name__ == "__main__": # run all test_ functions import traceback g = globals() failed = 0 for name in sorted(n for n in g if n.startswith("test_")): try: g[name]() print("PASS", name) except Exception: failed += 1 print("FAIL", name) traceback.print_exc() print("FAILED:", failed) sys.exit(1 if failed else 0)