"""CE-Gate e-process 纯函数单元测试。 覆盖 compute_e_value、gate_decision、probation_verdict 三个公共函数 的核心路径与边界条件。 """ import math import pytest from core.evolution.gate import compute_e_value, gate_decision, probation_verdict from core.evolution.types import GateParams, GateVerdict _PARAMS = GateParams( e_confirm=20.0, e_provisional=3.0, w_net_min=2, delta_min=0.02, lambda_dir=-0.642, e_rollback=10.0, ) class TestComputeEValue: """compute_e_value 的数学正确性与边界校验。""" def test_zero_zero_returns_one(self) -> None: """W=L=0 时 e 值应为 1(无证据,中性)。""" assert compute_e_value(0, 0) == pytest.approx(1.0) def test_negative_w_raises(self) -> None: """负 W 应立即报错。""" with pytest.raises(ValueError): compute_e_value(-1, 0) def test_negative_l_raises(self) -> None: """负 L 应立即报错。""" with pytest.raises(ValueError): compute_e_value(0, -1) def test_heavy_loss_returns_near_zero(self) -> None: """重度失败时 e 值趋近于零。""" assert compute_e_value(0, 20) < 0.05 def test_heavy_win_returns_large(self) -> None: """重度胜利时 e 值远大于 100。""" assert compute_e_value(10, 0) > 100 def test_symmetric(self) -> None: """W>L 时 e 值应大于 W compute_e_value(3, 5) class TestGateDecision: """gate_decision 四出口优先级链测试。""" def test_confirmed_needs_both_e_and_delta(self) -> None: """高 e 值 + 足够 delta → accept_confirmed。""" v = gate_decision(10, 0, 10, 10, params=_PARAMS) assert v.decision == "accept_confirmed" def test_continue_on_balanced(self) -> None: """平衡局面且题未尽 → continue。""" v = gate_decision(3, 3, 6, 20, params=_PARAMS) assert v.decision == "continue" def test_reject_inertia_on_exhaustion(self) -> None: """题尽且证据不足 → reject_inertia。""" v = gate_decision(1, 1, 2, 0, params=_PARAMS) assert v.decision == "reject_inertia" def test_n_used_zero_raises(self) -> None: """n_used=0 应立即报错。""" with pytest.raises(ValueError): gate_decision(0, 0, 0, 10, params=_PARAMS) def test_n_remaining_negative_raises(self) -> None: """n_remaining<0 应立即报错。""" with pytest.raises(ValueError): gate_decision(1, 0, 1, -1, params=_PARAMS) class TestProbationVerdict: """probation_verdict 试用期结算测试。""" def test_strong_win_confirmed(self) -> None: """强烈胜利 → confirmed 转正。""" assert probation_verdict(10, 0, params=_PARAMS) == "confirmed" def test_strong_loss_rollback(self) -> None: """强烈失败 → rollback 回滚。""" assert probation_verdict(0, 10, params=_PARAMS) == "rollback" def test_balanced_unverified(self) -> None: """平衡局面 → unverified 惯性转正。""" assert probation_verdict(3, 3, params=_PARAMS) == "unverified"