from __future__ import annotations import inspect import math import pytest from backend.app.services import quality_gate from backend.app.services.quality_gate import pass_quality_gate def test_quality_gate_reports_per_feature_kl_for_matrix_inputs() -> None: original = [ [0.10, 0.90], [0.20, 0.80], [0.30, 0.70], [0.40, 0.60], [0.50, 0.50], ] synthetic = [ [0.11, 0.88], [0.21, 0.78], [0.31, 0.68], [0.41, 0.58], [0.51, 0.48], ] result = pass_quality_gate(original, synthetic, kl_threshold=0.5) assert result["kl_aggregation"] == "mean_per_feature" assert len(result["per_feature_kl_divergence"]) == 2 assert result["kl_divergence"] >= 0.0 def test_quality_gate_source_does_not_flatten_vector_matrices() -> None: assert "reshape(-1)" not in inspect.getsource(quality_gate) def test_quality_gate_handles_empty_nonfinite_and_shape_errors() -> None: empty = pass_quality_gate([], [], kl_threshold=0.5) assert empty["accepted"] is True assert empty["kl_divergence"] == 0.0 assert empty["mmd"] == 0.0 noisy = pass_quality_gate( [[0.1, float("nan")], [float("inf"), 0.4]], [[0.2, 0.3], [0.5, float("-inf")]], kl_threshold=10.0, ) assert math.isfinite(float(noisy["kl_divergence"])) assert math.isfinite(float(noisy["mmd"])) with pytest.raises(ValueError, match="same feature dimension"): pass_quality_gate([[0.1, 0.2]], [[0.1]], kl_threshold=0.5)