Files
tatlock/tests/agents/test_tools.py
T
jpmschweitzerandClaude Opus 4.5 100ebeae52 feat: migrate web search from tatlock_core to Librarian
Move web search functionality to The Librarian agent, integrating with
the library-desk /rag/search endpoint for enhanced search capabilities.

Changes:
- Add search_web, read_url, read_urls_batch tools to Librarian
- Add WebSearchResult, ContentExtractionResult models to client
- Add search_web, extract_content, extract_content_batch client methods
- Update Librarian capability with web/url/internet domains
- Remove search_web from tatlock_core tools and toolset
- Update Tatlock system prompt to delegate web search to Librarian
- Add comprehensive unit tests for new Librarian tools
- Clean up legacy src/agents/tools.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 18:30:16 +01:00

192 lines
6.4 KiB
Python

"""
Tests for Tatlock's permanent tools (calculator, date/time).
Note: Web search has been moved to The Librarian agent.
See tests/agents/librarian/test_tools.py for search tests.
"""
import pytest
from datetime import datetime
from src.agents.tools import (
calculate,
get_current_datetime,
calculate_time_offset,
time_difference,
)
# ============================================================================
# Calculator Tests
# ============================================================================
class TestCalculator:
"""Tests for the calculator tool."""
def test_basic_arithmetic(self):
"""Test basic arithmetic operations."""
assert calculate("2 + 2") == "4"
assert calculate("10 - 3") == "7"
assert calculate("5 * 6") == "30"
assert calculate("20 / 4") == "5" # Integer result, no decimal
def test_complex_expressions(self):
"""Test complex mathematical expressions."""
assert calculate("(2 + 3) * 4") == "20"
assert calculate("10 ** 2") == "100"
assert calculate("17 % 5") == "2"
def test_math_functions(self):
"""Test mathematical functions."""
assert calculate("sqrt(16)") == "4" # Integer result
assert calculate("abs(-5)") == "5"
assert calculate("round(3.7)") == "4"
# Test with constants
result = calculate("pi * 2")
assert "6.28" in result # Approximately 6.283...
def test_trigonometry(self):
"""Test trigonometric functions."""
result = calculate("sin(0)")
assert result == "0" # Integer result
# cos(0) should be 1
result = calculate("cos(0)")
assert result == "1" # Integer result
def test_logarithms(self):
"""Test logarithmic functions."""
result = calculate("log10(100)")
assert result == "2" # Integer result
result = calculate("exp(0)")
assert result == "1" # Integer result
def test_error_handling(self):
"""Test error handling for invalid expressions."""
result = calculate("1 / 0")
assert "Error: Division by zero" in result
result = calculate("invalid_function(5)")
assert "Error calculating" in result
def test_integer_results(self):
"""Test that integer results don't show unnecessary decimals."""
assert calculate("4.0 + 6.0") == "10"
assert calculate("sqrt(9)") == "3"
# ============================================================================
# Date/Time Tests
# ============================================================================
class TestDateTime:
"""Tests for date/time toolkit."""
def test_get_current_datetime_full(self):
"""Test getting full current datetime."""
result = get_current_datetime("full")
# Should match format YYYY-MM-DD HH:MM:SS
assert len(result) == 19
assert result[4] == "-"
assert result[7] == "-"
assert result[10] == " "
assert result[13] == ":"
assert result[16] == ":"
def test_get_current_datetime_date(self):
"""Test getting current date only."""
result = get_current_datetime("date")
# Should match format YYYY-MM-DD
assert len(result) == 10
assert result[4] == "-"
assert result[7] == "-"
# Verify it's a valid date
datetime.strptime(result, "%Y-%m-%d")
def test_get_current_datetime_time(self):
"""Test getting current time only."""
result = get_current_datetime("time")
# Should match format HH:MM:SS
assert len(result) == 8
assert result[2] == ":"
assert result[5] == ":"
def test_get_current_datetime_iso(self):
"""Test getting ISO format."""
result = get_current_datetime("iso")
# Should be parseable as ISO format
datetime.fromisoformat(result)
def test_calculate_time_offset_days(self):
"""Test calculating time offsets in days."""
result = calculate_time_offset("1 day ago")
assert len(result) == 19 # YYYY-MM-DD HH:MM:SS
result = calculate_time_offset("2 days from now")
assert len(result) == 19
def test_calculate_time_offset_weeks(self):
"""Test calculating time offsets in weeks."""
result = calculate_time_offset("1 week ago")
assert len(result) == 19
result = calculate_time_offset("2 weeks from now")
assert len(result) == 19
def test_calculate_time_offset_months(self):
"""Test calculating time offsets in months."""
result = calculate_time_offset("1 month ago")
assert len(result) == 19
result = calculate_time_offset("3 months from now")
assert len(result) == 19
def test_calculate_time_offset_years(self):
"""Test calculating time offsets in years."""
result = calculate_time_offset("1 year ago")
assert len(result) == 19
result = calculate_time_offset("2 years from now")
assert len(result) == 19
def test_calculate_time_offset_hours(self):
"""Test calculating time offsets in hours."""
result = calculate_time_offset("5 hours ago")
assert len(result) == 19
result = calculate_time_offset("3 hours from now")
assert len(result) == 19
def test_calculate_time_offset_invalid(self):
"""Test error handling for invalid time offsets."""
result = calculate_time_offset("invalid input")
assert "Error" in result
assert "Cannot parse" in result
def test_time_difference(self):
"""Test calculating time difference."""
result = time_difference("2024-01-01", "2024-01-15")
assert "14 day" in result
def test_time_difference_with_now(self):
"""Test time difference with 'now'."""
# Get today's date
today = datetime.now().strftime("%Y-%m-%d")
result = time_difference(today, "now")
# Should be less than a day
assert "Less than" in result or "hour" in result or "minute" in result
def test_time_difference_with_times(self):
"""Test time difference with full timestamps."""
result = time_difference("2024-01-01 10:00:00", "2024-01-01 14:30:00")
assert "4 hour" in result
assert "30 minute" in result
def test_time_difference_error(self):
"""Test error handling for invalid dates."""
result = time_difference("invalid-date", "now")
assert "Error" in result