import pytest
import pandas as pd
import numpy as np
from privacy_tuner.input.feature_analyzer import FeatureAnalyzer


def test_feature_analyzer_basic():
    df = pd.DataFrame({
        'age': [25, 30, 35, 40],
        'income': [50000, 60000, 70000, 80000],
        'gender': ['M', 'F', 'M', 'F']
    })
    analyzer = FeatureAnalyzer(df)

    # 检查列类型检测
    assert analyzer.column_types == {'age': 'numeric', 'income': 'numeric', 'gender': 'categorical'}

    # 检查统计信息
    assert analyzer.stats['age']['mean'] == 32.5
    assert analyzer.stats['income']['std'] == pytest.approx(12909.944, rel=1e-3)

    # 检查敏感度（默认 range）
    assert analyzer.sensitivity['age'] == 15  # 40-25
    assert analyzer.sensitivity['income'] == 30000  # 80000-50000
    assert analyzer.sensitivity['gender'] == 1.0


def test_feature_analyzer_std_sensitivity():
    df = pd.DataFrame({'age': [25, 30, 35, 40]})
    analyzer = FeatureAnalyzer(df, sensitivity_type='std')
    assert analyzer.sensitivity['age'] == pytest.approx(df['age'].std())


def test_feature_analyzer_custom_sensitivity():
    df = pd.DataFrame({'age': [25, 30, 35, 40]})
    # 自定义函数：返回方差
    analyzer = FeatureAnalyzer(df, sensitivity_type=lambda col: col.var())
    assert analyzer.sensitivity['age'] == pytest.approx(df['age'].var())


def test_feature_analyzer_missing_values():
    df = pd.DataFrame({
        'age': [25, None, 35, 40],
        'gender': ['M', 'F', None, 'F']
    })
    # 应该能处理缺失值（dropna 已经在加载时处理过，但这里模拟）
    df = df.dropna()
    analyzer = FeatureAnalyzer(df)
    assert analyzer.column_types['age'] == 'numeric'
    assert analyzer.column_types['gender'] == 'categorical'