# Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca """Shared fixtures. Tests run on the SYNTHETIC table (built in memory from the generator, no private data). ``pytest --real`` additionally runs the tests marked ``real`` on data/processed/*.""" from __future__ import annotations import polars as pl import pytest from agentic_valuation.config import PROCESSED, SYNTHETIC, load_config from agentic_valuation.data.build import build_from_synthetic from agentic_valuation.data.splits import assign_splits, stratified_subsample from agentic_valuation.data.synthetic import generate from agentic_valuation.features.matrix import build_feature_matrix SYN_N_BY_SPLIT = {"validation": 40, "test": 60, "holdout": 30} def pytest_addoption(parser: pytest.Parser) -> None: parser.addoption("--real", action="store_true", default=False, help="also run checks on the real processed data") def pytest_configure(config: pytest.Config) -> None: config.addinivalue_line("markers", "real: needs data/processed (private); enabled with --real") def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None: if config.getoption("--real"): return skip = pytest.mark.skip(reason="needs --real and the private processed data") for item in items: if "real" in item.keywords: item.add_marker(skip) @pytest.fixture(scope="session") def cfg() -> dict: return load_config("data") @pytest.fixture(scope="session") def syn_analytic() -> pl.DataFrame: src = SYNTHETIC / "synthetic_transactions.parquet" raw = pl.read_parquet(src) if src.exists() else generate(20_000) df, _ = build_from_synthetic(raw) return df @pytest.fixture(scope="session") def syn_splits(syn_analytic: pl.DataFrame, cfg: dict) -> pl.DataFrame: return assign_splits(syn_analytic, cfg) @pytest.fixture(scope="session") def syn_subsamples(syn_analytic: pl.DataFrame, syn_splits: pl.DataFrame, cfg: dict) -> pl.DataFrame: return stratified_subsample(syn_analytic, syn_splits, cfg, n_by_split=SYN_N_BY_SPLIT) @pytest.fixture(scope="session") def syn_matrix(syn_analytic: pl.DataFrame, syn_splits: pl.DataFrame) -> pl.DataFrame: return build_feature_matrix(syn_analytic, syn_splits, geo=None, comps_summary=True) @pytest.fixture(scope="session") def real_bundle() -> dict[str, pl.DataFrame]: paths = {k: PROCESSED / f"{k}.parquet" for k in ("analytic", "splits", "llm_subsamples", "feature_matrix", "geo_features")} if not paths["analytic"].exists(): pytest.skip("data/processed/analytic.parquet missing") return {k: pl.read_parquet(p) for k, p in paths.items() if p.exists()}