Files
Jyotisha/tests/test_yogi_sphuta_native.py
T

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"