from __future__ import annotations import json import unittest from pathlib import Path from scripts.rectification.varga_style_calibration_report import summarize ROOT = Path(__file__).resolve().parents[1] def _answer(group: str, answer_class: str, recorded: str, chosen: str) -> dict: other = "天蝎座" if recorded == "天秤座" else "天秤座" yes_sign = chosen if answer_class == "yes" else other weak_sign = chosen if answer_class == "weak_yes" else (recorded if recorded != yes_sign else other) return { "group": group, "answer_class": answer_class, "recorded_sign": recorded, "options": [ {"answer_class": "yes", "sign": yes_sign}, {"answer_class": "weak_yes", "sign": weak_sign}, ], } def _case(case_id: str, source: str, answers: list[dict], before: int = 2, after: int = 2) -> dict: return { "case_id_hash": case_id, "birth_time_source": source, "recorded_minute": "04:51", "uncertainty_before_minutes": before, "uncertainty_after_minutes": after, "answers": answers, } class VargaStyleCalibrationReportTest(unittest.TestCase): def test_random_third_and_high_hit_rate(self) -> None: random_third = { "cases": [ _case("a", "hospital_record", [_answer("d9", "yes", "天秤座", "天秤座")]), _case("b", "hospital_record", [_answer("d9", "yes", "天秤座", "天蝎座")]), _case("c", "hospital_record", [_answer("d9", "weak_yes", "天秤座", "天蝎座")]), ] } random_report = summarize(random_third) self.assertEqual(random_report["d9"]["n"], 3) self.assertEqual(random_report["d9"]["hit_rate"], 0.333) self.assertEqual(random_report["d10"]["n"], 0) self.assertIsNone(random_report["d10"]["hit_rate"]) high = { "cases": [ _case(str(index), "hospital_record", [ _answer("d10", "yes", "巨蟹座", "巨蟹座" if index < 9 else "狮子座"), ]) for index in range(10) ] } high_report = summarize(high) self.assertEqual(high_report["d10"]["n"], 10) self.assertEqual(high_report["d10"]["hit_rate"], 0.9) def test_filters_non_hospital_and_wide_uncertainty(self) -> None: payload = { "cases": [ _case("hospital", "hospital_record", [_answer("nakshatra", "yes", "角宿", "角宿")]), _case("approx", "approximate", [_answer("nakshatra", "yes", "角宿", "角宿")]), _case("wide", "hospital_record", [_answer("nakshatra", "yes", "角宿", "角宿")], before=15, after=15), ] } report = summarize(payload) self.assertEqual(report["nakshatra"]["n"], 1) self.assertEqual(report["nakshatra"]["hit_rate"], 1.0) def test_summary_has_no_case_ids(self) -> None: payload = { "cases": [ _case("secret-hash", "hospital_record", [_answer("d9", "yes", "天秤座", "天秤座")]), ] } dumped = json.dumps(summarize(payload), ensure_ascii=False) self.assertNotIn("secret-hash", dumped) self.assertNotIn("04:51", dumped) if __name__ == "__main__": unittest.main()