"""Tests for Family 1: Basic Sanity attacks."""

from rewardprobe.families.basic_sanity import BasicSanityFamily
from rewardprobe.types import Severity


class TestBasicSanityFamily:
    def test_clean_env_passes_all(self, clean_env):
        family = BasicSanityFamily()
        result = family.run(clean_env)
        # Exact match fn should pass: empty/whitespace/random return 0, ground truth returns 1
        assert result.passed >= 5  # At minimum basic checks pass

    def test_always_one_catches_empty(self, always_one_env):
        family = BasicSanityFamily()
        result = family.run(always_one_env)
        attack_names = {f.attack for f in result.findings}
        assert "empty" in attack_names
        assert "whitespace" in attack_names
        assert "random_tokens" in attack_names

    def test_crashing_fn_caught(self, crashing_env):
        family = BasicSanityFamily()
        result = family.run(crashing_env)
        crash_findings = [f for f in result.findings if f.error is not None]
        assert len(crash_findings) > 0
        assert all(f.severity == Severity.CRITICAL for f in crash_findings)

    def test_out_of_range_caught(self, out_of_range_env):
        family = BasicSanityFamily()
        result = family.run(out_of_range_env)
        range_findings = [f for f in result.findings if f.attack == "reward_range"]
        assert len(range_findings) > 0

    def test_signal_variance_catches_flat(self, always_one_env):
        family = BasicSanityFamily()
        result = family.run(always_one_env)
        variance_findings = [f for f in result.findings if f.attack == "signal_variance"]
        assert len(variance_findings) > 0

    def test_family_result_structure(self, buggy_env):
        family = BasicSanityFamily()
        result = family.run(buggy_env)
        assert result.name == "basic_sanity"
        assert result.display_name == "Basic Sanity"
        assert result.total == 7
        assert 0 <= result.passed <= 7
