Coverage for tests / unit / tools / shellcheck / test_options.py: 100%
77 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"""Unit tests for shellcheck plugin options and command building."""
3from __future__ import annotations
5import pytest
6from assertpy import assert_that
8from lintro.tools.definitions.shellcheck import (
9 SHELLCHECK_DEFAULT_FORMAT,
10 SHELLCHECK_DEFAULT_SEVERITY,
11 SHELLCHECK_DEFAULT_TIMEOUT,
12 SHELLCHECK_SEVERITY_LEVELS,
13 SHELLCHECK_SHELL_DIALECTS,
14 ShellcheckPlugin,
15)
17# Tests for default option values
20@pytest.mark.parametrize(
21 ("option_name", "expected_value"),
22 [
23 ("timeout", SHELLCHECK_DEFAULT_TIMEOUT),
24 ("severity", SHELLCHECK_DEFAULT_SEVERITY),
25 ("exclude", None),
26 ("shell", None),
27 ],
28 ids=[
29 "timeout_equals_default",
30 "severity_equals_default",
31 "exclude_is_none",
32 "shell_is_none",
33 ],
34)
35def test_default_options_values(
36 shellcheck_plugin: ShellcheckPlugin,
37 option_name: str,
38 expected_value: object,
39) -> None:
40 """Default options have correct values.
42 Args:
43 shellcheck_plugin: The ShellcheckPlugin instance to test.
44 option_name: The name of the option to check.
45 expected_value: The expected value for the option.
46 """
47 assert_that(
48 shellcheck_plugin.definition.default_options[option_name],
49 ).is_equal_to(expected_value)
52# Tests for ShellcheckPlugin.set_options method - valid options
55@pytest.mark.parametrize(
56 ("option_name", "option_value"),
57 [
58 ("severity", "error"),
59 ("severity", "warning"),
60 ("severity", "info"),
61 ("severity", "style"),
62 ("exclude", ["SC2086", "SC2046"]),
63 ("shell", "bash"),
64 ("shell", "sh"),
65 ("shell", "dash"),
66 ("shell", "ksh"),
67 ],
68 ids=[
69 "severity_error",
70 "severity_warning",
71 "severity_info",
72 "severity_style",
73 "exclude_list",
74 "shell_bash",
75 "shell_sh",
76 "shell_dash",
77 "shell_ksh",
78 ],
79)
80def test_set_options_valid(
81 shellcheck_plugin: ShellcheckPlugin,
82 option_name: str,
83 option_value: object,
84) -> None:
85 """Set valid options correctly.
87 Args:
88 shellcheck_plugin: The ShellcheckPlugin instance to test.
89 option_name: The name of the option to set.
90 option_value: The value to set for the option.
91 """
92 shellcheck_plugin.set_options(**{option_name: option_value}) # type: ignore[arg-type]
93 assert_that(shellcheck_plugin.options.get(option_name)).is_equal_to(option_value)
96def test_set_options_severity_case_insensitive(
97 shellcheck_plugin: ShellcheckPlugin,
98) -> None:
99 """Set severity option is case insensitive.
101 Args:
102 shellcheck_plugin: The ShellcheckPlugin instance to test.
103 """
104 shellcheck_plugin.set_options(severity="WARNING")
105 assert_that(shellcheck_plugin.options.get("severity")).is_equal_to("warning")
108def test_set_options_shell_case_insensitive(
109 shellcheck_plugin: ShellcheckPlugin,
110) -> None:
111 """Set shell option is case insensitive.
113 Args:
114 shellcheck_plugin: The ShellcheckPlugin instance to test.
115 """
116 shellcheck_plugin.set_options(shell="BASH") # nosec B604
117 assert_that(shellcheck_plugin.options.get("shell")).is_equal_to("bash")
120# Tests for ShellcheckPlugin.set_options method - invalid types
123@pytest.mark.parametrize(
124 ("option_name", "invalid_value", "error_match"),
125 [
126 ("severity", "critical", "Invalid severity level"),
127 ("severity", "warn", "Invalid severity level"),
128 ("shell", "fish", "Invalid shell dialect"),
129 ("shell", "powershell", "Invalid shell dialect"),
130 ("exclude", "SC2086", "exclude must be a list"),
131 ("exclude", 123, "exclude must be a list"),
132 ],
133 ids=[
134 "invalid_severity_critical",
135 "invalid_severity_warn",
136 "invalid_shell_fish",
137 "invalid_shell_powershell",
138 "invalid_exclude_string",
139 "invalid_exclude_integer",
140 ],
141)
142def test_set_options_invalid_type(
143 shellcheck_plugin: ShellcheckPlugin,
144 option_name: str,
145 invalid_value: object,
146 error_match: str,
147) -> None:
148 """Raise ValueError for invalid option types.
150 Args:
151 shellcheck_plugin: The ShellcheckPlugin instance to test.
152 option_name: The name of the option being tested.
153 invalid_value: An invalid value for the option.
154 error_match: Pattern expected in the error message.
155 """
156 with pytest.raises(ValueError, match=error_match):
157 shellcheck_plugin.set_options(**{option_name: invalid_value}) # type: ignore[arg-type]
160# Tests for ShellcheckPlugin._build_command method
163def test_build_command_basic(shellcheck_plugin: ShellcheckPlugin) -> None:
164 """Build basic command without extra options.
166 Args:
167 shellcheck_plugin: The ShellcheckPlugin instance to test.
168 """
169 cmd = shellcheck_plugin._build_command()
170 assert_that(cmd).contains("shellcheck")
171 # Default format and severity should be included
172 assert_that(cmd).contains("--format")
173 assert_that(cmd).contains(SHELLCHECK_DEFAULT_FORMAT)
174 assert_that(cmd).contains("--severity")
175 assert_that(cmd).contains(SHELLCHECK_DEFAULT_SEVERITY)
178def test_build_command_with_severity(shellcheck_plugin: ShellcheckPlugin) -> None:
179 """Build command with severity option.
181 Args:
182 shellcheck_plugin: The ShellcheckPlugin instance to test.
183 """
184 shellcheck_plugin.set_options(severity="error")
185 cmd = shellcheck_plugin._build_command()
187 assert_that(cmd).contains("--severity")
188 severity_idx = cmd.index("--severity")
189 assert_that(cmd[severity_idx + 1]).is_equal_to("error")
192def test_build_command_with_exclude_codes(shellcheck_plugin: ShellcheckPlugin) -> None:
193 """Build command with exclude option.
195 Args:
196 shellcheck_plugin: The ShellcheckPlugin instance to test.
197 """
198 shellcheck_plugin.set_options(exclude=["SC2086", "SC2046"])
199 cmd = shellcheck_plugin._build_command()
201 assert_that(cmd).contains("--exclude")
202 # Each exclude code should be passed separately
203 exclude_indices = [i for i, x in enumerate(cmd) if x == "--exclude"]
204 assert_that(exclude_indices).is_length(2)
205 assert_that(cmd[exclude_indices[0] + 1]).is_equal_to("SC2086")
206 assert_that(cmd[exclude_indices[1] + 1]).is_equal_to("SC2046")
209def test_build_command_with_shell_dialect(shellcheck_plugin: ShellcheckPlugin) -> None:
210 """Build command with shell dialect option.
212 Args:
213 shellcheck_plugin: The ShellcheckPlugin instance to test.
214 """
215 shellcheck_plugin.set_options(shell="bash") # nosec B604
216 cmd = shellcheck_plugin._build_command()
218 assert_that(cmd).contains("--shell")
219 shell_idx = cmd.index("--shell")
220 assert_that(cmd[shell_idx + 1]).is_equal_to("bash")
223def test_build_command_with_all_options(shellcheck_plugin: ShellcheckPlugin) -> None:
224 """Build command with all options set.
226 Args:
227 shellcheck_plugin: The ShellcheckPlugin instance to test.
228 """
229 shellcheck_plugin.set_options(
230 severity="warning",
231 exclude=["SC2086"],
232 shell="ksh", # nosec B604
233 )
234 cmd = shellcheck_plugin._build_command()
236 assert_that(cmd).contains("--format")
237 assert_that(cmd).contains("--severity")
238 assert_that(cmd).contains("--exclude")
239 assert_that(cmd).contains("--shell")
241 # Verify correct values
242 severity_idx = cmd.index("--severity")
243 assert_that(cmd[severity_idx + 1]).is_equal_to("warning")
245 shell_idx = cmd.index("--shell")
246 assert_that(cmd[shell_idx + 1]).is_equal_to("ksh")
249# Tests for constants
252def test_severity_levels_constant() -> None:
253 """Verify SHELLCHECK_SEVERITY_LEVELS contains expected values."""
254 assert_that(SHELLCHECK_SEVERITY_LEVELS).contains("error")
255 assert_that(SHELLCHECK_SEVERITY_LEVELS).contains("warning")
256 assert_that(SHELLCHECK_SEVERITY_LEVELS).contains("info")
257 assert_that(SHELLCHECK_SEVERITY_LEVELS).contains("style")
258 assert_that(SHELLCHECK_SEVERITY_LEVELS).is_length(4)
261def test_shell_dialects_constant() -> None:
262 """Verify SHELLCHECK_SHELL_DIALECTS contains expected values."""
263 assert_that(SHELLCHECK_SHELL_DIALECTS).contains("bash")
264 assert_that(SHELLCHECK_SHELL_DIALECTS).contains("sh")
265 assert_that(SHELLCHECK_SHELL_DIALECTS).contains("dash")
266 assert_that(SHELLCHECK_SHELL_DIALECTS).contains("ksh")
267 assert_that(SHELLCHECK_SHELL_DIALECTS).is_length(4)
270def test_default_timeout_constant() -> None:
271 """Verify SHELLCHECK_DEFAULT_TIMEOUT is 30."""
272 assert_that(SHELLCHECK_DEFAULT_TIMEOUT).is_equal_to(30)
275def test_default_format_constant() -> None:
276 """Verify SHELLCHECK_DEFAULT_FORMAT is json1."""
277 assert_that(SHELLCHECK_DEFAULT_FORMAT).is_equal_to("json1")
280def test_default_severity_constant() -> None:
281 """Verify SHELLCHECK_DEFAULT_SEVERITY is style."""
282 assert_that(SHELLCHECK_DEFAULT_SEVERITY).is_equal_to("style")