Files
Jyotisha/tests/test_marriage_counting_geometry_only.py
T
Jesse_ChenandClaude Opus 5.5 ba97fd5980 fix(marriage): counting method reports a neutral geometry index only; real Parivartana no longer crashes (BUG-1183/1184)
TASK-upstream-sync4-20261002 T1 (upstream yinduzhanxing 0afa2780 for the
idea; wording is ours, in Chinese, per decision 2). _interpret_marriage_count
and _marriage_recommendations no longer state relationship counts, order,
quality or loyalty; the Marriage-counting evidence is always neutral and
carries only geometric_index (the dead D9-quality line in the adjudication is
removed). The count is computed before the Parivartana override (the old order
raised UnboundLocalError) and the exchange check now tests a real exchange
instead of a conjunction with the dispositor.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-02 14:01:13 +08:00

71 lines
3.0 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.
#!/usr/bin/env python3
"""BUG-1183 / BUG-1184 (TASK-upstream-sync4-20261002 T1).
The marriage-counting method only reports a geometry index: no relationship
count, order, quality or loyalty claim, and the same advice for every index.
A real Parivartana no longer crashes the module, and a conjunction with the
dispositor is not mistaken for one.
"""
from __future__ import annotations
import os
import re
import sys
SCRIPTS = os.path.join(os.path.dirname(__file__), '..', 'scripts')
if SCRIPTS not in sys.path:
sys.path.insert(0, SCRIPTS)
from marriage_counting import marriage_counting_full_analysis # noqa: E402
BANNED = re.compile(r'再婚|段关系|第一段|第二段|终身关系|忠诚度|一次|两段|多段|婚姻/认真关系数量')
def _text(result) -> str:
return '\n'.join([
str(result.get('interpretation') or ''),
*[str(item) for item in result.get('recommendations') or []],
str(result.get('note') or ''),
])
def test_every_index_is_described_as_geometry_without_event_claims() -> None:
advice = set()
for d9_sign in range(12):
result = marriage_counting_full_analysis('Venus', {'Venus': 15.0}, {'Venus': d9_sign * 30 + 10.0})
index = d9_sign + 1
assert result['geometric_index'] == index
assert result['marriage_count'] == index # compatibility field, same value
assert result['interpretation'].startswith(f'关系几何指数 {index}:')
assert '不代表婚姻或关系的次数' in result['interpretation']
assert not BANNED.search(_text(result)), _text(result)
advice.add(tuple(result['recommendations']))
# 原值: 指数 1 / 2 / ≥3 给三套不同建议(含「第一段关系由吉星主导,质量较好」)
# 新值: 所有指数同一套中性说明
assert len(advice) == 1
def test_same_and_opposite_sign_are_described_without_quality() -> None:
same = marriage_counting_full_analysis('Venus', {'Venus': 15.0}, {'Venus': 10.0})
assert 'D1 与 D9 两个参照点落在同一星座。' in same['interpretation']
opposite = marriage_counting_full_analysis('Venus', {'Venus': 15.0}, {'Venus': 190.0})
assert 'D1 与 D9 两个参照点落在相对的星座。' in opposite['interpretation']
def test_real_parivartana_does_not_crash_and_conjunction_is_not_exchange() -> None:
# Venus (7th lord) in Aries, Mars in Libra: a true exchange.
exchanged = marriage_counting_full_analysis(
'Venus', {'Venus': 15.0, 'Mars': 185.0}, {'Venus': 160.0}, {'7': {}})
assert 'error' not in exchanged
assert exchanged['parivartana']['has_parivartana'] is True
# Counted from Libra (the exchanged sign) to Virgo: 12.
assert exchanged['geometric_index'] == 12
# Venus and Mars both in Aries: a conjunction with the dispositor, not an exchange.
conjunct = marriage_counting_full_analysis(
'Venus', {'Venus': 15.0, 'Mars': 20.0}, {'Venus': 160.0}, {'7': {}})
assert 'error' not in conjunct
assert conjunct['parivartana']['has_parivartana'] is False
assert conjunct['geometric_index'] == 6