Coverage for tests / unit / ai / test_hook.py: 100%
58 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Tests for AI post-execution hook."""
3from __future__ import annotations
5from unittest.mock import MagicMock, patch
7from assertpy import assert_that
9from lintro.ai.config import AIConfig
10from lintro.ai.hook import AIPostExecutionHook
11from lintro.config.lintro_config import LintroConfig
12from lintro.enums.action import Action
13from lintro.models.core.tool_result import ToolResult
14from tests.unit.ai.conftest import MockIssue
16# ---------------------------------------------------------------------------
17# TestShouldRun
18# ---------------------------------------------------------------------------
21def test_should_run_returns_true_for_check_when_enabled():
22 """Verify should_run returns True for CHECK action when AI is enabled."""
23 config = LintroConfig(ai=AIConfig(enabled=True))
24 hook = AIPostExecutionHook(config)
26 result = hook.should_run(Action.CHECK)
28 assert_that(result).is_true()
31def test_should_run_returns_true_for_fix_when_enabled():
32 """Verify should_run returns True for FIX action when AI is enabled."""
33 config = LintroConfig(ai=AIConfig(enabled=True))
34 hook = AIPostExecutionHook(config)
36 result = hook.should_run(Action.FIX)
38 assert_that(result).is_true()
41def test_should_run_returns_false_for_test_action():
42 """Verify should_run returns False for TEST action even when AI is enabled."""
43 config = LintroConfig(ai=AIConfig(enabled=True))
44 hook = AIPostExecutionHook(config)
46 result = hook.should_run(Action.TEST)
48 assert_that(result).is_false()
51def test_should_run_returns_false_when_disabled():
52 """Verify should_run returns False when AI is disabled."""
53 config = LintroConfig(ai=AIConfig(enabled=False))
54 hook = AIPostExecutionHook(config)
56 result = hook.should_run(Action.CHECK)
58 assert_that(result).is_false()
61# ---------------------------------------------------------------------------
62# TestExecute
63# ---------------------------------------------------------------------------
66@patch("lintro.ai.orchestrator.run_ai_enhancement")
67def test_execute_calls_run_ai_enhancement(mock_run_ai_enhancement):
68 """Verify execute delegates to run_ai_enhancement with correct arguments."""
69 config = LintroConfig(ai=AIConfig(enabled=True))
70 hook = AIPostExecutionHook(config, ai_fix=True)
71 console_logger = MagicMock()
72 results = [
73 ToolResult(
74 name="ruff",
75 success=False,
76 issues_count=1,
77 issues=[
78 MockIssue(
79 file="src/main.py",
80 line=1,
81 message="Use of assert",
82 code="B101",
83 ),
84 ],
85 ),
86 ]
88 hook.execute(
89 action=Action.CHECK,
90 all_results=results,
91 console_logger=console_logger,
92 output_format="json",
93 )
95 mock_run_ai_enhancement.assert_called_once_with(
96 action=Action.CHECK,
97 all_results=results,
98 lintro_config=config,
99 logger=console_logger,
100 output_format="json",
101 ai_fix=True,
102 )
105@patch("lintro.ai.orchestrator.run_ai_enhancement")
106def test_execute_catches_exceptions_and_logs_warning(mock_run_ai_enhancement):
107 """Exceptions don't propagate; warning is logged."""
108 mock_run_ai_enhancement.side_effect = RuntimeError("provider exploded")
109 config = LintroConfig(ai=AIConfig(enabled=True))
110 hook = AIPostExecutionHook(config)
111 console_logger = MagicMock()
112 results = [
113 ToolResult(
114 name="ruff",
115 success=False,
116 issues_count=1,
117 issues=[
118 MockIssue(
119 file="src/main.py",
120 line=1,
121 message="err",
122 code="E501",
123 ),
124 ],
125 ),
126 ]
128 hook.execute(
129 action=Action.CHECK,
130 all_results=results,
131 console_logger=console_logger,
132 output_format="terminal",
133 )
135 console_logger.warning.assert_called_once()
136 warning_msg = console_logger.warning.call_args[0][0]
137 assert_that(warning_msg).contains("provider exploded")
140def test_execute_handles_import_failure():
141 """Verify graceful handling when the lazy import of run_ai_enhancement fails."""
142 config = LintroConfig(ai=AIConfig(enabled=True))
143 hook = AIPostExecutionHook(config)
144 console_logger = MagicMock()
145 results = [
146 ToolResult(
147 name="ruff",
148 success=False,
149 issues_count=1,
150 issues=[
151 MockIssue(
152 file="src/main.py",
153 line=1,
154 message="err",
155 code="E501",
156 ),
157 ],
158 ),
159 ]
161 with patch.dict(
162 "sys.modules",
163 {"lintro.ai.orchestrator": None},
164 ):
165 hook.execute(
166 action=Action.CHECK,
167 all_results=results,
168 console_logger=console_logger,
169 output_format="terminal",
170 )
172 console_logger.warning.assert_called_once()
173 warning_msg = console_logger.warning.call_args[0][0]
174 assert_that(warning_msg).contains("AI enhancement unavailable")