Files
Jyotisha/tests/test_functional_role_table.py
T
ClaudeandClaude Opus 5.5 578a361460 feat(chart): functional roles, 7/8 Chara Karaka and three new 特殊点 groups (#163 1-3)
/api/chart_points:
- karaka_scheme 7 (default) / 8 / both; shared ranking in
  chart_view_points/karaka_rank.py (unrounded in-sign degree, Rahu reversed
  in the 8 scheme, Ketu out). Bodies equal at full precision mark only the
  roles they span as tied; Goel uses the same ranking (BUG-1512).
- functional_roles: v2 BPHS ch.34 profile laid out per body, nodes pending,
  Yogakaraka / Badhaka / Kendradhipati (conditions not evaluated) as
  separate labels.
- sensitive_points (Bhrigu Bindu per chart node_mode, 64th Navamsa, 22nd
  Drekkana sign-only), sahams (PVR Table 74, nine first, all kept),
  goel_points (printed-text policy, worked example beside it).

盘面数据: 行星 gets Chara Karaka (AK · 自我, 七星/八星 switch), 自然属性,
管辖宫位, 功能角色, 补充身份; 特殊点 splits into 特殊上升 / 敏感点 / Saham /
Goel 特殊点 and the board's 特殊点 layer follows the open group.

jaimini.py, functional_benefics.py and varga.py are untouched (rectification
frozen identity).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-02 20:35:31 +08:00

39 lines
1.6 KiB
Python

"""Functional role table (issue #163): a layout of the v2 profile, never a reclassification."""
from __future__ import annotations
import sys
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
for path in (ROOT, ROOT / "scripts"):
if str(path) not in sys.path:
sys.path.insert(0, str(path))
from functional_benefics import SIGNS, derive_functional_benefic_malefic # noqa: E402
from chart_view_points.functional_roles import functional_role_table # noqa: E402
from yoga_engine import badhaka_house # noqa: E402
@pytest.mark.parametrize("sign", SIGNS)
def test_every_lagna_mirrors_the_profile(sign):
base = derive_functional_benefic_malefic(sign)
table = functional_role_table(sign)
rows = {row["planet"]: row for row in table["rows"]}
for planet in ("Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn"):
expected = "benefic" if planet in base["functional_benefics"] else "malefic" if planet in base["functional_malefics"] else "neutral"
assert rows[planet]["functional"] == expected
assert rows[planet]["owned_houses"] == base["owned_houses"][planet]
assert ({"key": "yogakaraka"} in rows[planet]["identities"]) == (planet in base["yogakarakas"])
for node in ("Rahu", "Ketu"):
assert rows[node]["functional"] == "pending"
badhaka = [planet for planet, row in rows.items() if any(item["key"] == "badhaka" for item in row["identities"])]
assert len(badhaka) == 1
assert rows[badhaka[0]]["owned_houses"].count(badhaka_house(sign)) == 1
def test_unknown_lagna_blocks():
assert functional_role_table("Nowhere")["status"] == "blocked"