"""Tests for the canonical constants module (thechart.core.constants).""" import os import sys from unittest.mock import patch def _fresh_constants(): """Import or reload the constants module and return it. Ensures a local binding exists in callers to avoid UnboundLocalError while supporting env var patching between tests. """ import importlib mod_name = "thechart.core.constants" if mod_name in sys.modules: mod = sys.modules[mod_name] return importlib.reload(mod) import thechart.core.constants as constants return constants class TestConstants: """Test cases for the canonical constants module.""" def test_default_log_level(self): with patch.dict(os.environ, {}, clear=True): constants = _fresh_constants() assert constants.LOG_LEVEL == "INFO" def test_custom_log_level(self): with patch.dict(os.environ, {"LOG_LEVEL": "debug"}, clear=True): constants = _fresh_constants() assert constants.LOG_LEVEL == "DEBUG" def test_default_log_path(self): with patch.dict(os.environ, {}, clear=True): constants = _fresh_constants() assert constants.LOG_PATH == "/tmp/logs/thechart" def test_custom_log_path(self): with patch.dict(os.environ, {"LOG_PATH": "/custom/log/path"}, clear=True): constants = _fresh_constants() assert constants.LOG_PATH == "/custom/log/path" def test_default_log_clear(self): with patch.dict(os.environ, {}, clear=True): constants = _fresh_constants() assert constants.LOG_CLEAR == "False" def test_custom_log_clear_true(self): with patch.dict(os.environ, {"LOG_CLEAR": "true"}, clear=True): constants = _fresh_constants() assert constants.LOG_CLEAR == "True" def test_custom_log_clear_false(self): with patch.dict(os.environ, {"LOG_CLEAR": "false"}, clear=True): constants = _fresh_constants() assert constants.LOG_CLEAR == "False" def test_log_level_case_insensitive(self): with patch.dict(os.environ, {"LOG_LEVEL": "warning"}, clear=True): constants = _fresh_constants() assert constants.LOG_LEVEL == "WARNING" def test_dotenv_override(self): # This is a structural test since dotenv is loaded during import with patch("thechart.core.constants.load_dotenv") as mock_load_dotenv: import importlib name = "thechart.core.constants" if name in sys.modules: importlib.reload(sys.modules[name]) else: import thechart.core.constants # noqa: F401 mock_load_dotenv.assert_called_once_with(override=True) def test_all_constants_are_strings(self): constants = _fresh_constants() assert isinstance(constants.LOG_LEVEL, str) assert isinstance(constants.LOG_PATH, str) assert isinstance(constants.LOG_CLEAR, str) def test_constants_not_empty(self): constants = _fresh_constants() assert constants.LOG_LEVEL != "" assert constants.LOG_PATH != "" assert constants.LOG_CLEAR != ""