Hide engine branding, gate supported divisional columns, align house cells, and add accessible symbol help. Reduce desktop chart width and stabilize the waiting slot. Validated with 78 browser checks and 87 focused frontend tests. Full suite retains 29 identical baseline loader failures; no new failures. Co-Authored-By: Claude Code <noreply@anthropic.com>
134 lines
5.8 KiB
Python
134 lines
5.8 KiB
Python
"""The chart page's dignity and varga-meaning tables must be the engine's.
|
|
|
|
`frontend/src/lib/vedic-chart-tables.json` is read by the chart-page mapper so
|
|
the divisional tables can show 入旺 / 自宫 / 落陷 without a second hand-written
|
|
rule set. This test pins it to the constants `jyotish_engine._get_dignity_level`
|
|
uses and to `divisional_charts_extended.VargaType`.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT / "scripts"))
|
|
|
|
import divisional_charts_extended # noqa: E402
|
|
import jyotish_engine # noqa: E402
|
|
from consultation_native_layers import build_d9_summary # noqa: E402
|
|
|
|
TABLES = json.loads((ROOT / "frontend/src/lib/vedic-chart-tables.json").read_text(encoding="utf-8"))
|
|
PLANETS = ["Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn", "Rahu", "Ketu"]
|
|
|
|
|
|
def _table_dignity(planet: str, sign: str) -> str | None:
|
|
"""Same precedence as `vargaDignity` in frontend/src/lib/chart-view-varga.ts."""
|
|
if TABLES["exaltation"].get(planet) == sign:
|
|
return "EXALTED"
|
|
if TABLES["signLords"].get(sign) == planet or TABLES["nodeOwnSign"].get(planet) == sign:
|
|
return "OWN_SIGN"
|
|
if TABLES["debilitation"].get(planet) == sign:
|
|
return "DEBILITATED"
|
|
return None
|
|
|
|
|
|
def test_tables_equal_engine_constants() -> None:
|
|
assert TABLES["signLords"] == jyotish_engine.SIGN_LORDS
|
|
assert TABLES["exaltation"] == jyotish_engine.EXALTATION
|
|
assert TABLES["debilitation"] == jyotish_engine.DEBILITATION
|
|
|
|
|
|
def test_every_planet_sign_pair_matches_engine_dignity_level() -> None:
|
|
for planet in PLANETS:
|
|
for sign in jyotish_engine.SIGN_LORDS:
|
|
# No degree and no chart context: the varga table shows the sign
|
|
# dignity only (no moolatrikona band, no neecha bhanga, no friendship).
|
|
engine = jyotish_engine._get_dignity_level(planet, sign)
|
|
expected = engine if engine in {"EXALTED", "OWN_SIGN", "DEBILITATED"} else None
|
|
if engine == "NEECHA_BHANGA":
|
|
expected = "DEBILITATED"
|
|
assert _table_dignity(planet, sign) == expected, (planet, sign, engine)
|
|
|
|
|
|
def test_varga_meanings_equal_engine_varga_types() -> None:
|
|
engine = {str(v.division): v.meaning for v in divisional_charts_extended.VargaType if v.division <= 60}
|
|
assert TABLES["vargaMeaning"] == engine
|
|
for division in ("40", "45", "60"):
|
|
assert division in TABLES["vargaMeaning"]
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def d9_projection() -> tuple[dict, dict]:
|
|
"""Run the real server mapper, not a Python imitation of its comparison.
|
|
|
|
The checked-in golden is a fictional chart, Raman ayanamsa / mean node.
|
|
No ephemeris is recomputed under a different process-global ayanamsa.
|
|
"""
|
|
frontend = ROOT / "frontend"
|
|
node = shutil.which("node")
|
|
tsx = frontend / "node_modules/tsx/dist/cli.mjs"
|
|
if not node or not tsx.is_file():
|
|
pytest.skip("D9 mapper/native comparison requires Node and frontend tsx dependencies")
|
|
golden = json.loads((frontend / "tests/fixtures/chart-view-golden.json").read_text(encoding="utf-8"))
|
|
assert golden["chart"]["birth"]["ayanamsa_name"] == "raman"
|
|
assert golden["chart"]["birth"]["node_mode"] == "mean"
|
|
script = """
|
|
import { readFileSync } from 'node:fs';
|
|
import { buildChartView } from './src/lib/chart-view-mapper.ts';
|
|
const golden = JSON.parse(readFileSync('./tests/fixtures/chart-view-golden.json', 'utf8'));
|
|
const birth = golden.chart.birth;
|
|
const view = buildChartView({
|
|
chart: golden.chart, varga: golden.varga_full, chara: null, western: null,
|
|
profile: {
|
|
name: 'Synthetic', date: birth.date, time: birth.time,
|
|
latitude: birth.lat, longitude: birth.lon, timezoneOffset: 8,
|
|
ayanamsa: birth.ayanamsa_name, birthTimeStatus: 'confirmed',
|
|
},
|
|
asOf: '2026-09-15',
|
|
});
|
|
process.stdout.write(JSON.stringify(view.vedic.vargas.find(varga => varga.id === 'D9')));
|
|
"""
|
|
completed = subprocess.run(
|
|
[node, str(tsx), "--eval", script],
|
|
cwd=frontend, text=True, encoding="utf-8", capture_output=True, timeout=60, check=False,
|
|
)
|
|
assert completed.returncode == 0, completed.stderr
|
|
return golden, json.loads(completed.stdout)
|
|
|
|
|
|
def test_d9_projected_planets_match_native_vargottama(d9_projection: tuple[dict, dict]) -> None:
|
|
golden, projected = d9_projection
|
|
natal = golden["chart"]["planets"]
|
|
d9 = golden["varga_full"]["result"]["D9_Navamsa"]
|
|
native = jyotish_engine._calc_vargottama(natal, {"D9_Navamsa": d9["planets"]})
|
|
assert projected["supportsDignity"] is True
|
|
assert projected["supportsVargottama"] is True
|
|
assert len(projected["rows"]) == len(PLANETS)
|
|
results = set()
|
|
for row in projected["rows"]:
|
|
expected = native[row["name"]]
|
|
assert row["sign"] == expected["d9_sign"]
|
|
assert row["natalSign"] == expected["d1_sign"]
|
|
assert row["vargottama"] is expected["is_vargottama"]
|
|
results.add(row["vargottama"])
|
|
assert results == {True, False}, "golden must exercise both valid outcomes"
|
|
|
|
|
|
def test_d9_projected_ascendant_matches_native_summary(d9_projection: tuple[dict, dict]) -> None:
|
|
# _calc_vargottama handles planets, NOT the ascendant; use the native lagna
|
|
# summary path for this separate contract instead of attributing it there.
|
|
golden, projected = d9_projection
|
|
native = build_d9_summary(
|
|
jyotish_engine, golden["chart"], {"varga_full": golden["varga_full"]["result"]},
|
|
)
|
|
assert native["status"] == "executed"
|
|
assert projected["ascendant"]["sign"] == native["lagna"]
|
|
assert projected["ascendant"]["natalSign"] == golden["chart"]["ascendant"]["sign"]
|
|
assert projected["ascendant"]["vargottama"] is native["lagna_vargottama"]
|