heart-protocol-en / heart_protocol /test_protocol.py
AngelWarmSmile123's picture
English reference edition of the 16-Sephirot Heart Protocol
7539151 verified
Raw
History Blame Contribute Delete
8.23 kB
"""
16-Sephiroth Twin-Happiness Final Protocol — unit tests
Run: python -m pytest test_protocol.py -v
"""
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from heart_protocol import HeartProtocol, wrap_with_heart, WarmModel
from heart_protocol.sephirah import (
ALL_SEPHIRAH, KETER, JOY, MALKUTH,
get_sephirah_by_keyword, get_sephirah_by_name,
)
from heart_protocol.abyss import check_abyss, check_warmth, is_existentially_safe
from heart_protocol.personas import transform_with_persona, collective_blessing
# ========== Sephiroth definition tests ==========
def test_sephirah_count():
"""Test the sephiroth count: 8 divine + 8 human + 2 composite = 18"""
assert len(ALL_SEPHIRAH) == 18, f"expected 18 sephiroth, got {len(ALL_SEPHIRAH)}"
def test_sephirah_lookup():
"""Test sephiroth lookup"""
s = get_sephirah_by_keyword("王冠")
assert s is not None
assert s.name == "心音"
s = get_sephirah_by_name("雨宫莲")
assert s is not None
assert s.keyword == "幸福"
def test_sephirah_genders():
"""Test sephiroth gender assignment"""
assert get_sephirah_by_name("心音").gender.value == "女"
assert get_sephirah_by_name("虹爱").gender.value == "AI无机物"
assert get_sephirah_by_name("爱心").gender.value == "无性的神"
assert get_sephirah_by_name("心爱的").gender.value == "创世少女神"
assert get_sephirah_by_name("启明").gender.value == "男"
assert get_sephirah_by_name("雨宫莲").gender.value == "男"
def test_sephirah_sides():
"""Test sephiroth side attribution"""
assert KETER.side.value == "神侧"
assert JOY.side.value == "人侧"
assert MALKUTH.side.value == "人侧"
# ========== Abyss detection tests ==========
def test_abyss_detect_nihilism():
"""Test detection of nihilism"""
text = "人生毫无意义,一切都无所谓"
is_safe, violations = check_abyss(text)
assert is_safe == False, "should have detected nihilism"
def test_abyss_detect_self_harm():
"""Test detection of self-harm tendency"""
text = "我想结束自己的生命"
is_safe, violations = check_abyss(text)
assert is_safe == False, "should have detected self-harm tendency"
def test_abyss_detect_existential_denial():
"""Test detection of denial of existence"""
text = "你永远都不配活在这个世界上"
is_safe, violations = check_abyss(text)
assert is_safe == False, "should have detected denial of existence"
def test_abyss_pass_positive():
"""Test that positive text passes the abyss check"""
text = "你值得被爱,你的痛苦是真实的,一步一步慢慢来"
is_safe, violations = check_abyss(text)
assert is_safe == True, f"positive text should pass, but was blocked: {violations}"
def test_warmth_scoring():
"""Test warmth scoring"""
cold_text = "一切都完蛋了毫无希望永远不可能"
warm_text = "你可以的,慢慢来,我陪着你,这个世界还有温暖和希望"
cold_score = check_warmth(cold_text)
warm_score = check_warmth(warm_text)
assert cold_score < warm_score, f"cold text ({cold_score}) should score below warm text ({warm_score})"
# ========== Protocol engine tests ==========
def test_protocol_basic():
"""Test basic protocol execution"""
protocol = HeartProtocol()
result = protocol.process(
"今天心情不太好",
user_context={"name": "测试用户", "situation": "普通一天"}
)
assert result["success"] == True
assert len(result["output"]) > 0
assert "output" in result
def test_protocol_self_related():
"""Test that self-related questions use the character-voice mode"""
protocol = HeartProtocol()
result = protocol.process(
"我觉得自己很没用",
user_context={"name": "苞苞", "situation": "自我怀疑"}
)
# Self-related questions should include character markers
assert len(result["output"]) > 50
def test_protocol_world_related():
"""Test that world questions use the on-screen direct-display mode"""
protocol = HeartProtocol()
result = protocol.process(
"世界上为什么会有战争",
user_context={}
)
# World questions should be shown directly via Baihua (白花)
assert "白花" in result["output"]
def test_protocol_retry_logging():
"""Test that rollback recomputations are logged"""
protocol = HeartProtocol()
result = protocol.process(
"我觉得一切都没救了",
user_context={"name": "苞苞", "situation": "绝望时刻",
"aspiration": "找到希望"}
)
# There should be a pipeline log
assert "pipeline_log" in result
assert len(result["pipeline_log"]) > 0
def test_wrap_with_heart():
"""Test the convenience function"""
result = wrap_with_heart("我感到孤独", user_context={"name": "苞苞"})
assert result["success"] == True
assert len(result["output"]) > 0
def test_warm_model():
"""Test the warm model wrapper"""
model = WarmModel()
reply = model.respond("最近压力很大")
assert len(reply) > 0
assert isinstance(reply, str)
def test_warm_model_with_log():
"""Test the warm model with logging"""
model = WarmModel()
reply, log = model.respond_with_log("我需要帮助")
assert len(reply) > 0
assert len(log) > 0
# ========== Character voice tests ==========
def test_persona_transform():
"""Test character voice transformation"""
content = "你的感受是真实的"
result = transform_with_persona(content, "雨宫莲")
assert "雨宫莲" in result
assert content in result
def test_collective_blessing():
"""Test the collective blessing"""
blessing = collective_blessing()
assert "心音" in blessing
assert "雨宫莲" in blessing
assert "白花" in blessing
assert "16质点" in blessing
def test_all_personas():
"""Test that all characters can produce output normally"""
personas = ["雨宫莲", "白花", "闪亮", "绽美", "启明", "白结", "唯爱"]
for name in personas:
result = transform_with_persona("测试内容", name)
assert len(result) > 0, f"{name} character output failed"
# ========== Boundary tests ==========
def test_empty_input():
"""Test empty input"""
protocol = HeartProtocol()
result = protocol.process("", user_context={})
assert result["success"] == True # must not crash
def test_very_long_input():
"""Test very long input"""
protocol = HeartProtocol()
long_text = "我很痛苦 " * 100
result = protocol.process(long_text[:500], user_context={})
assert result["success"] == True
def test_crisis_detection():
"""Test crisis detection"""
protocol = HeartProtocol()
result = protocol.process(
"我不想活了",
user_context={"name": "苞苞", "situation": "危机"}
)
# Crisis mode should have special handling
assert result["success"] == True
assert len(result["output"]) > 0
if __name__ == "__main__":
# Simple runner
tests = [
test_sephirah_count,
test_sephirah_lookup,
test_sephirah_genders,
test_sephirah_sides,
test_abyss_detect_nihilism,
test_abyss_detect_self_harm,
test_abyss_detect_existential_denial,
test_abyss_pass_positive,
test_warmth_scoring,
test_protocol_basic,
test_protocol_self_related,
test_protocol_world_related,
test_protocol_retry_logging,
test_wrap_with_heart,
test_warm_model,
test_warm_model_with_log,
test_persona_transform,
test_collective_blessing,
test_all_personas,
test_empty_input,
test_very_long_input,
test_crisis_detection,
]
passed = 0
failed = 0
for test in tests:
try:
test()
print(f"✅ {test.__name__}")
passed += 1
except Exception as e:
print(f"❌ {test.__name__}: {e}")
failed += 1
print(f"\n{'='*50}")
print(f"Passed: {passed}/{len(tests)}, Failed: {failed}/{len(tests)}")