Files
OpenJarvis/tests/tools/test_calculator.py
T
Jon Saad-FalconandClaude Opus 4.6 301e9cd2d4 Implement OpenJarvis v1.0 — all five pillars, SDK, benchmarks, Docker
Complete implementation across six development phases (v0.1 through v1.0):

- Core: Registry system, config, event bus, types (Phase 0)
- Intelligence + Inference: Model routing, Ollama/vLLM/llama.cpp/Cloud engines (Phase 1)
- Memory: SQLite/FAISS/ColBERT/BM25/Hybrid backends, document ingest, context injection (Phase 2)
- Agents: Simple/Orchestrator/Custom/OpenClaw agents, tool system (Phase 3)
- Learning: HeuristicRouter, reward functions, GRPO stub, telemetry aggregation (Phase 4)
- SDK: Jarvis class, OpenClaw protocol/transport, benchmarks, Docker deployment (Phase 5)

520 tests passing, 8 skipped (optional deps). Ruff lint clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 00:52:48 +00:00

112 lines
3.1 KiB
Python

"""Tests for the calculator tool."""
from __future__ import annotations
import math
import pytest
from openjarvis.tools.calculator import CalculatorTool, safe_eval
class TestSafeEval:
def test_addition(self):
assert safe_eval("2 + 3") == 5
def test_subtraction(self):
assert safe_eval("10 - 3") == 7
def test_multiplication(self):
assert safe_eval("4 * 5") == 20
def test_division(self):
assert safe_eval("10 / 4") == 2.5
def test_floor_division(self):
assert safe_eval("10 // 3") == 3
def test_modulo(self):
assert safe_eval("10 % 3") == 1
def test_power(self):
assert safe_eval("2 ** 10") == 1024
def test_negative(self):
assert safe_eval("-5 + 3") == -2
def test_nested_expressions(self):
assert safe_eval("(2 + 3) * (4 - 1)") == 15
def test_sqrt(self):
assert safe_eval("sqrt(16)") == 4.0
def test_log(self):
assert abs(safe_eval("log(e)") - 1.0) < 1e-10
def test_pi_constant(self):
assert abs(safe_eval("pi") - math.pi) < 1e-10
def test_trig(self):
assert abs(safe_eval("sin(0)")) < 1e-10
assert abs(safe_eval("cos(0)") - 1.0) < 1e-10
def test_division_by_zero(self):
with pytest.raises(ZeroDivisionError):
safe_eval("1 / 0")
def test_syntax_error(self):
with pytest.raises(SyntaxError):
safe_eval("2 +")
def test_unsupported_string_constant(self):
with pytest.raises(ValueError, match="Unsupported constant"):
safe_eval("'hello'")
def test_unknown_function(self):
with pytest.raises(ValueError, match="Unknown function"):
safe_eval("exec('bad')")
def test_unknown_variable(self):
with pytest.raises(ValueError, match="Unknown variable"):
safe_eval("x + 1")
class TestCalculatorTool:
def test_spec(self):
tool = CalculatorTool()
assert tool.spec.name == "calculator"
assert tool.spec.category == "math"
def test_basic_math(self):
tool = CalculatorTool()
result = tool.execute(expression="2 + 3 * 4")
assert result.success is True
assert result.content == "14"
def test_empty_expression(self):
tool = CalculatorTool()
result = tool.execute(expression="")
assert result.success is False
def test_no_expression(self):
tool = CalculatorTool()
result = tool.execute()
assert result.success is False
def test_division_by_zero_error(self):
tool = CalculatorTool()
result = tool.execute(expression="1/0")
assert result.success is False
assert "division by zero" in result.content
def test_invalid_expression_error(self):
tool = CalculatorTool()
result = tool.execute(expression="import os")
assert result.success is False
def test_openai_function_format(self):
tool = CalculatorTool()
fn = tool.to_openai_function()
assert fn["function"]["name"] == "calculator"
assert "expression" in fn["function"]["parameters"]["properties"]