Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions tests/copilot_usage/test_logging_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""Tests for copilot_usage.logging_config — setup_logging, _emoji_patcher, LEVEL_EMOJI."""

# pyright: reportPrivateUsage=false
# pyright: reportUnknownMemberType=false
# pyright: reportAttributeAccessIssue=false
# pyright: reportUnknownVariableType=false
# pyright: reportUnknownArgumentType=false

from __future__ import annotations

import sys

from loguru import logger

from copilot_usage.logging_config import (
LEVEL_EMOJI,
_emoji_patcher,
setup_logging,
)

# ---------------------------------------------------------------------------
# setup_logging
# ---------------------------------------------------------------------------


def test_setup_logging_adds_exactly_one_sink() -> None:
"""After setup_logging(), logger has exactly one handler."""
setup_logging()
assert len(logger._core.handlers) == 1


def test_setup_logging_idempotent() -> None:
"""Calling setup_logging() twice still results in exactly 1 sink."""
setup_logging()
setup_logging()
assert len(logger._core.handlers) == 1


def test_setup_logging_targets_stderr() -> None:
"""After setup_logging(), the single sink targets sys.stderr."""
setup_logging()
handler = next(iter(logger._core.handlers.values()))
assert handler._sink._stream is sys.stderr


def test_setup_logging_level_is_warning() -> None:
"""After setup_logging(), the minimum log level is WARNING."""
setup_logging()
handler = next(iter(logger._core.handlers.values()))
assert handler.levelno == logger.level("WARNING").no


# ---------------------------------------------------------------------------
# _emoji_patcher
# ---------------------------------------------------------------------------


def test_emoji_patcher_known_levels() -> None:
"""_emoji_patcher sets record['extra']['emoji'] for each known level."""
for level_name, expected_emoji in LEVEL_EMOJI.items():
record: dict[str, object] = {
"level": type("Level", (), {"name": level_name})(),
"extra": {},
}
_emoji_patcher(record) # type: ignore[arg-type]
assert record["extra"]["emoji"] == expected_emoji # type: ignore[index]


def test_emoji_patcher_unknown_level_fallback() -> None:
"""_emoji_patcher falls back to ' ' for an unknown level name."""
record: dict[str, object] = {
"level": type("Level", (), {"name": "NONEXISTENT"})(),
"extra": {},
}
_emoji_patcher(record) # type: ignore[arg-type]
assert record["extra"]["emoji"] == " " # type: ignore[index]


# ---------------------------------------------------------------------------
# LEVEL_EMOJI
# ---------------------------------------------------------------------------

_STANDARD_LEVELS = frozenset(
{"TRACE", "DEBUG", "INFO", "SUCCESS", "WARNING", "ERROR", "CRITICAL"}
)


def test_level_emoji_covers_all_standard_levels() -> None:
"""LEVEL_EMOJI contains entries for all seven standard loguru levels."""
assert _STANDARD_LEVELS.issubset(LEVEL_EMOJI.keys())
Loading