Venus/Jupiter/Moon periods no longer collapse into one marriage-opportunity line. Full reading reports the ten BPHS conditional dasha families; Skill 6.9.16. Co-authored-by: Cursor <cursoragent@cursor.com>
56 lines
2.4 KiB
Python
56 lines
2.4 KiB
Python
"""Key/type stability for upstream-sync2 goldens. Extra keys are allowed."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from scripts.jyotish_engine import compute_chart_data
|
|
from scripts.relationship_analysis import analyze_relationship
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
GOLDEN_DIR = ROOT / "tests/golden/upstream_sync2"
|
|
|
|
|
|
def _assert_keys_and_types(expected, actual, path: str = "$") -> None:
|
|
if isinstance(expected, dict):
|
|
assert isinstance(actual, dict), path
|
|
for key, value in expected.items():
|
|
assert key in actual, f"missing {path}.{key}"
|
|
_assert_keys_and_types(value, actual[key], f"{path}.{key}")
|
|
return
|
|
if isinstance(expected, list):
|
|
assert isinstance(actual, list), path
|
|
if expected and actual:
|
|
_assert_keys_and_types(expected[0], actual[0], f"{path}[0]")
|
|
return
|
|
assert type(actual) is type(expected) or (
|
|
isinstance(expected, (int, float)) and isinstance(actual, (int, float))
|
|
), path
|
|
|
|
|
|
def test_relationship_golden_keys_remain_and_event_class_split_is_additive() -> None:
|
|
golden = json.loads((GOLDEN_DIR / "relationship_einstein.json").read_text(encoding="utf-8"))
|
|
expected = golden["response"]
|
|
chart, _asc_idx, _jd, _ayanamsa = compute_chart_data(
|
|
1879, 3, 14, 11, 30, 48.4, 9.98, 0.89, node_mode="mean", ayanamsa_name="raman"
|
|
)
|
|
planets = chart.get("planets") if isinstance(chart, dict) else {}
|
|
asc_sign = ((chart.get("ascendant") or {}).get("sign") if isinstance(chart, dict) else None) or "Aries"
|
|
actual = analyze_relationship(planets, asc_sign, dasha_info=golden.get("dasha_info"))
|
|
for key in ("assessment", "timing"):
|
|
if key in expected and key in actual:
|
|
_assert_keys_and_types(expected[key], actual[key], key)
|
|
assert "event_class_split" in actual
|
|
split = actual["event_class_split"]
|
|
assert set(split) >= {"romantic_activation", "relationship_formation", "legal_marriage"}
|
|
|
|
|
|
def test_consultation_golden_snapshot_shape_is_dict_with_timing_horizon_contract() -> None:
|
|
golden = json.loads((GOLDEN_DIR / "consultation_marriage_evidence_snapshot.json").read_text(encoding="utf-8"))
|
|
snapshot = golden["evidence_snapshot"]
|
|
assert isinstance(snapshot, dict)
|
|
assert "capability_evidence_pool" in snapshot
|
|
assert isinstance(snapshot["capability_evidence_pool"]["total_entries"], int)
|