Skip to main content
Glama

MCP Memory Service

test_time_parser.py8.89 kB
""" Unit tests for time_parser module """ import pytest from datetime import datetime, date, timedelta import time import sys import os sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) from mcp_memory_service.utils.time_parser import ( parse_time_expression, extract_time_expression, get_time_of_day_range, get_last_period_range, get_this_period_range, get_month_range, get_named_period_range ) class TestTimeParser: """Test time parsing functionality""" def test_relative_days(self): """Test parsing relative day expressions""" # Test "yesterday" start_ts, end_ts = parse_time_expression("yesterday") assert start_ts is not None assert end_ts is not None yesterday = date.today() - timedelta(days=1) start_dt = datetime.fromtimestamp(start_ts) end_dt = datetime.fromtimestamp(end_ts) assert start_dt.date() == yesterday assert end_dt.date() == yesterday assert start_dt.time() == datetime.min.time() assert end_dt.time().hour == 23 assert end_dt.time().minute == 59 # Test "3 days ago" start_ts, end_ts = parse_time_expression("3 days ago") three_days_ago = date.today() - timedelta(days=3) start_dt = datetime.fromtimestamp(start_ts) assert start_dt.date() == three_days_ago # Test "today" start_ts, end_ts = parse_time_expression("today") start_dt = datetime.fromtimestamp(start_ts) assert start_dt.date() == date.today() def test_relative_weeks(self): """Test parsing relative week expressions""" start_ts, end_ts = parse_time_expression("2 weeks ago") assert start_ts is not None assert end_ts is not None start_dt = datetime.fromtimestamp(start_ts) end_dt = datetime.fromtimestamp(end_ts) # Should be a Monday to Sunday range assert start_dt.weekday() == 0 # Monday assert end_dt.weekday() == 6 # Sunday # Should be roughly 2 weeks ago days_ago = (date.today() - start_dt.date()).days assert 14 <= days_ago <= 20 # Allow some flexibility for week boundaries def test_relative_months(self): """Test parsing relative month expressions""" start_ts, end_ts = parse_time_expression("1 month ago") assert start_ts is not None assert end_ts is not None start_dt = datetime.fromtimestamp(start_ts) end_dt = datetime.fromtimestamp(end_ts) # Should be first to last day of the month assert start_dt.day == 1 assert (end_dt + timedelta(days=1)).day == 1 # Next day is first of next month def test_specific_dates(self): """Test parsing specific date formats""" # Test MM/DD/YYYY format with unambiguous date start_ts, end_ts = parse_time_expression("03/15/2024") assert start_ts is not None start_dt = datetime.fromtimestamp(start_ts) assert start_dt.year == 2024 assert start_dt.month == 3 assert start_dt.day == 15 # Test YYYY-MM-DD format start_ts, end_ts = parse_time_expression("2024-06-15") assert start_ts is not None start_dt = datetime.fromtimestamp(start_ts) assert start_dt.date() == date(2024, 6, 15) def test_month_names(self): """Test parsing month names""" current_year = datetime.now().year current_month = datetime.now().month # Test a past month start_ts, end_ts = parse_time_expression("january") start_dt = datetime.fromtimestamp(start_ts) # Should be this year's January if we're past January, otherwise last year's expected_year = current_year if current_month > 1 else current_year - 1 assert start_dt.month == 1 assert start_dt.year == expected_year def test_seasons(self): """Test parsing season names""" # Test summer start_ts, end_ts = parse_time_expression("last summer") assert start_ts is not None assert end_ts is not None start_dt = datetime.fromtimestamp(start_ts) end_dt = datetime.fromtimestamp(end_ts) # Summer is roughly June 21 to September 22 assert start_dt.month == 6 assert end_dt.month == 9 def test_holidays(self): """Test parsing holiday names""" # Test Christmas start_ts, end_ts = parse_time_expression("christmas") assert start_ts is not None start_dt = datetime.fromtimestamp(start_ts) end_dt = datetime.fromtimestamp(end_ts) # Christmas window should include Dec 25 +/- a few days assert start_dt.month == 12 assert 22 <= start_dt.day <= 25 assert 25 <= end_dt.day <= 28 def test_time_of_day(self): """Test time of day parsing""" # Test "yesterday morning" start_ts, end_ts = parse_time_expression("yesterday morning") start_dt = datetime.fromtimestamp(start_ts) end_dt = datetime.fromtimestamp(end_ts) yesterday = date.today() - timedelta(days=1) assert start_dt.date() == yesterday assert 5 <= start_dt.hour <= 6 # Morning starts at 5 AM assert 11 <= end_dt.hour <= 12 # Morning ends before noon def test_date_ranges(self): """Test date range expressions""" start_ts, end_ts = parse_time_expression("between january and march") assert start_ts is not None assert end_ts is not None start_dt = datetime.fromtimestamp(start_ts) end_dt = datetime.fromtimestamp(end_ts) assert start_dt.month == 1 assert end_dt.month == 3 def test_quarters(self): """Test quarter expressions""" start_ts, end_ts = parse_time_expression("first quarter of 2024") assert start_ts is not None start_dt = datetime.fromtimestamp(start_ts) end_dt = datetime.fromtimestamp(end_ts) assert start_dt == datetime(2024, 1, 1, 0, 0, 0) assert end_dt.year == 2024 assert end_dt.month == 3 assert end_dt.day == 31 def test_extract_time_expression(self): """Test extracting time expressions from queries""" # Test extraction with semantic content cleaned, (start_ts, end_ts) = extract_time_expression( "find meetings from last week about project updates" ) assert "meetings" in cleaned assert "project updates" in cleaned assert "last week" not in cleaned assert start_ts is not None assert end_ts is not None # Test multiple time expressions cleaned, (start_ts, end_ts) = extract_time_expression( "yesterday in the morning I had coffee" ) assert "coffee" in cleaned assert "yesterday" not in cleaned assert "in the morning" not in cleaned def test_edge_cases(self): """Test edge cases and error handling""" # Test empty string start_ts, end_ts = parse_time_expression("") assert start_ts is None assert end_ts is None # Test invalid date format start_ts, end_ts = parse_time_expression("13/32/2024") # Invalid month and day assert start_ts is None assert end_ts is None # Test nonsense string start_ts, end_ts = parse_time_expression("random gibberish text") assert start_ts is None assert end_ts is None def test_this_period_expressions(self): """Test 'this X' period expressions""" # This week start_ts, end_ts = parse_time_expression("this week") start_dt = datetime.fromtimestamp(start_ts) end_dt = datetime.fromtimestamp(end_ts) # Should include today today = date.today() assert start_dt.date() <= today <= end_dt.date() # This month start_ts, end_ts = parse_time_expression("this month") start_dt = datetime.fromtimestamp(start_ts) assert start_dt.month == datetime.now().month assert start_dt.year == datetime.now().year def test_recent_expressions(self): """Test 'recent' and similar expressions""" start_ts, end_ts = parse_time_expression("recently") assert start_ts is not None assert end_ts is not None # Should default to last 7 days days_diff = (end_ts - start_ts) / (24 * 3600) assert 6 <= days_diff <= 8 # Allow for some time variance if __name__ == "__main__": pytest.main([__file__, "-v"])

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/doobidoo/mcp-memory-service'

If you have feedback or need assistance with the MCP directory API, please join our Discord server