Consultation was passing the birth mahadasha into event-class splits, so marriage hits stayed empty and timing still said 缔结. Read live MD/AD from dasha_sub_periods, derive activation copy from the split, and isolate fence failures so one bad varga cannot 500 the whole report. Co-authored-by: Cursor <cursoragent@cursor.com>
101 lines
3.9 KiB
Python
101 lines
3.9 KiB
Python
"""Event-class evidence items for marriage themes."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT / "scripts"))
|
|
|
|
from jyotish_api_server import JyotishAPIHandler # noqa: E402
|
|
from relationship_analysis import analyze_relationship # noqa: E402
|
|
from relationship_event_class_evidence import build_event_class_evidence # noqa: E402
|
|
|
|
|
|
def _theme_evidence(technique, chart, conclusion, sentiment, strength, *, source, details=None):
|
|
return {
|
|
"technique": technique,
|
|
"chart": chart,
|
|
"conclusion": conclusion,
|
|
"sentiment": sentiment,
|
|
"strength": strength,
|
|
"details": {**(details or {}), "source": source},
|
|
}
|
|
|
|
|
|
def _moon_saturn_seventh_house() -> dict:
|
|
return {
|
|
"Moon": {"sign": "Aquarius", "house": 7, "longitude": 311.48},
|
|
"Saturn": {"sign": "Aquarius", "house": 7, "longitude": 319.01},
|
|
"Venus": {"sign": "Pisces", "house": 8, "longitude": 341.99},
|
|
"Jupiter": {"sign": "Virgo", "house": 2, "longitude": 165.27},
|
|
"Sun": {"sign": "Leo", "house": 1, "longitude": 125.0},
|
|
}
|
|
|
|
|
|
def test_moon_saturn_seventh_with_venus_ad_emits_romantic_and_legal_items() -> None:
|
|
relationship = analyze_relationship(
|
|
_moon_saturn_seventh_house(),
|
|
asc_sign="Leo",
|
|
dasha_info={"maha_dasha": "Saturn", "antar_dasha": "Venus"},
|
|
ul_sign="Libra",
|
|
darakaraka="Sun",
|
|
)
|
|
items = build_event_class_evidence(relationship, _theme_evidence)
|
|
by_name = {item["technique"]: item for item in items}
|
|
assert "Romantic-activation" in by_name
|
|
assert "Legal-marriage" in by_name
|
|
assert by_name["Romantic-activation"]["strength"] == "weak"
|
|
assert by_name["Romantic-activation"]["sentiment"] == "neutral"
|
|
assert by_name["Legal-marriage"]["details"]["hits"]
|
|
|
|
|
|
def test_pratyantar_venus_does_not_emit_legal_marriage_item() -> None:
|
|
relationship = analyze_relationship(
|
|
_moon_saturn_seventh_house(),
|
|
asc_sign="Leo",
|
|
dasha_info={"maha_dasha": "Saturn", "antar_dasha": "Mercury", "pratyantar": "Venus"},
|
|
ul_sign="Libra",
|
|
darakaraka="Sun",
|
|
)
|
|
split = relationship["event_class_split"]
|
|
assert "Venus_pd" in split["pd_hits"]
|
|
assert "Venus_dasha" not in split["legal_marriage"]["hits"]
|
|
items = build_event_class_evidence(relationship, _theme_evidence)
|
|
assert all(item["technique"] != "Legal-marriage" for item in items)
|
|
|
|
|
|
def test_consultation_shaped_1990_chart_feeds_nonempty_event_class_hits() -> None:
|
|
golden = json.loads(
|
|
(ROOT / "tests/golden/upstream_sync2/consultation_marriage_1990_fictional.json").read_text(
|
|
encoding="utf-8"
|
|
)
|
|
)
|
|
chart = golden["chart"]
|
|
handler = JyotishAPIHandler.__new__(JyotishAPIHandler)
|
|
dasha = (chart.get("modules") or {}).get("dasha") or {}
|
|
dasha_info = handler._thematic_dasha_info(chart, dasha)
|
|
assert dasha_info["maha_dasha"] == "Saturn"
|
|
assert dasha_info["antar_dasha"] == "Jupiter"
|
|
timing = (((golden.get("thematic_report") or {}).get("themes") or {}).get("marriage") or {}).get("timing") or {}
|
|
assert "Unknown" not in str(timing.get("dasha_period") or "")
|
|
assert timing.get("dasha_period") == "Saturn-Jupiter"
|
|
relationship = analyze_relationship(
|
|
chart["planets"],
|
|
asc_sign=chart["ascendant"]["sign"],
|
|
dasha_info=dasha_info,
|
|
)
|
|
items = handler._derived_marriage_evidence(
|
|
chart,
|
|
{"relationship": relationship, "full_modules": chart.get("modules") or {}},
|
|
)
|
|
by_name = {item["technique"]: item for item in items}
|
|
nonempty = [
|
|
name
|
|
for name in ("Romantic-activation", "Relationship-formation")
|
|
if (by_name.get(name) or {}).get("details", {}).get("hits")
|
|
]
|
|
assert nonempty, {name: (by_name.get(name) or {}).get("details") for name in by_name}
|