165 lines
5.6 KiB
Python
165 lines
5.6 KiB
Python
"""
|
|
Unit tests for the Logger module.
|
|
"""
|
|
|
|
import pytest
|
|
import sys
|
|
import tempfile
|
|
import os
|
|
from pathlib import Path
|
|
from unittest.mock import patch, MagicMock
|
|
from loguru import logger
|
|
|
|
from src.logger import setup_logger, get_logger, LoggerMixin
|
|
|
|
|
|
class TestLoggerSetup:
|
|
"""Test cases for logger setup functionality."""
|
|
|
|
def test_setup_logger_default(self):
|
|
"""Test logger setup with default parameters."""
|
|
with patch('loguru.logger.remove') as mock_remove, \
|
|
patch('loguru.logger.add') as mock_add:
|
|
|
|
setup_logger()
|
|
|
|
# Verify default logger was removed
|
|
mock_remove.assert_called_once()
|
|
|
|
# Verify console logger was added
|
|
assert mock_add.call_count == 1
|
|
console_call = mock_add.call_args_list[0]
|
|
assert console_call[0][0] == sys.stderr
|
|
assert "level" in console_call[1]
|
|
assert console_call[1]["colorize"] is True
|
|
|
|
def test_setup_logger_with_file(self):
|
|
"""Test logger setup with file output."""
|
|
with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
|
|
log_file = tmp_file.name
|
|
|
|
try:
|
|
with patch('loguru.logger.remove') as mock_remove, \
|
|
patch('loguru.logger.add') as mock_add:
|
|
|
|
setup_logger(log_file=log_file)
|
|
|
|
# Verify both console and file loggers were added
|
|
assert mock_add.call_count == 2
|
|
|
|
# Check file logger call
|
|
file_call = mock_add.call_args_list[1]
|
|
assert file_call[0][0] == log_file
|
|
assert "rotation" in file_call[1]
|
|
assert "retention" in file_call[1]
|
|
assert "compression" in file_call[1]
|
|
finally:
|
|
# Clean up
|
|
if os.path.exists(log_file):
|
|
os.unlink(log_file)
|
|
|
|
def test_setup_logger_verbose(self):
|
|
"""Test logger setup with verbose mode."""
|
|
with patch('loguru.logger.remove') as mock_remove, \
|
|
patch('loguru.logger.add') as mock_add:
|
|
|
|
setup_logger(verbose=True)
|
|
|
|
# Verify DEBUG level was set
|
|
console_call = mock_add.call_args_list[0]
|
|
assert console_call[1]["level"] == "DEBUG"
|
|
|
|
def test_setup_logger_custom_level(self):
|
|
"""Test logger setup with custom log level."""
|
|
with patch('loguru.logger.remove') as mock_remove, \
|
|
patch('loguru.logger.add') as mock_add:
|
|
|
|
setup_logger(log_level="WARNING")
|
|
|
|
# Verify WARNING level was set
|
|
console_call = mock_add.call_args_list[0]
|
|
assert console_call[1]["level"] == "WARNING"
|
|
|
|
def test_setup_logger_custom_rotation(self):
|
|
"""Test logger setup with custom rotation settings."""
|
|
with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
|
|
log_file = tmp_file.name
|
|
|
|
try:
|
|
with patch('loguru.logger.remove') as mock_remove, \
|
|
patch('loguru.logger.add') as mock_add:
|
|
|
|
setup_logger(log_file=log_file, rotation="100 MB")
|
|
|
|
# Verify custom rotation was set
|
|
file_call = mock_add.call_args_list[1]
|
|
assert file_call[1]["rotation"] == "100 MB"
|
|
finally:
|
|
# Clean up
|
|
if os.path.exists(log_file):
|
|
os.unlink(log_file)
|
|
|
|
def test_setup_logger_exception_handler(self):
|
|
"""Test that exception handler is set up."""
|
|
with patch('loguru.logger.remove') as mock_remove, \
|
|
patch('loguru.logger.add') as mock_add, \
|
|
patch('sys.excepthook') as mock_excepthook:
|
|
|
|
setup_logger()
|
|
|
|
# Verify exception handler was set
|
|
assert mock_excepthook is not None
|
|
assert callable(mock_excepthook)
|
|
|
|
|
|
class TestGetLogger:
|
|
"""Test cases for get_logger function."""
|
|
|
|
def test_get_logger_no_name(self):
|
|
"""Test getting logger without name."""
|
|
with patch('loguru.logger.bind') as mock_bind:
|
|
get_logger()
|
|
mock_bind.assert_called_once()
|
|
|
|
def test_get_logger_with_name(self):
|
|
"""Test getting logger with name."""
|
|
with patch('loguru.logger.bind') as mock_bind:
|
|
get_logger("test_module")
|
|
mock_bind.assert_called_once_with(name="test_module")
|
|
|
|
|
|
class TestLoggerMixin:
|
|
"""Test cases for LoggerMixin class."""
|
|
|
|
def test_logger_property(self):
|
|
"""Test logger property in mixin."""
|
|
|
|
class TestClass(LoggerMixin):
|
|
pass
|
|
|
|
with patch('loguru.logger.bind') as mock_bind:
|
|
test_obj = TestClass()
|
|
_ = test_obj.logger
|
|
|
|
# Verify logger was bound with class name and object id
|
|
mock_bind.assert_called_once()
|
|
args, kwargs = mock_bind.call_args
|
|
assert kwargs["name"] == "TestClass"
|
|
assert "id" in kwargs
|
|
|
|
def test_logger_mixin_inheritance(self):
|
|
"""Test that logger mixin works with inheritance."""
|
|
|
|
class ParentClass(LoggerMixin):
|
|
pass
|
|
|
|
class ChildClass(ParentClass):
|
|
pass
|
|
|
|
with patch('loguru.logger.bind') as mock_bind:
|
|
child_obj = ChildClass()
|
|
_ = child_obj.logger
|
|
|
|
# Verify logger was bound with child class name
|
|
args, kwargs = mock_bind.call_args
|
|
assert kwargs["name"] == "ChildClass" |