Co-authored-by: Perplexity Computer <perplexity@tower.local> Co-committed-by: Perplexity Computer <perplexity@tower.local>
166 lines
6.3 KiB
Python
166 lines
6.3 KiB
Python
"""Tests for the graduation test runner.
|
|
|
|
Refs: #953 (Graduation Test)
|
|
"""
|
|
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestConditionResults:
|
|
"""Tests for individual graduation condition evaluations."""
|
|
|
|
def test_economic_independence_pass(self):
|
|
"""Passes when sats earned exceeds sats spent."""
|
|
from timmy.sovereignty.graduation import evaluate_economic_independence
|
|
|
|
result = evaluate_economic_independence(sats_earned=100.0, sats_spent=50.0)
|
|
assert result.passed is True
|
|
assert result.actual == 50.0 # net
|
|
assert "Earned: 100.0" in result.detail
|
|
|
|
def test_economic_independence_fail_net_negative(self):
|
|
"""Fails when spending exceeds earnings."""
|
|
from timmy.sovereignty.graduation import evaluate_economic_independence
|
|
|
|
result = evaluate_economic_independence(sats_earned=10.0, sats_spent=50.0)
|
|
assert result.passed is False
|
|
|
|
def test_economic_independence_fail_zero_earnings(self):
|
|
"""Fails when earnings are zero even if spending is zero."""
|
|
from timmy.sovereignty.graduation import evaluate_economic_independence
|
|
|
|
result = evaluate_economic_independence(sats_earned=0.0, sats_spent=0.0)
|
|
assert result.passed is False
|
|
|
|
def test_operational_independence_pass(self):
|
|
"""Passes when uptime meets threshold and no interventions."""
|
|
from timmy.sovereignty.graduation import evaluate_operational_independence
|
|
|
|
result = evaluate_operational_independence(uptime_hours=24.0, human_interventions=0)
|
|
assert result.passed is True
|
|
|
|
def test_operational_independence_fail_low_uptime(self):
|
|
"""Fails when uptime is below threshold."""
|
|
from timmy.sovereignty.graduation import evaluate_operational_independence
|
|
|
|
result = evaluate_operational_independence(uptime_hours=20.0, human_interventions=0)
|
|
assert result.passed is False
|
|
|
|
def test_operational_independence_fail_interventions(self):
|
|
"""Fails when there are human interventions."""
|
|
from timmy.sovereignty.graduation import evaluate_operational_independence
|
|
|
|
result = evaluate_operational_independence(uptime_hours=24.0, human_interventions=2)
|
|
assert result.passed is False
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestGraduationReport:
|
|
"""Tests for the GraduationReport rendering."""
|
|
|
|
def test_to_dict(self):
|
|
"""Report serializes to dict correctly."""
|
|
from timmy.sovereignty.graduation import ConditionResult, GraduationReport
|
|
|
|
report = GraduationReport(
|
|
all_passed=False,
|
|
conditions=[
|
|
ConditionResult(name="Test", passed=True, actual=0, target=0, unit=" calls")
|
|
],
|
|
)
|
|
d = report.to_dict()
|
|
assert d["all_passed"] is False
|
|
assert len(d["conditions"]) == 1
|
|
assert d["conditions"][0]["name"] == "Test"
|
|
|
|
def test_to_markdown(self):
|
|
"""Report renders to readable markdown."""
|
|
from timmy.sovereignty.graduation import ConditionResult, GraduationReport
|
|
|
|
report = GraduationReport(
|
|
all_passed=True,
|
|
conditions=[
|
|
ConditionResult(name="Perception", passed=True, actual=0, target=0),
|
|
ConditionResult(name="Decision", passed=True, actual=3, target=5),
|
|
],
|
|
)
|
|
md = report.to_markdown()
|
|
assert "PASSED" in md
|
|
assert "Perception" in md
|
|
assert "Decision" in md
|
|
assert "falsework" in md.lower()
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestRunGraduationTest:
|
|
"""Tests for the full graduation test runner."""
|
|
|
|
@patch("timmy.sovereignty.graduation.evaluate_perception_independence")
|
|
@patch("timmy.sovereignty.graduation.evaluate_decision_independence")
|
|
@patch("timmy.sovereignty.graduation.evaluate_narration_independence")
|
|
def test_all_pass(self, mock_narr, mock_dec, mock_perc):
|
|
"""Full graduation passes when all 5 conditions pass."""
|
|
from timmy.sovereignty.graduation import ConditionResult, run_graduation_test
|
|
|
|
mock_perc.return_value = ConditionResult(name="Perception", passed=True, actual=0, target=0)
|
|
mock_dec.return_value = ConditionResult(name="Decision", passed=True, actual=3, target=5)
|
|
mock_narr.return_value = ConditionResult(name="Narration", passed=True, actual=0, target=0)
|
|
|
|
report = run_graduation_test(
|
|
sats_earned=100.0,
|
|
sats_spent=50.0,
|
|
uptime_hours=24.0,
|
|
human_interventions=0,
|
|
)
|
|
|
|
assert report.all_passed is True
|
|
assert len(report.conditions) == 5
|
|
assert all(c.passed for c in report.conditions)
|
|
|
|
@patch("timmy.sovereignty.graduation.evaluate_perception_independence")
|
|
@patch("timmy.sovereignty.graduation.evaluate_decision_independence")
|
|
@patch("timmy.sovereignty.graduation.evaluate_narration_independence")
|
|
def test_partial_fail(self, mock_narr, mock_dec, mock_perc):
|
|
"""Graduation fails when any single condition fails."""
|
|
from timmy.sovereignty.graduation import ConditionResult, run_graduation_test
|
|
|
|
mock_perc.return_value = ConditionResult(name="Perception", passed=True, actual=0, target=0)
|
|
mock_dec.return_value = ConditionResult(name="Decision", passed=False, actual=10, target=5)
|
|
mock_narr.return_value = ConditionResult(name="Narration", passed=True, actual=0, target=0)
|
|
|
|
report = run_graduation_test(
|
|
sats_earned=100.0,
|
|
sats_spent=50.0,
|
|
uptime_hours=24.0,
|
|
human_interventions=0,
|
|
)
|
|
|
|
assert report.all_passed is False
|
|
|
|
def test_persist_report(self, tmp_path):
|
|
"""Graduation report persists to JSON file."""
|
|
from timmy.sovereignty.graduation import (
|
|
ConditionResult,
|
|
GraduationReport,
|
|
persist_graduation_report,
|
|
)
|
|
|
|
report = GraduationReport(
|
|
all_passed=False,
|
|
conditions=[ConditionResult(name="Test", passed=False, actual=5, target=0)],
|
|
)
|
|
|
|
with patch("timmy.sovereignty.graduation.settings") as mock_settings:
|
|
mock_settings.repo_root = str(tmp_path)
|
|
path = persist_graduation_report(report)
|
|
|
|
assert path.exists()
|
|
import json
|
|
|
|
with open(path) as f:
|
|
data = json.load(f)
|
|
assert data["all_passed"] is False
|