Coverage for tests / cli / test_config_command.py: 100%
85 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 the lintro config CLI command."""
3from __future__ import annotations
5import json
6from unittest.mock import MagicMock, patch
8import pytest
9from assertpy import assert_that
10from click.testing import CliRunner
12from lintro.cli import cli
13from lintro.config.lintro_config import (
14 EnforceConfig,
15 ExecutionConfig,
16 LintroConfig,
17 LintroToolConfig,
18)
21@pytest.fixture
22def cli_runner() -> CliRunner:
23 """Create a CLI runner for testing.
25 Returns:
26 CliRunner: A Click test runner instance.
27 """
28 return CliRunner()
31@pytest.fixture
32def mock_config() -> LintroConfig:
33 """Create a mock LintroConfig for testing.
35 Returns:
36 LintroConfig: A configured LintroConfig instance.
37 """
38 return LintroConfig(
39 execution=ExecutionConfig(
40 enabled_tools=[],
41 tool_order="priority",
42 fail_fast=False,
43 ),
44 enforce=EnforceConfig(
45 line_length=88,
46 target_python="py313",
47 ),
48 tools={
49 "ruff": LintroToolConfig(enabled=True),
50 "black": LintroToolConfig(enabled=True),
51 },
52 config_path="/path/to/.lintro-config.yaml",
53 )
56# =============================================================================
57# Tests for JSON output mode of config command
58# =============================================================================
61@patch("lintro.cli_utils.commands.config.get_config")
62@patch("lintro.cli_utils.commands.config.validate_config_consistency")
63@patch("lintro.cli_utils.commands.config.is_tool_injectable")
64def test_json_output_is_valid_json(
65 mock_injectable: MagicMock,
66 mock_validate: MagicMock,
67 mock_get_config: MagicMock,
68 mock_config: LintroConfig,
69 cli_runner: CliRunner,
70) -> None:
71 """JSON output is valid JSON.
73 Args:
74 mock_injectable: Mock for is_tool_injectable function.
75 mock_validate: Mock for validate_config_consistency function.
76 mock_get_config: Mock for get_config function.
77 mock_config: Mock LintroConfig instance.
78 cli_runner: Click test runner instance.
79 """
80 mock_get_config.return_value = mock_config
81 mock_validate.return_value = []
82 mock_injectable.return_value = True
84 result = cli_runner.invoke(cli, ["config", "--json"])
86 assert_that(result.exit_code).is_equal_to(0)
87 # Should be valid JSON
88 data = json.loads(result.output)
89 assert_that(data).contains("global_settings")
90 assert_that(data).contains("tool_configs")
93@patch("lintro.cli_utils.commands.config.get_config")
94@patch("lintro.cli_utils.commands.config.validate_config_consistency")
95@patch("lintro.cli_utils.commands.config.is_tool_injectable")
96def test_json_output_includes_line_length(
97 mock_injectable: MagicMock,
98 mock_validate: MagicMock,
99 mock_get_config: MagicMock,
100 mock_config: LintroConfig,
101 cli_runner: CliRunner,
102) -> None:
103 """JSON output includes line length in global settings.
105 Args:
106 mock_injectable: Mock for is_tool_injectable function.
107 mock_validate: Mock for validate_config_consistency function.
108 mock_get_config: Mock for get_config function.
109 mock_config: Mock LintroConfig instance.
110 cli_runner: Click test runner instance.
111 """
112 mock_get_config.return_value = mock_config
113 mock_validate.return_value = []
114 mock_injectable.return_value = True
116 result = cli_runner.invoke(cli, ["config", "--json"])
118 data = json.loads(result.output)
119 assert_that(data["global_settings"]["line_length"]).is_equal_to(88)
122@patch("lintro.cli_utils.commands.config.get_config")
123@patch("lintro.cli_utils.commands.config.validate_config_consistency")
124@patch("lintro.cli_utils.commands.config.is_tool_injectable")
125def test_json_output_includes_tool_order(
126 mock_injectable: MagicMock,
127 mock_validate: MagicMock,
128 mock_get_config: MagicMock,
129 mock_config: LintroConfig,
130 cli_runner: CliRunner,
131) -> None:
132 """JSON output includes tool execution order.
134 Args:
135 mock_injectable: Mock for is_tool_injectable function.
136 mock_validate: Mock for validate_config_consistency function.
137 mock_get_config: Mock for get_config function.
138 mock_config: Mock LintroConfig instance.
139 cli_runner: Click test runner instance.
140 """
141 mock_get_config.return_value = mock_config
142 mock_validate.return_value = []
143 mock_injectable.return_value = True
145 result = cli_runner.invoke(cli, ["config", "--json"])
147 data = json.loads(result.output)
148 # Should have tools in priority order (black before ruff)
149 assert_that(data).contains("tool_execution_order")
150 tool_names = [t["tool"] for t in data["tool_execution_order"]]
151 assert_that(tool_names).contains("black")
152 # Verify black comes before ruff (lower priority = runs first)
153 assert_that(tool_names).contains("ruff")
154 assert_that(tool_names.index("black")).is_less_than(tool_names.index("ruff"))
157@patch("lintro.cli_utils.commands.config.get_config")
158@patch("lintro.cli_utils.commands.config.validate_config_consistency")
159@patch("lintro.cli_utils.commands.config.is_tool_injectable")
160def test_json_output_includes_warnings(
161 mock_injectable: MagicMock,
162 mock_validate: MagicMock,
163 mock_get_config: MagicMock,
164 mock_config: LintroConfig,
165 cli_runner: CliRunner,
166) -> None:
167 """JSON output includes configuration warnings.
169 Args:
170 mock_injectable: Mock for is_tool_injectable function.
171 mock_validate: Mock for validate_config_consistency function.
172 mock_get_config: Mock for get_config function.
173 mock_config: Mock LintroConfig instance.
174 cli_runner: Click test runner instance.
175 """
176 mock_get_config.return_value = mock_config
177 mock_validate.return_value = ["black: Native config differs"]
178 mock_injectable.return_value = True
180 result = cli_runner.invoke(cli, ["config", "--json"])
182 data = json.loads(result.output)
183 assert_that(data).contains("warnings")
184 assert_that(len(data["warnings"])).is_greater_than(0)
185 assert_that(data["warnings"][0]).contains("black")
188@patch("lintro.cli_utils.commands.config.get_config")
189@patch("lintro.cli_utils.commands.config.validate_config_consistency")
190@patch("lintro.cli_utils.commands.config.is_tool_injectable")
191def test_json_output_includes_config_source(
192 mock_injectable: MagicMock,
193 mock_validate: MagicMock,
194 mock_get_config: MagicMock,
195 mock_config: LintroConfig,
196 cli_runner: CliRunner,
197) -> None:
198 """JSON output includes config_source field.
200 Args:
201 mock_injectable: Mock for is_tool_injectable function.
202 mock_validate: Mock for validate_config_consistency function.
203 mock_get_config: Mock for get_config function.
204 mock_config: Mock LintroConfig instance.
205 cli_runner: Click test runner instance.
206 """
207 mock_get_config.return_value = mock_config
208 mock_validate.return_value = []
209 mock_injectable.return_value = True
211 result = cli_runner.invoke(cli, ["config", "--json"])
213 data = json.loads(result.output)
214 assert_that(data).contains("config_source")
215 assert_that(data["config_source"]).contains(".lintro-config.yaml")
218# =============================================================================
219# Tests for verbose mode of config command
220# =============================================================================
223@patch("lintro.cli_utils.commands.config.get_config")
224@patch("lintro.cli_utils.commands.config.validate_config_consistency")
225@patch("lintro.cli_utils.commands.config.is_tool_injectable")
226@patch("lintro.cli_utils.commands.config._load_native_tool_config")
227def test_verbose_shows_native_config(
228 mock_native_config: MagicMock,
229 mock_injectable: MagicMock,
230 mock_validate: MagicMock,
231 mock_get_config: MagicMock,
232 mock_config: LintroConfig,
233 cli_runner: CliRunner,
234) -> None:
235 """Verbose mode shows native config column.
237 Args:
238 mock_native_config: Mock for _load_native_tool_config function.
239 mock_injectable: Mock for is_tool_injectable function.
240 mock_validate: Mock for validate_config_consistency function.
241 mock_get_config: Mock for get_config function.
242 mock_config: Mock LintroConfig instance.
243 cli_runner: Click test runner instance.
244 """
245 mock_get_config.return_value = mock_config
246 mock_validate.return_value = []
247 mock_injectable.return_value = False
248 mock_native_config.return_value = {"printWidth": 100}
250 result = cli_runner.invoke(cli, ["config", "--verbose"])
252 assert_that(result.exit_code).is_equal_to(0)
253 # Verbose should show Native Config column
254 assert_that(
255 "Native" in result.output or "native" in result.output.lower(),
256 ).is_true()