kokoro-memory / tests /test_kokoro_memory.py
AIIT-Threshold's picture
kokoro-memory 1.0.0
2b99fec verified
Raw
History Blame Contribute Delete
3.95 kB
"""Unit tests — control plane of the kokoro memory store.
Each test gets a fresh module import against a temp KOKORO_MEMORY_ROOT so
tests never touch a real store and never depend on each other.
"""
import os
import sys
import importlib
import pytest
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@pytest.fixture()
def km(tmp_path, monkeypatch):
monkeypatch.setenv("KOKORO_MEMORY_ROOT", str(tmp_path))
monkeypatch.setenv("KOKORO_OWNER_NAME", "User")
monkeypatch.setenv("KOKORO_AGENT_NAME", "Assistant")
sys.path.insert(0, REPO_ROOT)
sys.modules.pop("kokoro_memory", None)
module = importlib.import_module("kokoro_memory")
yield module
sys.modules.pop("kokoro_memory", None)
def test_store_and_recall_grounding(km):
assert km.add_fact("truth", "favorite_fruit", "the favorite fruit is a crisp apple",
source="user_explicit", confidence=0.9)
assert km.add_fact("identity", "core_belief", "memory is resonance, not a database",
source="system", confidence=1.0)
results = km.recall("what is the favorite fruit")
assert results, "recall returned nothing"
assert results[0]["key"] == "favorite_fruit"
def test_junk_rejected(km):
assert not km.add_fact("event", "note", "ok")
assert not km.add_fact("event", "", "something with no key")
def test_bracket_scaffolding_detector(km):
assert km._is_bracket_scaffolding("()々")
assert km._is_bracket_scaffolding("「kokoro memory」")
assert km._is_bracket_scaffolding("「」『』()/・")
# Legitimate content must pass
assert not km._is_bracket_scaffolding("Japanese uses 「」 quotes for emphasis")
assert not km._is_bracket_scaffolding("無→波→気→命→和→愛→魂 is the seven-kanji order")
def test_duplicate_rejected(km):
assert km.add_fact("truth", "sky_color", "the sky is blue on a clear day")
assert not km.add_fact("truth", "sky_color", "the sky is blue on a clear day")
def test_auto_classify(km):
assert km._auto_classify("roadmap", "plan to build a rocket next year") == "夢"
assert km._auto_classify("mood", "I feel excited about the launch") == "感覚"
def test_public_pii_quarantined(km):
stored = km.add_fact("noun", "contact", "reach me at someone@example.com",
origin_surface="public_chat")
assert not stored
qdir = os.path.join(km.MEMORY_ROOT, "quarantine")
assert os.path.isdir(qdir) and os.listdir(qdir)
def test_public_source_cannot_spoof(km):
assert km.add_fact("event", "claim", "the moon landing conference is next tuesday",
source="user_explicit", origin_surface="public_chat")
fact = km._load_fact("出来事", "claim")
assert fact["source"] == "public_chat_conversation"
assert fact["authority_class"] == "public_user_submitted"
assert fact["trusted_by_default"] is False
def test_raw_turn_roundtrip_and_names(km):
km.append_raw_turn("hello there", "hi, good to see you")
raw = km.load_raw_recent()
assert "User: hello there" in raw
assert "Assistant: hi, good to see you" in raw
def test_hallucinated_turn_truncated(km):
text = "real reply here\nUser: fake next turn"
assert km._sanitize_turn_text(text) == "real reply here"
def test_purge_token_salad_dry_run(km):
# Bypass add_fact's junk gate to plant salad directly, as the old defect did
km._save_fact({"key": "salad", "value": "()々", "category": "出来事"})
report = km.purge_token_salad(dry_run=True)
assert report["purged_count"] == 1
assert report["dry_run"] is True
# Identity category is protected even from real purges
km._save_fact({"key": "soul_salad", "value": "()々", "category": "心"})
report = km.purge_token_salad(dry_run=False)
assert {"category": "心", "key": "soul_salad", "value": "()々"} in report["protected_skipped"]