87 lines
3.5 KiB
Python
87 lines
3.5 KiB
Python
"""BUG-1420: Yogi / Ava Yogi is computed from the chart, not left blocked."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from scripts.annual_native.yogi_sphuta import (
|
|
build_luminary_sphuta_report,
|
|
build_yogi_sphuta_local,
|
|
compare_yogi_sphuta_to_replay,
|
|
)
|
|
from scripts.jyotish_engine import compute_chart_data
|
|
from tests.report_english_fictional import fictional_case
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
LIMIT = 1e-6
|
|
|
|
|
|
def _delta(left: float, right: float) -> float:
|
|
return ((left - right + 180.0) % 360.0) - 180.0
|
|
|
|
|
|
def test_formula_matches_the_declared_offsets() -> None:
|
|
result = build_yogi_sphuta_local({
|
|
"ascendant": {"sign": "Aries"},
|
|
"planets": {"Sun": {"degree_raw": 0.0}, "Moon": {"degree_raw": 0.0}},
|
|
})
|
|
assert result["status"] == "partial_verified"
|
|
assert result["formula_profile"] == "pyjhora_yogi_sphuta_v1"
|
|
assert result["yogi"]["longitude"] == pytest.approx(93.33333333)
|
|
assert result["yogi"]["sign"] == "Cancer"
|
|
assert result["ava_yogi"]["longitude"] == pytest.approx(280.0)
|
|
assert result["source_longitudes"] == {"Sun": 0.0, "Moon": 0.0}
|
|
|
|
|
|
def test_birth_longitudes_match_the_chart_within_one_microdegree() -> None:
|
|
birth = fictional_case(0)
|
|
chart, _asc, _jd, _ayanamsa = compute_chart_data(
|
|
birth["year"], birth["month"], birth["day"], birth["hour"], birth["minute"],
|
|
birth["lat"], birth["lon"], birth["tz"],
|
|
node_mode=birth["node_mode"], second=birth["second"], ayanamsa_name=birth["ayanamsa"],
|
|
)
|
|
result = build_yogi_sphuta_local(chart)
|
|
assert result["status"] != "blocked"
|
|
for name in ("Sun", "Moon"):
|
|
assert abs(result["source_longitudes"][name] - chart["planets"][name]["degree_raw"]) <= LIMIT
|
|
expected = (result["source_longitudes"]["Sun"] + result["source_longitudes"]["Moon"] + 93.0 + 20.0 / 60.0) % 360.0
|
|
assert abs(_delta(result["yogi"]["longitude"], expected)) <= LIMIT
|
|
|
|
|
|
def test_missing_longitude_states_the_reason() -> None:
|
|
result = build_yogi_sphuta_local({"planets": {"Sun": {"degree_raw": 1.0}}})
|
|
assert result["status"] == "blocked"
|
|
assert result["reason"] == "sun_or_moon_longitude_missing"
|
|
|
|
|
|
def test_import_failure_is_not_stored_as_blocked() -> None:
|
|
source = (ROOT / "scripts" / "jyotish_engine.py").read_text(encoding="utf-8")
|
|
assert "yogi_sphuta_local_unavailable" not in source
|
|
assert "yogi_sphuta: ImportError:" in source
|
|
|
|
|
|
def test_luminary_bundle_and_replay_comparison() -> None:
|
|
report = build_luminary_sphuta_report(sun_longitude=350, moon_longitude=20, ayanamsa="lahiri", ascendant_sign="Aries")
|
|
points = report["evidence_appendix"][0]["points"]
|
|
assert points["yogi"]["longitude"] == pytest.approx(103.33333333)
|
|
local = build_yogi_sphuta_local({
|
|
"ascendant": {"sign": "Aries"},
|
|
"planets": {"Sun": {"degree_raw": 350.0}, "Moon": {"degree_raw": 20.0}},
|
|
})
|
|
comparison = compare_yogi_sphuta_to_replay(local, {
|
|
"status": "partial_verified",
|
|
"yogi": {"longitude": 103.33333333},
|
|
"ava_yogi": {"longitude": 290.0},
|
|
})
|
|
assert comparison["status"] == "partial_verified"
|
|
assert "not independent multi-engine parity" in comparison["claim_boundary"]
|
|
|
|
|
|
@pytest.mark.parametrize("number", [True, float("nan"), float("inf")])
|
|
def test_nonfinite_sun_is_blocked(number) -> None:
|
|
result = build_yogi_sphuta_local({"planets": {"Sun": {"degree_raw": number}, "Moon": {"degree_raw": 0}}})
|
|
assert result["status"] == "blocked"
|
|
assert result["reason"] == "sun_or_moon_longitude_missing"
|