五档不再写稳定、离婚、再婚或婚前咨询,并写明这是结构指数。公开盘中英文各锁一条。配偶星证据行改成 0 到 1,不乘 100。pytest tests/test_d9_evidence_bands.py 3 通过。 Co-Authored-By: Grok (agent loop)
135 lines
5.4 KiB
Python
135 lines
5.4 KiB
Python
"""BUG-1318: D9 marriage rating is an evidence band, not an outcome claim.
|
||
|
||
Upstream f891a2c1. The five bands must not say the relationship is stable,
|
||
ending, repeated, or in need of premarital counseling. The DK evidence line
|
||
keeps the 0-1 index and does not print a fake /100 score.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import importlib.util
|
||
import json
|
||
import os
|
||
import re
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
ROOT = os.path.join(os.path.dirname(__file__), "..")
|
||
SCRIPTS = os.path.join(ROOT, "scripts")
|
||
if SCRIPTS not in sys.path:
|
||
sys.path.insert(0, SCRIPTS)
|
||
|
||
from jyotish_engine import compute_chart_data # noqa: E402
|
||
|
||
|
||
def _api_handler():
|
||
"""Reuse the existing unbound handler helper. Do not add another forgery site."""
|
||
path = os.path.join(os.path.dirname(__file__), "test_api_server_security.py")
|
||
spec = importlib.util.spec_from_file_location("_api_security_helpers", path)
|
||
module = importlib.util.module_from_spec(spec)
|
||
spec.loader.exec_module(module)
|
||
return module._handler()
|
||
from marriage_counting import ( # noqa: E402
|
||
D9_CLAIM_BOUNDARY,
|
||
D9_EVIDENCE_BANDS,
|
||
_assess_d9_marriage_quality,
|
||
marriage_counting_full_analysis,
|
||
render_d9_evidence_report,
|
||
)
|
||
from varga import calc_varga # noqa: E402
|
||
|
||
BANNED = re.compile(r"稳定|离婚|再婚|婚前咨询|几段")
|
||
|
||
|
||
def _quality(points_chart: dict) -> dict:
|
||
return _assess_d9_marriage_quality(points_chart, None)
|
||
|
||
|
||
def test_five_bands_have_no_outcome_claims_and_keep_the_boundary() -> None:
|
||
samples = {
|
||
"supportive_evidence_stronger": {"Venus": 331.0, "Mars": 271.0, "Jupiter": 91.0},
|
||
"supportive_evidence_mixed_positive": {"Venus": 31.0},
|
||
"mixed_evidence": {"Venus": 10.0},
|
||
"pressure_evidence_mixed": {"Venus": 151.0},
|
||
"pressure_evidence_stronger": {"Venus": 151.0, "Mars": 91.0, "Jupiter": 271.0},
|
||
}
|
||
seen = []
|
||
for key, chart in samples.items():
|
||
quality = _quality(chart)
|
||
assert quality["quality_band"] == key
|
||
assert quality["claim_boundary"] == D9_CLAIM_BOUNDARY
|
||
assert quality["claim_boundary_en"]
|
||
assert not BANNED.search(quality["quality_rating"])
|
||
assert not BANNED.search(quality["quality_rating_en"])
|
||
seen.append(quality["quality_band"])
|
||
assert seen == [band[0] for band in D9_EVIDENCE_BANDS]
|
||
|
||
|
||
def test_public_chart_report_snapshots_in_both_languages() -> None:
|
||
cases = json.loads(
|
||
Path(ROOT, "references/real_case_calibration/minute_rectification_development_v1.json").read_text(encoding="utf-8")
|
||
)["cases"]
|
||
birth = next(case for case in cases if case["case_id"] == "steve_jobs_1955_development")["birth"]
|
||
assert birth["source"]["rodden_rating"] == "AA"
|
||
year, month, day = (int(part) for part in birth["date"].split("-"))
|
||
hour, minute = (int(part) for part in birth["time"].split(":"))
|
||
chart, *_ = compute_chart_data(
|
||
year, month, day, hour, minute,
|
||
birth["latitude"], birth["longitude"], birth["timezone_offset"],
|
||
ayanamsa_name="raman",
|
||
)
|
||
longitudes = {name: row["degree_raw"] for name, row in chart["planets"].items()}
|
||
d9 = {}
|
||
for name, lon in longitudes.items():
|
||
divisional = calc_varga(lon, 9)
|
||
d9[name] = divisional["sign_idx"] * 30 + divisional["degree_in_sign"]
|
||
result = marriage_counting_full_analysis(chart["houses"]["house_7"]["lord"], longitudes, d9)
|
||
quality = result["d9_marriage_quality"]
|
||
assert quality["quality_band"] == "mixed_evidence"
|
||
assert quality["quality_points"] == 0
|
||
chinese = render_d9_evidence_report(quality, "zh")
|
||
english = render_d9_evidence_report(quality, "en")
|
||
assert chinese == (
|
||
"D9 证据档位:证据混杂\n"
|
||
"D9 结构证据指数,不预测婚姻次数、稳定、离婚、伴侣好坏,也不提示需要婚前咨询"
|
||
)
|
||
assert english == (
|
||
"D9 evidence band: Mixed evidence\n"
|
||
"D9 structural evidence index. It does not predict marriage count, stability, "
|
||
"divorce, or partner quality, and it does not suggest premarital counseling."
|
||
)
|
||
assert "/100" not in chinese
|
||
assert "/100" not in english
|
||
|
||
|
||
def test_dk_evidence_line_prints_the_zero_to_one_index() -> None:
|
||
cases = json.loads(
|
||
Path(ROOT, "references/real_case_calibration/minute_rectification_development_v1.json").read_text(encoding="utf-8")
|
||
)["cases"]
|
||
birth = next(case for case in cases if case["case_id"] == "steve_jobs_1955_development")["birth"]
|
||
year, month, day = (int(part) for part in birth["date"].split("-"))
|
||
hour, minute = (int(part) for part in birth["time"].split(":"))
|
||
chart, asc_idx, *_ = compute_chart_data(
|
||
year, month, day, hour, minute,
|
||
birth["latitude"], birth["longitude"], birth["timezone_offset"],
|
||
ayanamsa_name="raman",
|
||
)
|
||
longitudes = {name: row["degree_raw"] for name, row in chart["planets"].items()}
|
||
handler = _api_handler()
|
||
evidence = handler._compute_relationship_timing_evidence(
|
||
{},
|
||
chart["planets"],
|
||
longitudes,
|
||
asc_idx,
|
||
chart["ascendant"]["sign"],
|
||
)
|
||
notes = [row["note"] for row in evidence["evidence"] if row.get("label") == "Darakaraka (DK)"]
|
||
assert len(notes) == 1
|
||
assert "/100" not in notes[0]
|
||
assert "婚姻质量指数" in notes[0]
|
||
assert "(0到1)" in notes[0]
|
||
score = evidence["darakaraka"]["marriage_quality_score"]
|
||
assert isinstance(score, float)
|
||
assert 0.0 <= score <= 1.0
|
||
assert str(score) in notes[0]
|