"""Test QualityConfig class and configuration loading.""" import os import pytest from code_quality_guard import QualityConfig class TestQualityConfig: """Test QualityConfig dataclass and environment loading.""" def test_default_config(self): """Test default configuration values.""" config = QualityConfig() # Core settings assert config.duplicate_threshold == 0.7 assert config.duplicate_enabled is True assert config.complexity_threshold == 10 assert config.complexity_enabled is True assert config.modernization_enabled is True assert config.require_type_hints is True assert config.enforcement_mode == "strict" # PostToolUse features assert config.state_tracking_enabled is False assert config.cross_file_check_enabled is False assert config.verify_naming is True assert config.show_success is False # Skip patterns assert "test_" in config.skip_patterns assert "_test.py" in config.skip_patterns assert "/tests/" in config.skip_patterns assert "/fixtures/" in config.skip_patterns def test_from_env_with_defaults(self): """Test loading config from environment with defaults.""" config = QualityConfig.from_env() # Should use defaults when env vars not set assert config.duplicate_threshold == 0.7 assert config.complexity_threshold == 10 assert config.enforcement_mode == "strict" def test_from_env_with_custom_values(self): """Test loading config from environment with custom values.""" os.environ.update( { "QUALITY_DUP_THRESHOLD": "0.8", "QUALITY_DUP_ENABLED": "false", "QUALITY_COMPLEXITY_THRESHOLD": "15", "QUALITY_COMPLEXITY_ENABLED": "false", "QUALITY_MODERN_ENABLED": "false", "QUALITY_REQUIRE_TYPES": "false", "QUALITY_ENFORCEMENT": "permissive", "QUALITY_STATE_TRACKING": "true", "QUALITY_CROSS_FILE_CHECK": "true", "QUALITY_VERIFY_NAMING": "false", "QUALITY_SHOW_SUCCESS": "true", }, ) config = QualityConfig.from_env() assert config.duplicate_threshold == 0.8 assert config.duplicate_enabled is False assert config.complexity_threshold == 15 assert config.complexity_enabled is False assert config.modernization_enabled is False assert config.require_type_hints is False assert config.enforcement_mode == "permissive" assert config.state_tracking_enabled is True assert config.cross_file_check_enabled is True assert config.verify_naming is False assert config.show_success is True def test_from_env_with_invalid_boolean(self): """Test loading config with invalid boolean values.""" os.environ["QUALITY_DUP_ENABLED"] = "invalid" config = QualityConfig.from_env() # Should default to False for invalid boolean assert config.duplicate_enabled is False def test_from_env_with_invalid_float(self): """Test loading config with invalid float values.""" os.environ["QUALITY_DUP_THRESHOLD"] = "not_a_float" with pytest.raises(ValueError, match="could not convert string to float"): QualityConfig.from_env() def test_from_env_with_invalid_int(self): """Test loading config with invalid int values.""" os.environ["QUALITY_COMPLEXITY_THRESHOLD"] = "not_an_int" with pytest.raises(ValueError, match="invalid literal"): QualityConfig.from_env() def test_enforcement_modes(self): """Test different enforcement modes.""" modes = ["strict", "warn", "permissive"] for mode in modes: os.environ["QUALITY_ENFORCEMENT"] = mode config = QualityConfig.from_env() assert config.enforcement_mode == mode def test_skip_patterns_initialization(self): """Test skip patterns initialization.""" config = QualityConfig(skip_patterns=None) assert config.skip_patterns is not None assert len(config.skip_patterns) > 0 custom_patterns = ["custom_test_", "/custom/"] config = QualityConfig(skip_patterns=custom_patterns) assert config.skip_patterns == custom_patterns def test_threshold_boundaries(self): """Test threshold boundary values.""" # Test minimum threshold os.environ["QUALITY_DUP_THRESHOLD"] = "0.0" config = QualityConfig.from_env() assert config.duplicate_threshold == 0.0 # Test maximum threshold os.environ["QUALITY_DUP_THRESHOLD"] = "1.0" config = QualityConfig.from_env() assert config.duplicate_threshold == 1.0 # Test complexity threshold os.environ["QUALITY_COMPLEXITY_THRESHOLD"] = "1" config = QualityConfig.from_env() assert config.complexity_threshold == 1 def test_config_combinations(self): """Test various configuration combinations.""" test_cases = [ # All checks disabled { "env": { "QUALITY_DUP_ENABLED": "false", "QUALITY_COMPLEXITY_ENABLED": "false", "QUALITY_MODERN_ENABLED": "false", }, "expected": { "duplicate_enabled": False, "complexity_enabled": False, "modernization_enabled": False, }, }, # Only duplicate checking { "env": { "QUALITY_DUP_ENABLED": "true", "QUALITY_COMPLEXITY_ENABLED": "false", "QUALITY_MODERN_ENABLED": "false", }, "expected": { "duplicate_enabled": True, "complexity_enabled": False, "modernization_enabled": False, }, }, # PostToolUse only { "env": { "QUALITY_DUP_ENABLED": "false", "QUALITY_STATE_TRACKING": "true", "QUALITY_VERIFY_NAMING": "true", }, "expected": { "duplicate_enabled": False, "state_tracking_enabled": True, "verify_naming": True, }, }, ] for test_case in test_cases: os.environ.clear() os.environ.update(test_case["env"]) config = QualityConfig.from_env() for key, expected_value in test_case["expected"].items(): assert getattr(config, key) == expected_value def test_case_insensitive_boolean(self): """Test case-insensitive boolean parsing.""" test_values = ["TRUE", "True", "true", "FALSE", "False", "false"] expected = [True, True, True, False, False, False] for value, expected_bool in zip(test_values, expected, strict=False): os.environ["QUALITY_DUP_ENABLED"] = value config = QualityConfig.from_env() assert config.duplicate_enabled == expected_bool