Coverage for tests / unit / utils / console / test_logger_headers.py: 100%

32 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""Unit tests for ThreadSafeConsoleLogger header display methods. 

2 

3Tests cover the lintro header, tool header, and post-checks header 

4formatting and display functionality. 

5""" 

6 

7from __future__ import annotations 

8 

9from pathlib import Path 

10from unittest.mock import patch 

11 

12import pytest 

13from assertpy import assert_that 

14 

15from lintro.utils.console.logger import ThreadSafeConsoleLogger 

16 

17 

18def test_print_lintro_header_with_run_dir(tmp_path: Path) -> None: 

19 """Verify print_lintro_header outputs header when run directory exists. 

20 

21 When configured with a run_dir, the header should display a message 

22 indicating where output files will be generated, followed by a blank line. 

23 

24 Args: 

25 tmp_path: Temporary directory path for test files. 

26 """ 

27 logger = ThreadSafeConsoleLogger(run_dir=tmp_path) 

28 with patch.object(logger, "console_output") as mock_output: 

29 logger.print_lintro_header() 

30 # Should be called twice: header message and blank line 

31 assert_that(mock_output.call_count).is_equal_to(2) 

32 # Verify first call contains the run directory path 

33 first_call_text = mock_output.call_args_list[0].kwargs.get( 

34 "text", 

35 ( 

36 mock_output.call_args_list[0].args[0] 

37 if mock_output.call_args_list[0].args 

38 else "" 

39 ), 

40 ) 

41 assert_that(str(tmp_path) in first_call_text).is_true() 

42 

43 

44def test_print_lintro_header_without_run_dir_is_noop( 

45 logger: ThreadSafeConsoleLogger, 

46) -> None: 

47 """Verify print_lintro_header does nothing without run directory. 

48 

49 Without a run_dir, there's no output location to announce, so the 

50 header should be skipped entirely. 

51 

52 Args: 

53 logger: ThreadSafeConsoleLogger instance fixture. 

54 """ 

55 with patch.object(logger, "console_output") as mock_output: 

56 logger.print_lintro_header() 

57 mock_output.assert_not_called() 

58 

59 

60def test_print_tool_header_outputs_formatted_header( 

61 logger: ThreadSafeConsoleLogger, 

62) -> None: 

63 """Verify print_tool_header outputs a formatted banner for tool execution. 

64 

65 The tool header should include borders, the tool name, action, and 

66 decorative emoji elements to visually separate tool output sections. 

67 

68 Args: 

69 logger: ThreadSafeConsoleLogger instance fixture. 

70 """ 

71 with patch.object(logger, "console_output") as mock_output: 

72 logger.print_tool_header("ruff", "check") 

73 # Should output: border, header text, border, blank line 

74 assert_that(mock_output.call_count).is_equal_to(4) 

75 

76 

77@pytest.mark.parametrize( 

78 ("tool_name", "action"), 

79 [ 

80 pytest.param("ruff", "check", id="ruff-check"), 

81 pytest.param("black", "fmt", id="black-fmt"), 

82 pytest.param("mypy", "check", id="mypy-check"), 

83 pytest.param("pytest", "test", id="pytest-test"), 

84 ], 

85) 

86def test_print_tool_header_various_tools( 

87 logger: ThreadSafeConsoleLogger, 

88 tool_name: str, 

89 action: str, 

90) -> None: 

91 """Verify print_tool_header works with various tool and action combinations. 

92 

93 Different tools should produce appropriate headers with their names 

94 and corresponding actions displayed correctly. 

95 

96 Args: 

97 logger: ThreadSafeConsoleLogger instance fixture. 

98 tool_name: The name of the tool to display. 

99 action: The action being performed. 

100 """ 

101 with patch.object(logger, "console_output") as mock_output: 

102 logger.print_tool_header(tool_name, action) 

103 assert_that(mock_output.call_count).is_equal_to(4) 

104 # Verify tool name appears in the header 

105 header_text = str(mock_output.call_args_list[1]) 

106 assert_that(header_text).contains(tool_name) 

107 

108 

109def test_print_post_checks_header_outputs_styled_header( 

110 logger: ThreadSafeConsoleLogger, 

111) -> None: 

112 """Verify print_post_checks_header outputs a distinctive styled header. 

113 

114 The post-checks header uses a different style (magenta, heavy borders) 

115 to visually separate optional follow-up checks from primary tool runs. 

116 

117 Args: 

118 logger: ThreadSafeConsoleLogger instance fixture. 

119 """ 

120 with patch.object(logger, "console_output") as mock_output: 

121 logger.print_post_checks_header() 

122 # Should output: border, title, subtitle, border, blank line 

123 assert_that(mock_output.call_count).is_equal_to(5)