sunnyware / tests /test_memory_summarize.py
shamiur's picture
Part 586: Add tests for memory content helpers
74ebe3f
Raw History Blame Contribute Delete
11.2 kB
import sys
sys.path.insert(0, 'src')
from sunnyware.memory import _summarize_old_events
def _row(event_type, content):
return {"event_type": event_type, "payload": {"content": content}}
def test_summarize_empty():
assert _summarize_old_events([]) == ""
def test_summarize_no_user_messages():
rows = [_row("assistant_message", "hello")]
assert _summarize_old_events(rows) == ""
def test_summarize_single_user():
rows = [_row("user_message", "what is AAPL price")]
result = _summarize_old_events(rows)
assert "AAPL price" in result
assert result.startswith("Earlier in this conversation")
def test_summarize_multiple_users():
rows = [
_row("user_message", "AAPL price"),
_row("assistant_message", "$180"),
_row("user_message", "MSFT price"),
_row("assistant_message", "$400"),
]
result = _summarize_old_events(rows)
assert "AAPL" in result
assert "MSFT" in result
assert "; " in result
def test_summarize_respects_max_chars():
rows = [_row("user_message", "question " + str(i) + " " + "x" * 80) for i in range(10)]
result = _summarize_old_events(rows, max_chars=100)
assert len(result) < 200
assert result.endswith("...")
def test_summarize_caps_each_snippet():
rows = [_row("user_message", "x" * 200)]
result = _summarize_old_events(rows)
assert len(result) < 200
import asyncio
def test_build_context_with_summary_no_pool():
from sunnyware.memory import build_context_with_summary
result = asyncio.run(build_context_with_summary("", max_turns=4))
assert result == []
def test_should_skip_message_empty():
from sunnyware.memory import _should_skip_message
assert _should_skip_message("") is True
assert _should_skip_message(" ") is True
def test_should_skip_message_short():
from sunnyware.memory import _should_skip_message
assert _should_skip_message("ok") is True
assert _should_skip_message("yes") is True
assert _should_skip_message("no") is True
def test_should_skip_message_low_value():
from sunnyware.memory import _should_skip_message
assert _should_skip_message("thanks") is True
assert _should_skip_message("got it") is True
assert _should_skip_message("sure") is True
def test_should_not_skip_substantive():
from sunnyware.memory import _should_skip_message
assert _should_skip_message("what is AAPL price") is False
assert _should_skip_message("AAPL price") is False
assert _should_skip_message("MSFT earnings report") is False
def test_pruning_threshold_env_override():
import os, importlib
os.environ["SUNNYWARE_MIN_HISTORY_CHARS"] = "10"
import sunnyware.memory as m
importlib.reload(m)
assert m.MIN_HISTORY_CONTENT_CHARS == 10
assert m._should_skip_message("short") is True
assert m._should_skip_message("this is long enough") is False
os.environ.pop("SUNNYWARE_MIN_HISTORY_CHARS", None)
importlib.reload(m)
assert m.MIN_HISTORY_CONTENT_CHARS == 4
def test_score_event_empty():
from sunnyware.memory import _score_event_text
assert _score_event_text("", ["ai"]) == 0.0
def test_score_event_no_match():
from sunnyware.memory import _score_event_text
assert _score_event_text("hello world", ["xyz"]) == 0.0
def test_score_event_single_match():
from sunnyware.memory import _score_event_text
score = _score_event_text("what is AI", ["ai"])
assert score == 2.0
def test_score_event_multiple_matches():
from sunnyware.memory import _score_event_text
score = _score_event_text("ai and ai", ["ai"])
assert score == 3.0
def test_score_longer_keyword_weighted():
from sunnyware.memory import _score_event_text
score_short = _score_event_text("machine", ["ai"])
score_long = _score_event_text("machine", ["machine"])
assert score_long > score_short
def test_score_two_keywords():
from sunnyware.memory import _score_event_text
score = _score_event_text("ai and machine", ["ai", "machine"])
assert score == 9.0
def test_format_context_empty():
from sunnyware.memory import format_context
assert format_context([]) == ""
def test_format_context_single_event():
from sunnyware.memory import format_context
events = [
{"event_type": "user_message", "payload": {"content": "hello world"}},
]
result = format_context(events)
assert result == "[user] hello world"
def test_format_context_assistant_role():
from sunnyware.memory import format_context
events = [
{"event_type": "assistant_message", "payload": {"content": "hi there"}},
]
result = format_context(events)
assert result == "[assistant] hi there"
def test_format_context_string_payload():
from sunnyware.memory import format_context
import json
events = [
{"event_type": "user_message", "payload": json.dumps({"content": "from string"})},
]
result = format_context(events)
assert "[user] from string" in result
def test_format_context_multiple_events():
from sunnyware.memory import format_context
events = [
{"event_type": "user_message", "payload": {"content": "first"}},
{"event_type": "assistant_message", "payload": {"content": "second"}},
]
result = format_context(events)
assert result == "[user] first\n[assistant] second"
def test_format_context_skips_empty_content():
from sunnyware.memory import format_context
events = [
{"event_type": "user_message", "payload": {"content": ""}},
{"event_type": "user_message", "payload": {"content": "real content"}},
]
result = format_context(events)
assert "real content" in result
assert result.count("[user]") == 1
def test_format_context_truncates_long_content():
from sunnyware.memory import format_context
long_text = "x" * 500
events = [
{"event_type": "user_message", "payload": {"content": long_text}},
]
result = format_context(events, max_chars_per_event=50)
assert len(result) < 100
def test_format_context_replaces_newlines():
from sunnyware.memory import format_context
events = [
{"event_type": "user_message", "payload": {"content": "line1\nline2"}},
]
result = format_context(events)
assert "\n" not in result.replace("[user] ", "")
def test_format_context_unknown_event_type():
from sunnyware.memory import format_context
events = [
{"event_type": "other_event", "payload": {"content": "misc"}},
]
result = format_context(events)
assert result == "[assistant] misc"
def test_format_context_empty():
from sunnyware.memory import format_context
assert format_context([]) == ""
def test_format_context_single_event():
from sunnyware.memory import format_context
events = [
{"event_type": "user_message", "payload": {"content": "hello world"}},
]
result = format_context(events)
assert result == "[user] hello world"
def test_format_context_assistant_role():
from sunnyware.memory import format_context
events = [
{"event_type": "assistant_message", "payload": {"content": "hi there"}},
]
result = format_context(events)
assert result == "[assistant] hi there"
def test_format_context_string_payload():
from sunnyware.memory import format_context
import json
events = [
{"event_type": "user_message", "payload": json.dumps({"content": "from string"})},
]
result = format_context(events)
assert "[user] from string" in result
def test_format_context_multiple_events():
from sunnyware.memory import format_context
events = [
{"event_type": "user_message", "payload": {"content": "first"}},
{"event_type": "assistant_message", "payload": {"content": "second"}},
]
result = format_context(events)
assert result == "[user] first\n[assistant] second"
def test_format_context_skips_empty_content():
from sunnyware.memory import format_context
events = [
{"event_type": "user_message", "payload": {"content": ""}},
{"event_type": "user_message", "payload": {"content": "real content"}},
]
result = format_context(events)
assert "real content" in result
assert result.count("[user]") == 1
def test_format_context_truncates_long_content():
from sunnyware.memory import format_context
long_text = "x" * 500
events = [
{"event_type": "user_message", "payload": {"content": long_text}},
]
result = format_context(events, max_chars_per_event=50)
assert len(result) < 100
def test_format_context_replaces_newlines():
from sunnyware.memory import format_context
events = [
{"event_type": "user_message", "payload": {"content": "line1\nline2"}},
]
result = format_context(events)
assert "\n" not in result.replace("[user] ", "")
def test_format_context_unknown_event_type():
from sunnyware.memory import format_context
events = [
{"event_type": "other_event", "payload": {"content": "misc"}},
]
result = format_context(events)
assert result == "[assistant] misc"
def test_extract_content_dict():
from sunnyware.memory import _extract_content
assert _extract_content({"content": "hello"}) == "hello"
assert _extract_content({"content": ""}) == ""
assert _extract_content({}) == ""
assert _extract_content({"other": "x"}) == ""
def test_extract_content_string():
from sunnyware.memory import _extract_content
import json
assert _extract_content(json.dumps({"content": "from string"})) == "from string"
assert _extract_content('{"content": "nested"}') == "nested"
def test_extract_content_invalid_string():
from sunnyware.memory import _extract_content
assert _extract_content("not json") == ""
assert _extract_content("") == ""
def test_extract_content_none():
from sunnyware.memory import _extract_content
assert _extract_content(None) == ""
assert _extract_content(123) == ""
def test_sanitize_content_empty():
from sunnyware.memory import _sanitize_content
assert _sanitize_content("", 100) == ""
assert _sanitize_content(None, 100) == ""
def test_sanitize_content_short():
from sunnyware.memory import _sanitize_content
result = _sanitize_content("hello world", 100)
assert result == "hello world"
def test_sanitize_content_truncates():
from sunnyware.memory import _sanitize_content
result = _sanitize_content("x" * 200, 50)
assert result.startswith("x" * 50)
assert "[truncated, orig 200 chars]" in result
def test_sanitize_content_redacts_base64():
from sunnyware.memory import _sanitize_content
# Create a 600-char base64-ish string with uppercase, lowercase, and digit
b64 = "A" * 200 + "a" * 200 + "1" * 200
result = _sanitize_content(b64, 5000)
assert "[redacted:" in result
assert len(result) < len(b64)
def test_sanitize_content_does_not_redact_short_runs():
from sunnyware.memory import _sanitize_content
text = "Hello World 123"
result = _sanitize_content(text, 1000)
assert "redacted" not in result
assert result == text