"""End-to-end pipeline test on the clearly labelled synthetic fixture.""" import json import os import shutil from pathlib import Path import pytest def test_pipeline_on_synthetic(tmp_path, monkeypatch): from ucml import synthetic db = synthetic.make(tmp_path / "synthetic" / "autoka-synthetic.db", n_listings=1500) monkeypatch.setenv("UCML_ROOT", str(tmp_path)) monkeypatch.setenv("UCML_SNAPSHOT", str(db)) import importlib from ucml import config importlib.reload(config) from ucml import ingest, cleaning importlib.reload(ingest); importlib.reload(cleaning) (tmp_path / "data" / "raw" / "registry").mkdir(parents=True) real_reg = Path(__file__).resolve().parents[1] / "data" / "raw" / "registry" srcs = {"_comment": "synthetic", "sources": [{"id": f"synthdealer{i:02d}", "name": f"D{i}", "type": "direct", "region": "Montréal"} for i in range(20)] + [{"id": "otogo", "name": "Otogo", "type": "portail"}]} (tmp_path / "data" / "raw" / "registry" / "sources.json").write_text(json.dumps(srcs)) (tmp_path / "data" / "raw" / "registry" / "villes_gps.json").write_text(json.dumps({"ville": [45.5, -73.6]})) m = ingest.run(snapshot=db, outdir=tmp_path / "data" / "interim", with_hash=False) assert m["rows"]["vehicles"] == 1500 importlib.reload(config) stats = cleaning.run(interim=tmp_path / "data" / "interim", out=tmp_path / "data" / "processed", registry=tmp_path / "data" / "raw" / "registry") assert stats["S0"] == 1500 assert stats["S1_hedonic"] > 1000 assert (tmp_path / "data" / "processed" / "exclusions.csv").exists() assert (tmp_path / "data" / "processed" / "price_events.parquet").exists() def test_first_cut_never_null_in_risk_set(): """Regression test for E-016: first_cut must be 0 (not NULL) for listing-days of never-cut listings.""" import polars as pl from ucml import config as C p = C.PROCESSED / "risk_set.parquet" if not p.exists(): pytest.skip("risk set not built") rs = pl.read_parquet(p, columns=["first_cut", "cut", "exit"]) assert rs["first_cut"].null_count() == 0 and rs["cut"].null_count() == 0 and rs["exit"].null_count() == 0