Files
Jyotisha/tests/run_celebrity_regression.py
T

160 lines
5.2 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
"""
名人案例批量回归测试 v1.0
验证引擎对22个名人案例的排盘和解盘能力
"""
import json
import sys
import os
import subprocess
# 路径
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ENGINE = os.path.join(REPO_ROOT, "scripts", "jyotish_engine.py")
CASES_FILE = os.path.join(REPO_ROOT, "tests", "celebrity_cases.json")
SIGNS = ['Aries','Taurus','Gemini','Cancer','Leo','Virgo',
'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces']
def run_case(case):
"""对单个案例跑 full-reading 引擎"""
cmd = [
sys.executable, ENGINE, "chart",
"--year", str(case["year"]),
"--month", str(case["month"]),
"--day", str(case["day"]),
"--hour", str(case["hour"]),
"--minute", str(case["minute"]),
"--lat", str(case["lat"]),
"--lon", str(case["lon"]),
"--tz", str(case["tz"]),
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120, cwd=REPO_ROOT)
if result.returncode != 0:
return {"error": result.stderr[:500]}
try:
return json.loads(result.stdout)
except json.JSONDecodeError:
return {"error": f"JSON解析失败: {result.stdout[:300]}"}
def extract_chart_summary(chart_data):
"""从引擎输出中提取解盘关键结论"""
if not chart_data or "error" in chart_data:
return None
planets = {}
for pname in ['Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu']:
p = chart_data.get("planets", {}).get(pname, {})
if p:
sign_idx = int(p.get("longitude", 0) / 30) % 12
planets[pname] = {
"sign": SIGNS[sign_idx],
"house": int(p.get("house", 0)),
"degree": round(p.get("longitude", 0) % 30, 2),
}
asc_sign = SIGNS.get(int(chart_data.get("ascendant", {}).get("sign_index", 0)), "?")
return {
"lagna": asc_sign,
"planets": planets,
"summary": f"上升{asc_sign}"
}
def run_all():
with open(CASES_FILE, "r", encoding="utf-8") as f:
cases = json.load(f)
results = []
passed = 0
failed = 0
print(f"{'='*80}")
print(f"名人案例批量回归测试")
print(f"案例数: {len(cases)}")
print(f"测试时间: 引擎 chart 命令排盘正确性")
print(f"{'='*80}")
for i, case in enumerate(cases, 1):
name = case["name"]
print(f"\n[{i}/{len(cases)}] {name} ({case['year']}-{case['month']:02d}-{case['day']:02d})")
data = run_case(case)
if "error" in data:
print(f" ❌ 引擎错误: {data['error'][:100]}")
failed += 1
results.append({"id": case["id"], "name": name, "status": "error", "detail": data["error"]})
continue
# 提取信息
has_asc = "ascendant" in data
planet_count = len(data.get("planets", {}))
status = "" if has_asc else "⚠️"
print(f" {status} 上升: {has_asc}, 行星数: {planet_count}")
# 与已知数据比对(如果有)
known_check = []
if case.get("known_lagna") and has_asc:
asc_sign = SIGNS[data.get("ascendant", {}).get("sign_index", 0) % 12]
match = "" if asc_sign == case["known_lagna"] else ""
known_check.append(f"上升: 预期{case['known_lagna']} 实际{asc_sign} {match}")
for check in known_check:
print(f" {check}")
passed_count = sum(1 for c in known_check if "" in c)
results.append({
"id": case["id"],
"name": name,
"status": "passed" if has_asc else "warn",
"key_data": known_check,
})
passed += 1
# 汇总报告
print(f"\n\n{'='*80}")
print(f"汇总报告")
print(f"{'='*80}")
print(f"总计: {len(cases)} 案例")
print(f"通过: {passed}")
print(f"失败: {failed}")
print(f"通过率: {passed/len(cases)*100:.0f}%")
print(f"\n{'='*80}")
print(f"案例清单")
print(f"{'='*80}")
print(f"{'姓名':>22} | {'状态':>4} | {'出生日期':>14} | {'上升':>8} | {'星盘结论'}")
print("-"*80)
for r in results:
status_mark = "" if r["status"] == "passed" else ""
case = next(c for c in cases if c["id"] == r["id"])
conclusion = case.get("summary_conclusion", "")[:35]
print(f"{r['name']:>22} | {status_mark:>4} | "
f"{case['year']}-{case['month']:02d}-{case['day']:02d} | "
f"{'...' if r['key_data'] else '?':>8} | {conclusion}")
# 保存报告
report = {
"total": len(cases),
"passed": passed,
"failed": failed,
"pass_rate": f"{passed/len(cases)*100:.0f}%",
"results": results,
}
report_path = os.path.join(REPO_ROOT, "tests", "celebrity_regression_report.json")
with open(report_path, "w", encoding="utf-8") as f:
json.dump(report, f, ensure_ascii=False, indent=2)
print(f"\n报告已保存: {report_path}")
if __name__ == "__main__":
run_all()