File size: 3,597 Bytes
022dce0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import logging
import os
import sys
from datetime import datetime
from ankigen.logging import setup_logger


def test_setup_logger_returns_logger():
    """1) setup_logger returns a logging.Logger"""
    logger = setup_logger("test_returns_logger")
    assert isinstance(logger, logging.Logger)
    assert logger.name == "test_returns_logger"


def test_setup_logger_handlers(tmp_path, monkeypatch):
    """2) Logger has exactly 2 handlers (StreamHandler + FileHandler)"""
    # Redirect home directory to tmp_path to avoid creating files in actual home
    monkeypatch.setattr(
        "ankigen.logging.os.path.expanduser", lambda x: str(tmp_path) if x == "~" else x
    )

    logger = setup_logger("test_handlers")

    # Check number of handlers
    assert len(logger.handlers) == 2

    handler_types = [type(h) for h in logger.handlers]
    # One should be StreamHandler (for console)
    assert any(
        issubclass(t, logging.StreamHandler) and not issubclass(t, logging.FileHandler)
        for t in handler_types
    )
    # One should be FileHandler
    assert any(issubclass(t, logging.FileHandler) for t in handler_types)

    # Verify StreamHandler uses stdout
    console_handler = next(
        h
        for h in logger.handlers
        if isinstance(h, logging.StreamHandler)
        and not isinstance(h, logging.FileHandler)
    )
    assert console_handler.stream == sys.stdout


def test_file_handler_path_pattern(tmp_path, monkeypatch):
    """3) File handler writes to the correct path pattern"""
    monkeypatch.setattr(
        "ankigen.logging.os.path.expanduser", lambda x: str(tmp_path) if x == "~" else x
    )

    name = "test_path"
    logger = setup_logger(name)

    file_handler = next(
        h for h in logger.handlers if isinstance(h, logging.FileHandler)
    )
    log_file_path = file_handler.baseFilename

    timestamp = datetime.now().strftime("%Y%m%d")
    # Expected pattern: ~/.ankigen/logs/{name}_{YYYYMMDD}.log
    expected_path = tmp_path / ".ankigen" / "logs" / f"{name}_{timestamp}.log"

    assert os.path.abspath(log_file_path) == os.path.abspath(str(expected_path))
    # Check if the directory was created
    assert os.path.exists(os.path.dirname(log_file_path))


def test_setup_logger_clears_old_handlers(tmp_path, monkeypatch):
    """4) Calling setup_logger twice with same name clears old handlers (no duplicates)"""
    monkeypatch.setattr(
        "ankigen.logging.os.path.expanduser", lambda x: str(tmp_path) if x == "~" else x
    )

    name = "test_clear_handlers"
    logger = setup_logger(name)
    assert len(logger.handlers) == 2
    initial_handlers = list(logger.handlers)

    # Call again with same name
    logger2 = setup_logger(name)
    assert logger is logger2
    assert len(logger2.handlers) == 2

    # Ensure handlers were replaced, not accumulated
    for handler in initial_handlers:
        assert handler not in logger2.handlers


def test_custom_log_level_respected():
    """5) Custom log_level is respected"""
    name_debug = "test_log_level_debug"
    logger_debug = setup_logger(name_debug, log_level=logging.DEBUG)
    assert logger_debug.level == logging.DEBUG

    name_info = "test_log_level_info"
    logger_info = setup_logger(name_info, log_level=logging.INFO)
    assert logger_info.level == logging.INFO


def test_custom_name_creates_distinct_logger():
    """6) Custom name creates a distinct logger"""
    logger1 = setup_logger("logger1")
    logger2 = setup_logger("logger2")
    assert logger1.name == "logger1"
    assert logger2.name == "logger2"
    assert logger1 is not logger2