Spaces:
Sleeping
Sleeping
| """Tests for V3 Bidirectional Solver — forward read + backward zone targeting.""" | |
| import pytest | |
| from engine.solver import ( | |
| forward, | |
| state_transition, | |
| solve_for_b_range, | |
| optimal_b_temperature, | |
| ) | |
| from engine.shared import VADUG | |
| # ── Forward ──────────────────────────────────────────────────────── | |
| class TestForward: | |
| def test_happy_text_high_valence(self): | |
| """'I am happy' should produce V > 140.""" | |
| result = forward("I am happy") | |
| assert result.v > 140, f"Expected V > 140, got {result}" | |
| # ── State transition ─────────────────────────────────────────────── | |
| class TestStateTransition: | |
| def test_neutral_b_preserves_a_direction(self): | |
| """Neutral B should preserve A's direction — V stays on same side of 128.""" | |
| a = VADUG(v=180, a=140, d=150, u=20, g=140) | |
| b = VADUG(v=128, a=128, d=128, u=0, g=128) | |
| c = state_transition(a, b) | |
| # A is positive (180), neutral B should keep C positive | |
| assert c.v > 128, f"Expected C.v > 128, got {c.v}" | |
| # C should be pulled toward neutral but still positive | |
| assert c.v < a.v, f"Expected C.v < A.v ({a.v}), got {c.v}" | |
| def test_warm_b_lifts_crisis_a(self): | |
| """Warm B should lift a crisis state — C.v > A.v.""" | |
| crisis = VADUG(v=60, a=180, d=50, u=200, g=40) | |
| warm = VADUG(v=200, a=100, d=160, u=10, g=180) | |
| c = state_transition(crisis, warm) | |
| assert c.v > crisis.v, f"Expected C.v > {crisis.v}, got {c.v}" | |
| assert c.d > crisis.d, f"Expected C.d > {crisis.d}, got {c.d}" | |
| assert c.g > crisis.g, f"Expected C.g > {crisis.g}, got {c.g}" | |
| def test_weights_sum_to_one(self): | |
| """Default weights: 60% A + 40% B.""" | |
| a = VADUG(v=100, a=100, d=100, u=100, g=100) | |
| b = VADUG(v=200, a=200, d=200, u=200, g=200) | |
| c = state_transition(a, b) | |
| # 100*0.6 + 200*0.4 = 140 | |
| assert c.v == 140 | |
| assert c.a == 140 | |
| assert c.d == 140 | |
| # ── Backward: zone targeting ────────────────────────────────────── | |
| class TestSolveForBRange: | |
| def test_neutral_a_to_joy_requires_positive_b(self): | |
| """From neutral A, reaching JOY zone requires positive B (V > 128).""" | |
| neutral = VADUG(v=128, a=128, d=128, u=0, g=128) | |
| ranges = solve_for_b_range(neutral, "JOY", temperature_steps=256) | |
| assert len(ranges) > 0, "Should find valid ranges for JOY from neutral" | |
| # Valid B values should be predominantly positive (above neutral) | |
| # The lowest valid B may dip slightly below 128 due to zone radius, | |
| # but the range center should be well above 128 | |
| lowest_start = min(s for s, _ in ranges) | |
| highest_end = max(e for _, e in ranges) | |
| midpoint = (lowest_start + highest_end) // 2 | |
| assert midpoint > 128, f"Expected range midpoint > 128, got {midpoint}" | |
| def test_deep_crisis_to_joy_narrow_or_empty(self): | |
| """Deep crisis A may have empty or narrow range to JOY. | |
| Can't reach joy from crisis in one step — this is correct behavior. | |
| """ | |
| crisis = VADUG(v=30, a=200, d=30, u=230, g=20) | |
| ranges = solve_for_b_range(crisis, "JOY", temperature_steps=256) | |
| # Either empty or very narrow — crisis is far from joy | |
| total_width = sum(end - start + 1 for start, end in ranges) | |
| assert total_width <= 30, ( | |
| f"Expected narrow/empty range from deep crisis to JOY, " | |
| f"got total width {total_width}" | |
| ) | |
| class TestOptimalBTemperature: | |
| def test_returns_value_in_valid_range(self): | |
| """Optimal B should fall within one of the valid ranges.""" | |
| neutral = VADUG(v=128, a=128, d=128, u=0, g=128) | |
| opt = optimal_b_temperature(neutral, "JOY") | |
| assert opt is not None, "Should find optimal B for JOY from neutral" | |
| ranges = solve_for_b_range(neutral, "JOY", temperature_steps=256) | |
| in_range = any(start <= opt <= end for start, end in ranges) | |
| assert in_range, f"Optimal B {opt} not in any valid range {ranges}" | |
| def test_unreachable_returns_none(self): | |
| """If no B can reach the zone, return None.""" | |
| # Extremely deep crisis — may not reach NEUTRAL's tiny radius | |
| extreme = VADUG(v=0, a=255, d=0, u=255, g=0) | |
| result = optimal_b_temperature(extreme, "NEUTRAL") | |
| # NEUTRAL has radius 8 — very tight, hard to hit from extreme | |
| # This may or may not be None depending on math, so just check type | |
| assert result is None or isinstance(result, int) | |