- Remove console StreamHandler from get_logger() — say() already handles console output via click.echo(); having both caused every message to appear twice - Move GRM_LOG_LEVEL filtering into ui.say() via _console_level() so console verbosity is still user-controllable while the log file always captures everything at DEBUG - Remove [GRM] prefix from say() calls — no longer needed without duplicate logger output, giving cleaner user-facing messages - Update test_logging_config.py: remove console handler tests and _level_from_env tests (now in test_ui.py), expect 1 handler only - Add test_ui.py coverage for _console_level and say() level filtering - Update README to document single-path console output via click.echo - 116 tests, 100% coverage, pyright clean, ruff clean
59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
"""Unit tests for logging configuration."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from collections.abc import Generator
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from gitea_runner_manager.logging_config import get_logger
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _cleanup_loggers() -> Generator[None, None, None]:
|
|
"""Remove test loggers after each test to prevent state leakage."""
|
|
yield
|
|
for name in list(logging.Logger.manager.loggerDict.keys()):
|
|
if name.startswith("test_"):
|
|
logger = logging.getLogger(name)
|
|
logger.handlers.clear()
|
|
del logging.Logger.manager.loggerDict[name]
|
|
|
|
|
|
class TestGetLogger:
|
|
def test_returns_logger(self, tmp_path: Path) -> None:
|
|
with patch("gitea_runner_manager.logging_config.Path.home", return_value=tmp_path):
|
|
logger = get_logger("test_returns_logger")
|
|
|
|
assert isinstance(logger, logging.Logger)
|
|
assert logger.name == "test_returns_logger"
|
|
assert len(logger.handlers) == 1 # file only
|
|
|
|
def test_caches_same_instance(self, tmp_path: Path) -> None:
|
|
with patch("gitea_runner_manager.logging_config.Path.home", return_value=tmp_path):
|
|
logger1 = get_logger("test_caches_same")
|
|
logger2 = get_logger("test_caches_same")
|
|
|
|
assert logger1 is logger2
|
|
|
|
def test_file_handler_writes(self, tmp_path: Path) -> None:
|
|
with patch("gitea_runner_manager.logging_config.Path.home", return_value=tmp_path):
|
|
logger = get_logger("test_file_writes")
|
|
logger.info("hello from test")
|
|
|
|
log_file = tmp_path / ".local" / "state" / "grm" / "logs" / "grm.log"
|
|
assert log_file.exists()
|
|
content = log_file.read_text()
|
|
assert "hello from test" in content
|
|
assert "INFO" in content
|
|
|
|
def test_only_file_handler(self, tmp_path: Path) -> None:
|
|
with patch("gitea_runner_manager.logging_config.Path.home", return_value=tmp_path):
|
|
logger = get_logger("test_only_file")
|
|
|
|
assert len(logger.handlers) == 1
|
|
assert isinstance(logger.handlers[0], logging.FileHandler)
|