Files
Jyotisha/tests/test_d9_evidence_bands.py
T
jesse-uxandGrok (agent loop) d32ad7b7b1 婚恋评级改成证据档位,配偶星分数不再写成百分制(BUG-1318,上游 f891a2c1)
五档不再写稳定、离婚、再婚或婚前咨询,并写明这是结构指数。公开盘中英文各锁一条。配偶星证据行改成 0 到 1,不乘 100。pytest tests/test_d9_evidence_bands.py 3 通过。

Co-Authored-By: Grok (agent loop)
2026-10-14 00:48:25 +08:00

135 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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]