#!/usr/bin/env python # -*- coding: utf-8 -*- """ Golden Test:用 JSON fixture 回归报表 transform 流水线关键输出。 后续可追加 JNPF 导出的样例 fixture 做对比。 """ from __future__ import annotations import json import math from pathlib import Path from typing import Any, Dict, List from online_dev.report_manager.engine.convert import transform from online_dev.report_manager.engine.dataset_transform import transform_dataset_rows _FIXTURES_DIR = Path(__file__).parent / "fixtures" def _load_fixture(name: str) -> dict: path = _FIXTURES_DIR / name with open(path, encoding="utf-8") as f: return json.load(f) def _cell_v(snapshot: dict, sheet_id: str, row: int, col: int) -> str: sheet = (snapshot.get("sheets") or {}).get(sheet_id) or {} cell = (sheet.get("cellData") or {}).get(str(row), {}).get(str(col), {}) v = cell.get("v") return "" if v is None else str(v) def _prepare_datasets(fixture: dict) -> Dict[str, List[Any]]: raw = fixture.get("datasets") or {} field_mapping_root = fixture.get("field_mapping") or {} version_convert = fixture.get("convert_config") out: Dict[str, List[Any]] = {} for alias, rows in raw.items(): mapping = field_mapping_root.get(alias) if isinstance(field_mapping_root, dict) else field_mapping_root out[alias] = transform_dataset_rows( rows, field_mapping=mapping, version_convert=version_convert, alias=alias, ) return out def _values_match(expected: Any, actual: str, *, tolerance: float = 1e-6) -> bool: if expected == actual: return True try: exp_f = float(expected) act_f = float(actual) return math.isclose(exp_f, act_f, rel_tol=tolerance, abs_tol=tolerance) except (TypeError, ValueError): return False def _run_golden_fixture(fixture: dict) -> None: datasets = _prepare_datasets(fixture) out = transform( fixture["snapshot"], fixture.get("cells") or {}, datasets, fixture.get("params") or {}, column_list=fixture.get("column_list"), fence_list=fixture.get("fence_list"), ) failures: List[str] = [] for sheet_id, cells in (fixture.get("expect") or {}).items(): for addr, expected in cells.items(): row_s, col_s = addr.split(",", 1) actual = _cell_v(out, sheet_id, int(row_s), int(col_s)) exp_str = "" if expected is None else str(expected) if not _values_match(exp_str, actual): failures.append( f" {sheet_id}!{addr}: expected {exp_str!r}, got {actual!r}" ) if failures: name = fixture.get("name") or "unnamed" msg = f"{name} failed ({len(failures)} cell(s)):\n" + "\n".join(failures) raise AssertionError(msg) def test_golden_list_down(): _run_golden_fixture(_load_fixture("golden_list_down.json")) def test_all_golden_fixtures(): for path in sorted(_FIXTURES_DIR.glob("golden_*.json")): _run_golden_fixture(_load_fixture(path.name)) if __name__ == "__main__": test_all_golden_fixtures() print(f"ok ({len(list(_FIXTURES_DIR.glob('golden_*.json')))} fixtures)")