test: auto-generate 60-rule yoga test suite from 60-chart benchmark

- yoga_test_suite.json: 60 rules x True/False test cases generated
  from the 60-chart benchmark (40 rules have both True+False)
- run_yoga_test_suite.py: test runner, 97/100 passed, 3 known FN
  residuals (bahu_puthra, dehasthoulya, grihanasa)
- Inspired by PyJHora's hardcoded _from_planet_positions methodology
This commit is contained in:
732642856
2026-06-06 19:57:09 +08:00
parent 9a4cc24c12
commit 5b464a9078
2 changed files with 5326 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
"""
自动化 Yoga 测试运行器 — 从 yoga_test_suite.json 加载用例并批量验证
"""
import json, sys, os
SKILL_DIR = '/Users/wuyongnaren/.workbuddy/skills/jyotish-vedic-astrology'
sys.path.insert(0, os.path.join(SKILL_DIR, 'scripts'))
RULES_PATH = os.path.join(SKILL_DIR, 'references', 'yoga_rules.json')
from yoga_engine import YogaEngine
engine = YogaEngine(RULES_PATH)
def detect(rule_id, planets, asc, ctx=None):
return any(r.get('rule_id') == rule_id for r in engine.detect(planets, asc, context=ctx))
suite_path = os.path.join(SKILL_DIR, 'tests', 'yoga_test_suite.json')
with open(suite_path) as f:
suite = json.load(f)
passed = 0
failed = 0
failures = []
print(f'Yoga Test Suite: {len(suite)} rules')
print('=' * 60)
for entry in suite:
rid = entry['rule_id']
rid_short = rid[-30:] if len(rid) > 30 else rid
for mode in ['true', 'false']:
if mode not in entry: continue
d = entry[mode]
expected = (mode == 'true')
result = detect(rid, d['planets'], d['asc'], d.get('context'))
if result == expected:
passed += 1
else:
failed += 1
chart = d.get('chart', '?')
failures.append(f' FAIL: {rid_short:30s} {mode:5s} chart={chart} expect={expected} got={result}')
for f in failures:
print(f)
print(f'\nResults: {passed} passed, {failed} failed ({passed+failed} total)')
File diff suppressed because it is too large Load Diff