85 lines
3.8 KiB
Python
85 lines
3.8 KiB
Python
"""
|
|
tests/test_platform_invariants.py
|
|
Rigorous mathematical invariance and governance test suite for HIFFI Artist Intelligence.
|
|
Guarantees zero-imputation, rank continuity, isolated simulation, and score bounds.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
import sys
|
|
import pytest
|
|
import pandas as pd
|
|
import numpy as np
|
|
|
|
# Ensure project root is on sys.path for test discovery
|
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
|
if str(PROJECT_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
from core.cpi_engine import CommercialPowerEngine
|
|
|
|
DATA_PATH = PROJECT_ROOT / "data" / "hiffi_multiplatform_500.csv"
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def cohort_df():
|
|
assert DATA_PATH.exists(), f"Master dataset not found at {DATA_PATH}"
|
|
df = pd.read_csv(DATA_PATH)
|
|
assert len(df) == 500, f"Expected 500 rows, found {len(df)}"
|
|
return df
|
|
|
|
|
|
def test_zero_imputation_policy(cohort_df):
|
|
"""Enforces that missing streaming telemetry is strictly NaN, never synthetic zeroes."""
|
|
if "spotify_monthly_listeners" in cohort_df.columns:
|
|
zero_listeners = (cohort_df["spotify_monthly_listeners"] == 0).sum()
|
|
assert zero_listeners == 0, f"Violation: Found {zero_listeners} synthetic zeroes in Spotify listeners!"
|
|
|
|
|
|
def test_effective_weight_distribution_sums(cohort_df):
|
|
"""Verifies that all dynamic weights sum to 100% (+/- floating point tolerance)."""
|
|
assert "effective_weights" in cohort_df.columns, "Column 'effective_weights' missing."
|
|
for idx, weights_str in enumerate(cohort_df["effective_weights"]):
|
|
if pd.isna(weights_str) or weights_str == "NONE":
|
|
continue
|
|
# Extract percentage numbers: e.g. 'yt:50.0%,sp_monthly:25.0%'
|
|
percentages = [float(p.split(":")[1].replace("%", "")) for p in str(weights_str).split(",")]
|
|
total = sum(percentages)
|
|
assert abs(total - 100.0) < 0.25, f"Row {idx} weights do not sum to 100%: {weights_str} (sum={total})"
|
|
|
|
|
|
def test_published_rank_continuity(cohort_df):
|
|
"""Verifies published ranks are unique, consecutive integers from 1 to 500."""
|
|
ranks = cohort_df["hiffi_xp_published_rank"].dropna().astype(int).tolist()
|
|
assert len(ranks) == 500, f"Expected 500 published ranks, got {len(ranks)}"
|
|
expected_ranks = list(range(1, 501))
|
|
assert sorted(ranks) == expected_ranks, "Published ranks contain gaps, duplicates, or out-of-order sequences!"
|
|
|
|
|
|
def test_score_normalization_bounds(cohort_df):
|
|
"""Ensures production and XP composite scores are bounded in [0.0, 100.0]."""
|
|
for col in ["production_hiffi_score", "hiffi_xp_score"]:
|
|
if col in cohort_df.columns:
|
|
valid_vals = cohort_df[col].dropna()
|
|
assert (valid_vals >= 0.0).all(), f"Found negative scores in {col}"
|
|
assert (valid_vals <= 100.0).all(), f"Found scores exceeding 100.0 in {col}"
|
|
|
|
|
|
def test_sales_provenance_tiers_clean(cohort_df):
|
|
"""Verifies all 500 rows have valid, recognized provenance statuses."""
|
|
valid_statuses = {"VERIFIED_CSPC", "VERIFIED_RIAA", "ESTIMATED_SEA"}
|
|
actual_statuses = set(cohort_df["sales_data_status"].dropna().unique())
|
|
invalid = actual_statuses - valid_statuses
|
|
assert not invalid, f"Detected unrecognized sales statuses: {invalid}"
|
|
assert cohort_df["total_eas_cspc"].isna().sum() == 0, "Found NaN in total_eas_cspc"
|
|
|
|
|
|
def test_cpi_simulation_isolation(cohort_df):
|
|
"""Confirms running simulation engine in-memory does not modify published baseline ranks."""
|
|
engine = CommercialPowerEngine()
|
|
sim_df = engine.simulate_ranking(cohort_df, commercial_weight=0.20, mode="global_redistribution")
|
|
|
|
# Check that published baseline ranks remain identical
|
|
assert (sim_df["hiffi_xp_published_rank"] == cohort_df["hiffi_xp_published_rank"]).all()
|
|
# Check that simulated rank column was generated and populated
|
|
assert "simulated_rank" in sim_df.columns
|
|
assert (sim_df["simulated_rank"] >= 1).all() |