import os import pytest from cpl.core.log.log_level import LogLevel from cpl.core.log.log_settings import LogSettings from cpl.core.log.logger import Logger from cpl.core.log.logger_abc import LoggerABC # --- LogLevel --- def test_log_level_values(): assert LogLevel.off.value == "OFF" assert LogLevel.trace.value == "TRC" assert LogLevel.debug.value == "DEB" assert LogLevel.info.value == "INF" assert LogLevel.warning.value == "WAR" assert LogLevel.error.value == "ERR" assert LogLevel.fatal.value == "FAT" def test_log_level_order(): levels = list(LogLevel) assert levels.index(LogLevel.trace) < levels.index(LogLevel.debug) assert levels.index(LogLevel.debug) < levels.index(LogLevel.info) assert levels.index(LogLevel.info) < levels.index(LogLevel.warning) assert levels.index(LogLevel.warning) < levels.index(LogLevel.error) assert levels.index(LogLevel.error) < levels.index(LogLevel.fatal) def test_log_level_by_name(): assert LogLevel["info"] == LogLevel.info assert LogLevel["error"] == LogLevel.error # --- LogSettings --- def test_log_settings_defaults(): s = LogSettings() assert s.path == "logs" assert s.filename == "app.log" assert s.console == LogLevel.info assert s.level == LogLevel.info def test_log_settings_from_src(): s = LogSettings({"path": "custom_logs", "filename": "myapp.log"}) assert s.path == "custom_logs" assert s.filename == "myapp.log" # --- LoggerABC --- def test_logger_abc_cannot_instantiate(): with pytest.raises(TypeError): LoggerABC() # --- Logger --- def test_logger_creates_instance(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger(__name__) assert logger is not None def test_logger_log_file_property(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger(__name__) assert logger.log_file.startswith("logs/") assert logger.log_file.endswith(".log") def test_logger_should_log_same_level(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger(__name__) assert logger._should_log(LogLevel.info, LogLevel.info) is True assert logger._should_log(LogLevel.error, LogLevel.error) is True def test_logger_should_log_higher_level(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger(__name__) assert logger._should_log(LogLevel.error, LogLevel.info) is True assert logger._should_log(LogLevel.fatal, LogLevel.debug) is True def test_logger_should_not_log_lower_level(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger(__name__) assert logger._should_log(LogLevel.debug, LogLevel.info) is False assert logger._should_log(LogLevel.trace, LogLevel.warning) is False def test_logger_file_format_message(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger("test_src") msg = logger._file_format_message("INF", "2024-01-01 00:00:00.000000", "hello", "world") assert "INF" in msg assert "hello" in msg assert "world" in msg assert "test_src" in msg def test_logger_console_format_message(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger("test_src") msg = logger._console_format_message("DEB", "2024-01-01 00:00:00.000000", "debug message") assert "DEB" in msg assert "debug message" in msg def test_logger_info_writes_file(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger(__name__) logger.info("test info message") log_files = list(tmp_path.glob("logs/*.log")) assert len(log_files) > 0 content = log_files[0].read_text() assert "test info message" in content def test_logger_debug_below_info_not_written_to_file(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) # Default level is INFO, so DEBUG should not appear in the file logger = Logger(__name__) logger.debug("should not appear in file") log_files = list(tmp_path.glob("logs/*.log")) if log_files: content = log_files[0].read_text() assert "should not appear in file" not in content def test_logger_set_level_invalid(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) with pytest.raises(ValueError): Logger.set_level("INVALID_LEVEL") def test_logger_fatal_exits(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger(__name__) with pytest.raises(SystemExit): logger.fatal("fatal error") def test_logger_fatal_prevent_quit(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) logger = Logger(__name__) logger.fatal("fatal no quit", prevent_quit=True) # Should not raise