"""Golden facts use deliberately fictional input, never a user birth record.""" import copy import json from pathlib import Path from scripts.reader_dasha_applicability import BOUNDARY, render_dasha_applicability from scripts.report_fact_table_contract import validate_fact_tables ROOT = Path(__file__).resolve().parents[1] def test_golden_applicability_never_relaxes_missing_or_inapplicable_families(): packet = json.loads((ROOT / "frontend/tests/fixtures/report-density-fictional-reader.json").read_text(encoding="utf8")) original = copy.deepcopy(packet) output = render_dasha_applicability(packet) families = packet["worksheets"]["timing_and_predictive_systems"]["dasha_master_pack"]["families"] assert len(families) == 15 assert output.count(BOUNDARY) == len(families) - 1 + 2 for key, value in families.items(): if key == "vimshottari": assert "| Vimshottari |" not in output continue name = "Kala Chakra" if key == "kala_chakra" else key.replace("_", "-").title() assert f"| {name} |" in output if value.get("reason"): from scripts.reader_dasha_applicability import REASON_LABELS assert REASON_LABELS[value["reason"]] in output assert value["reason"] not in output assert all(name in output for name in ["Narayana", "Tribhagi-40", "Shattrimshatsama", "Satabdika", "Mudda", "Patyayini"]) assert "月宿与月相组合未满足该大运的适用条件" in output assert "本地计算尚未提供可用周期" in output assert packet == original def test_golden_narayana_periods_and_readable_known_and_unknown_reasons(): packet = json.loads((ROOT / "frontend/tests/fixtures/report-density-fictional-reader.json").read_text(encoding="utf8")) timing = packet["worksheets"]["timing_and_predictive_systems"] assert len(timing["narayana_dasha"]["mahadasha_sequence"]) == 12 assert len(timing["narayana_dasha"]["dense_boundaries"]) == 156 output = render_dasha_applicability(packet) narayana = next(line for line in output.splitlines() if line.startswith("| Narayana |")) assert "本次已返回周期" in narayana assert "这不代表已完成多引擎验证" in narayana assert "缺少可核对周期" not in narayana assert "本次计算未提供帕特雅伊尼年运周期" in output assert "patyayini_dasha_missing" not in output timing["annual_tajika_pack"]["patyayini_dasha"]["reason"] = "unknown_internal_reason_123 arbitrary English detail" unknown = render_dasha_applicability(packet) assert "暂无可核对的详细说明" in unknown assert "unknown_internal_reason_123" not in unknown assert "arbitrary English detail" not in unknown def test_legacy_applicability_discloses_missing_evidence_without_guessing_families(): output = render_dasha_applicability({}) assert "缺少本次计算的结构化适用性证据" in output assert BOUNDARY not in output def test_full_golden_shared_markdown_is_byte_identical_and_reader_copy_is_clean(): from types import SimpleNamespace from scripts.professional_report_reference import build_professional_report_reference from scripts.reader_appendix_language import clean_reader_appendix_markdown packet = json.loads((ROOT / "frontend/tests/fixtures/report-density-fictional-reader.json").read_text(encoding="utf8")) raw = packet["markdown"] engine = SimpleNamespace(build_professional_report_reference_packet=lambda *args: packet, render_pl9_markdown=lambda value: raw) handler = SimpleNamespace(_high_rigor_birth_payload=lambda body: {"year": 2000, "hour": 12, "minute": 0, "today": "2026-09-22"}, _compute_full_reading_for_thematic=lambda birth: {}) for include in (False, True): result = build_professional_report_reference(handler, {"format": "markdown", "include_fact_tables": include}, engine=engine) assert result["markdown"].encode("utf8") == raw.encode("utf8") if include: assert result["reader_dasha_applicability"] == packet["reader_dasha_applicability"] clean = clean_reader_appendix_markdown(raw) assert "pl9" in raw.lower() assert "pl9" not in clean.lower() assert len(clean.splitlines()) == len(raw.splitlines()) assert sum(line.startswith("|") for line in clean.splitlines()) == sum(line.startswith("|") for line in raw.splitlines()) for field in ("degree_in_sign", "sign_cn", "nakshatra_lord"): assert clean.count(field) == raw.count(field) def test_optional_table_validator_fails_closed_on_bad_shape(): errors = [] validate_fact_tables([{"id": "annual"}], lambda *error: errors.append(error)) assert errors errors.clear() validate_fact_tables([], lambda *error: errors.append(error)) assert not errors def test_fact_subtable_contract_uses_golden_periods_and_keeps_legacy_snapshots(): import jsonschema packet = json.loads((ROOT / "frontend/tests/fixtures/report-density-fictional-engine.json").read_text(encoding="utf8")) source = "worksheets.timing_and_predictive_systems.dasha" timeline = packet["worksheets"]["timing_and_predictive_systems"]["dasha"]["timeline"] rows = [{"sourcePath": f"{source}.timeline[{index}]", "cells": [period["lord_cn"], period["start"], period["end"], f'{period["full_years"]:.2f}', "是" if period["is_current"] else "否"]} for index, period in enumerate(timeline)] table = {"id": "vimshottari", "title": "Vimshottari 主运", "claimStatus": "parameter_sensitive", "sourcePath": source, "note": "原始计算供核对。", "columns": ["主运", "起", "止", "年数", "当前"], "rows": rows} current_index, current = next((index, period) for index, period in enumerate(timeline) if period["is_current"]) child_source = f"{source}.timeline[{current_index}]" child = {"id": "antardasha", "title": "当前主运下分运", "sourcePath": child_source, "note": "原始计算供核对。", "columns": ["分运", "起", "止", "当前"], "rows": [{"sourcePath": f"{child_source}.antardasha_timeline[{index}]", "cells": [period["lord_cn"], period["start"], period["end"], "是" if period["is_current"] else "否"]} for index, period in enumerate(current["antardasha_timeline"])]} schema = json.loads((ROOT / "contracts/personal-report/report-document.v2.schema.json").read_text(encoding="utf8")) contract = {"$ref": "#/definitions/factTable", "definitions": schema["definitions"]} for candidate in [table, {**table, "subtables": [child]}]: errors = [] validate_fact_tables([candidate], lambda *error: errors.append(error)) assert not errors jsonschema.validate(candidate, contract) for mutation in ("row_width", "origin", "duplicate", "unknown_key"): invalid = copy.deepcopy({**table, "subtables": [child]}) if mutation == "row_width": invalid["subtables"][0]["rows"][0]["cells"].pop() elif mutation == "origin": invalid["subtables"][0]["sourcePath"] = "worksheets.other" elif mutation == "duplicate": invalid["subtables"].append(copy.deepcopy(child)) else: invalid["subtables"][0]["raw"] = True errors = [] validate_fact_tables([invalid], lambda *error: errors.append(error)) assert errors, mutation