Goldens regenerated by the capture scripts (PYTHONHASHSEED=0, cache TTL 0; two runs byte-identical). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
93 lines
3.3 KiB
Python
93 lines
3.3 KiB
Python
"""T2 / T3 of TASK-consult-career-yoga-functional-20261002 (BUG-1174, BUG-1175)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from scripts.consultation_native_layers import (
|
|
TRADITIONAL_YOGA_LABEL,
|
|
build_traditional_yogas,
|
|
collect_consultation_yogas,
|
|
merge_detected_yogas,
|
|
)
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def _compact(item):
|
|
if isinstance(item, dict) and item.get("name"):
|
|
return {"name": item["name"]}
|
|
if isinstance(item, str) and item:
|
|
return {"name": item}
|
|
return None
|
|
|
|
|
|
class _Handler:
|
|
def __init__(self):
|
|
self.calls = 0
|
|
|
|
def _compute_yogas_api(self, body):
|
|
self.calls += 1
|
|
return {"result": {
|
|
"extended_yogas": [{"name": "Sasa Yoga"}, {"name": "Amala Yoga"}],
|
|
"rule_engine_yogas": [{"name": "Gajakesari Yoga"}],
|
|
}}
|
|
|
|
|
|
def test_rule_engine_runs_even_when_chart_already_has_yogas() -> None:
|
|
handler = _Handler()
|
|
chart = {"yogas": [{"name": "Amala Yoga"}, {"name": "Amala Yoga"}]}
|
|
merged = collect_consultation_yogas(handler, chart, {}, {"Sun": {}}, {"sign": "Aries"}, _compact)
|
|
assert handler.calls == 1
|
|
assert [row["name"] for row in merged] == ["Amala Yoga", "Sasa Yoga", "Gajakesari Yoga"]
|
|
|
|
|
|
def test_merge_dedupes_by_normalised_name() -> None:
|
|
merged = merge_detected_yogas([{"name": "Amala Yoga"}], [{"name": "amala yoga"}, {"name": "Amala"}, {"name": "Vosi Yoga"}])
|
|
assert [row["name"] for row in merged] == ["Amala Yoga", "Vosi Yoga"]
|
|
|
|
|
|
def test_engine_failure_keeps_the_chart_list() -> None:
|
|
class Broken:
|
|
def _compute_yogas_api(self, body):
|
|
raise RuntimeError("boom")
|
|
|
|
merged = collect_consultation_yogas(Broken(), {"yogas": ["Adhi Yoga"]}, {}, {}, None, _compact)
|
|
assert [row["name"] for row in merged] == ["Adhi Yoga"]
|
|
|
|
|
|
def test_server_no_longer_skips_the_rule_engine() -> None:
|
|
source = (ROOT / "scripts" / "jyotish_api_server.py").read_text(encoding="utf-8")
|
|
block = source[source.index("if not _consultation_layer_present(modules.get('yogas')):"):]
|
|
block = block[: block.index("routes = _consultation_declared_routes(body)")]
|
|
assert "collect_consultation_yogas" in block
|
|
assert "if not compact:" not in block
|
|
|
|
|
|
def _modules(hits, ungoverned):
|
|
return {"raman_support": {"yogas": {"status": "executed", "hits": hits, "ungoverned_detected": ungoverned}}}
|
|
|
|
|
|
def test_traditional_yogas_closed_list_only_and_fixed_label() -> None:
|
|
layer = build_traditional_yogas(_modules(
|
|
[{"name": "Gaja Kesari", "hit": True}],
|
|
[
|
|
{"name": "Sasa Yoga"},
|
|
{"name": "Neechabhanga Raja Yoga"},
|
|
{"name": "Neechabhanga Raja Yoga (Kendra)"},
|
|
{"name": "Budhaditya Yoga"},
|
|
{"name": "Surya-Budha Yoga"},
|
|
{"name": "Kemadruma Yoga"},
|
|
{"name": "Raja Yoga (Mutual Aspect)"},
|
|
],
|
|
))
|
|
assert layer["status"] == "executed"
|
|
assert layer["label"] == TRADITIONAL_YOGA_LABEL == "传统格局,本站未验证,只作参考"
|
|
assert layer["names"] == ["Sasa Yoga", "Gajakesari Yoga", "Neecha Bhanga Raja Yoga", "Budha-Aditya Yoga"]
|
|
|
|
|
|
def test_traditional_yogas_skip_misses_and_empty() -> None:
|
|
layer = build_traditional_yogas(_modules([{"name": "Gajakesari Yoga", "hit": False}], []))
|
|
assert layer["names"] == []
|
|
assert build_traditional_yogas({})["status"] == "blocked"
|