phi-drift / tests /test_predictor.py
crexs's picture
Upload folder using huggingface_hub
914e970 verified
Raw
History Blame Contribute Delete
5.5 kB
"""Tests for the predictive needs model."""
import os
import tempfile
from pathlib import Path
import pytest
from infj_bot.core.plugins.predictor import PredictiveNeeds
@pytest.fixture
def tmp_db():
fd, path = tempfile.mkstemp(suffix=".db")
os.close(fd)
yield Path(path)
os.unlink(path)
def _make_emotion(label: str, intensity: float) -> dict:
return {"label": label, "intensity": intensity, "confidence": 0.8}
class TestPredictiveNeeds:
def test_init_creates_db(self, tmp_db):
PredictiveNeeds(db_path=tmp_db)
assert tmp_db.exists()
def test_record_interaction(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
p.record_interaction("I am stressed about work", _make_emotion("anxious", 0.7))
patterns = p._load_recent_patterns(10)
assert len(patterns) == 1
assert patterns[0]["emotion_label"] == "anxious"
assert patterns[0]["stress_score"] > 0
def test_extract_topics(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
p.record_interaction(
"My partner and I are fighting about money", _make_emotion("sad", 0.5)
)
patterns = p._load_recent_patterns(1)
topics = patterns[0]["topics"].split(",")
assert "relationship" in topics or "conflict" in topics or "security" in topics
def test_time_of_day_analysis(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
# Simulate morning stress
for _ in range(3):
p.record_interaction(
"Morning anxiety about deadlines", _make_emotion("anxious", 0.6)
)
patterns = p._load_recent_patterns(10)
result = p._analyze_time_of_day(patterns)
# The time bucket depends on when the test runs, so just check structure
for bucket, data in result.items():
assert "typical_emotion" in data
assert "avg_stress" in data
def test_predict_current_need_insufficient_data(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
assert p.predict_current_need() is None
def test_predict_current_need_with_data(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
for i in range(8):
p.record_interaction(
f"I am stressed and overwhelmed at work {i}",
_make_emotion("overwhelmed", 0.7),
)
pred = p.predict_current_need()
assert pred is not None
assert "prediction" in pred
assert "confidence" in pred
assert 0.0 <= pred["confidence"] <= 1.0
def test_detect_anomaly_emotion_shift(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
# Older patterns: calm
for _ in range(5):
p.record_interaction("All good", _make_emotion("neutral", 0.2))
# Recent patterns: sad
for _ in range(3):
p.record_interaction("Feeling down", _make_emotion("sad", 0.6))
anomaly = p.detect_anomaly()
assert anomaly is not None
assert anomaly["type"] == "emotion_shift"
def test_detect_anomaly_stress_spike(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
# Same emotion but rising stress signals
for _ in range(5):
p.record_interaction("Normal day", _make_emotion("anxious", 0.2))
for _ in range(3):
p.record_interaction(
"PANIC everything is broken deadline urgent",
_make_emotion("anxious", 0.9),
)
anomaly = p.detect_anomaly()
assert anomaly is not None
assert anomaly["type"] == "stress_spike"
def test_proactive_suggestion(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
for _ in range(6):
p.record_interaction(
"I can't cope with this workload overwhelmed burned out",
_make_emotion("overwhelmed", 0.8),
)
# Also trigger an anomaly
for _ in range(3):
p.record_interaction(
"Actually things are okay", _make_emotion("neutral", 0.2)
)
for _ in range(3):
p.record_interaction("I am so sad and stressed", _make_emotion("sad", 0.8))
suggestion = p.proactive_suggestion()
assert suggestion is not None
assert len(suggestion) > 10
def test_format_predictive_prompt_empty(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
assert p.format_predictive_prompt() == ""
def test_format_predictive_prompt_with_data(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
for _ in range(8):
p.record_interaction(
"I am stressed and overwhelmed at work", _make_emotion("anxious", 0.7)
)
prompt = p.format_predictive_prompt()
assert "PREDICTIVE SENSE" in prompt
assert "wonder" in prompt.lower()
def test_gap_trend_stable(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
for i in range(6):
p.record_interaction(f"msg {i}", _make_emotion("neutral", 0.3))
trend = p._analyze_gap_trend(p._load_recent_patterns(10))
assert trend in ("stable", None)
def test_stress_signal_scoring(self, tmp_db):
p = PredictiveNeeds(db_path=tmp_db)
p.record_interaction(
"I am burned out and overwhelmed", _make_emotion("sad", 0.5)
)
patterns = p._load_recent_patterns(1)
assert patterns[0]["stress_score"] > 0.4