# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/00_core_test.ipynb.

# %% auto 0
__all__ = ['TestValidateNside', 'TestMAD', 'TestRobustStd', 'TestSetupLogger']

# %% ../../nbs/00_core_test.ipynb 1
import pytest
import numpy as np
import logging
import io
import sys

from ..core import validate_nside, mad, robust_std, setup_logger


class TestValidateNside:
    """Test nside validation."""
    
    def test_valid_powers_of_2(self):
        """Test that valid powers of 2 are accepted."""
        for nside in [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]:
            assert validate_nside(nside) == nside
    
    def test_invalid_non_powers_of_2(self):
        """Test that non-powers of 2 raise ValueError."""
        for bad_nside in [3, 5, 6, 7, 10, 100, 1000, 1023, 1025]:
            with pytest.raises(ValueError, match="power of 2"):
                validate_nside(bad_nside)
    
    def test_zero_rejected(self):
        """Test that nside=0 is rejected."""
        with pytest.raises(ValueError):
            validate_nside(0)
    
    def test_negative_rejected(self):
        """Test that negative nside is rejected."""
        with pytest.raises(ValueError):
            validate_nside(-8)


class TestMAD:
    """Test Median Absolute Deviation calculation."""
    
    def test_basic_case(self):
        """Test MAD on simple array."""
        arr = np.array([1, 2, 3, 4, 5])
        assert mad(arr) == 1.0
    
    def test_even_elements(self):
        """Test MAD with even number of elements."""
        arr = np.array([1, 2, 3, 4])
        # Median of [1,2,3,4] is 2.5, deviations are [1.5, 0.5, 0.5, 1.5], MAD = median([1.5, 0.5, 0.5, 1.5]) = 1.0
        assert mad(arr) == 1.0
    
    def test_nan_values_ignored(self):
        """Test that NaN values are filtered out."""
        arr = np.array([1, 2, np.nan, 4, 5])
        assert mad(arr) == 1.5
    
    def test_all_nan_returns_nan(self):
        """Test that all-NaN array returns NaN."""
        arr = np.array([np.nan, np.nan, np.nan])
        result = mad(arr)
        assert np.isnan(result)
    
    def test_inf_values_ignored(self):
        """Test that inf values are filtered out."""
        arr = np.array([1, 2, np.inf, 4, 5])
        assert mad(arr) == 1.5
    
    def test_all_inf_returns_nan(self):
        """Test that all-inf array returns NaN."""
        arr = np.array([np.inf, np.inf, np.inf])
        result = mad(arr)
        assert np.isnan(result)
    
    def test_single_element(self):
        """Test MAD of single element."""
        arr = np.array([5.0])
        assert mad(arr) == 0.0
    
    def test_constant_array(self):
        """Test MAD of constant array."""
        arr = np.array([3, 3, 3, 3])
        assert mad(arr) == 0.0
    
    def test_negative_values(self):
        """Test MAD works with negative values."""
        arr = np.array([-5, -4, -3, -2, -1])
        assert mad(arr) == 1.0
    
    def test_list_input(self):
        """Test that MAD accepts list input."""
        result = mad([1, 2, 3, 4, 5])
        assert result == 1.0
    
    def test_empty_array(self):
        """Test MAD of empty array."""
        arr = np.array([])
        result = mad(arr)
        assert np.isnan(result)
    
    def test_integer_dtype(self):
        """Test MAD works with integer arrays."""
        arr = np.array([1, 2, 3, 4, 5], dtype=int)
        assert mad(arr) == 1.0
    
    def test_float_dtype(self):
        """Test MAD works with float arrays."""
        arr = np.array([1.5, 2.5, 3.5, 4.5, 5.5], dtype=float)
        assert mad(arr) == 1.0


class TestRobustStd:
    """Test robust standard deviation calculation."""
    
    def test_basic_case(self):
        """Test robust_std on simple array."""
        arr = np.array([1, 2, 3, 4, 5])
        result = robust_std(arr)
        expected = 1.0 * 1.4826
        assert abs(result - expected) < 1e-10
    
    def test_with_nan(self):
        """Test robust_std ignores NaN."""
        arr = np.array([1, 2, np.nan, 4, 5])
        result = robust_std(arr)
        expected = 1.5 * 1.4826
        assert abs(result - expected) < 1e-10
    
    def test_all_nan_returns_nan(self):
        """Test robust_std of all-NaN array."""
        arr = np.array([np.nan, np.nan])
        result = robust_std(arr)
        assert np.isnan(result)
    
    def test_constant_array(self):
        """Test robust_std of constant array."""
        arr = np.array([5, 5, 5, 5])
        result = robust_std(arr)
        assert result == 0.0
    
    def test_single_element(self):
        """Test robust_std of single element."""
        result = robust_std(np.array([5.0]))
        assert result == 0.0
    
    def test_scaling_factor(self):
        """Test that scaling factor 1.4826 is applied correctly."""
        arr = np.array([1, 3, 5, 7, 9])
        mad_val = mad(arr)
        robust_std_val = robust_std(arr)
        assert abs(robust_std_val - (mad_val * 1.4826)) < 1e-10


class TestSetupLogger:
    """Test logger setup function."""
    
    def test_logger_creation(self):
        """Test basic logger creation."""
        logger = setup_logger("test_logger_create")
        assert logger.name == "test_logger_create"
        assert logger.level == logging.INFO
    
    def test_custom_log_level(self):
        """Test logger with custom log level."""
        logger = setup_logger("test_logger_debug", level=logging.DEBUG)
        assert logger.level == logging.DEBUG
    
    def test_has_handlers(self):
        """Test that logger has handlers."""
        logger = setup_logger("test_logger_handlers")
        assert len(logger.handlers) > 0
    
    def test_no_duplicate_handlers(self):
        """Test that multiple calls don't add duplicate handlers."""
        logger_name = "test_logger_no_dup"
        logger1 = setup_logger(logger_name)
        initial_count = len(logger1.handlers)
        
        logger2 = setup_logger(logger_name)
        assert len(logger2.handlers) == initial_count
    
    def test_different_log_levels(self):
        """Test loggers with different levels."""
        logger_warning = setup_logger("test_logger_warning", level=logging.WARNING)
        assert logger_warning.level == logging.WARNING
        
        logger_error = setup_logger("test_logger_error", level=logging.ERROR)
        assert logger_error.level == logging.ERROR
    
    def test_logger_output(self):
        """Test that logger produces output (basic handler check)."""
        logger = setup_logger("test_logger_output_check", level=logging.INFO)
        # Just verify logger has StreamHandler that can format messages
        assert any(isinstance(h, logging.StreamHandler) for h in logger.handlers)
        assert all(h.formatter is not None for h in logger.handlers)
