Coverage for tests / unit / tools / shfmt / test_options.py: 100%

69 statements  

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

1"""Unit tests for shfmt plugin options.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING 

6 

7import pytest 

8from assertpy import assert_that 

9 

10from lintro.tools.definitions.shfmt import ( 

11 SHFMT_DEFAULT_TIMEOUT, 

12 ShfmtPlugin, 

13) 

14 

15if TYPE_CHECKING: 

16 pass 

17 

18 

19# ============================================================================= 

20# Tests for default options 

21# ============================================================================= 

22 

23 

24@pytest.mark.parametrize( 

25 ("option_name", "expected_value"), 

26 [ 

27 ("timeout", SHFMT_DEFAULT_TIMEOUT), 

28 ("indent", None), 

29 ("binary_next_line", False), 

30 ("switch_case_indent", False), 

31 ("space_redirects", False), 

32 ("language_dialect", None), 

33 ("simplify", False), 

34 ], 

35 ids=[ 

36 "timeout_equals_default", 

37 "indent_is_none", 

38 "binary_next_line_is_false", 

39 "switch_case_indent_is_false", 

40 "space_redirects_is_false", 

41 "language_dialect_is_none", 

42 "simplify_is_false", 

43 ], 

44) 

45def test_default_options_values( 

46 shfmt_plugin: ShfmtPlugin, 

47 option_name: str, 

48 expected_value: object, 

49) -> None: 

50 """Default options have correct values. 

51 

52 Args: 

53 shfmt_plugin: The ShfmtPlugin instance to test. 

54 option_name: The name of the option to check. 

55 expected_value: The expected value for the option. 

56 """ 

57 assert_that( 

58 shfmt_plugin.definition.default_options[option_name], 

59 ).is_equal_to(expected_value) 

60 

61 

62# ============================================================================= 

63# Tests for ShfmtPlugin.set_options method - valid options 

64# ============================================================================= 

65 

66 

67@pytest.mark.parametrize( 

68 ("option_name", "option_value"), 

69 [ 

70 ("indent", 0), 

71 ("indent", 2), 

72 ("indent", 4), 

73 ("binary_next_line", True), 

74 ("switch_case_indent", True), 

75 ("space_redirects", True), 

76 ("language_dialect", "bash"), 

77 ("language_dialect", "posix"), 

78 ("language_dialect", "mksh"), 

79 ("language_dialect", "bats"), 

80 ("simplify", True), 

81 ], 

82 ids=[ 

83 "indent_0_tabs", 

84 "indent_2_spaces", 

85 "indent_4_spaces", 

86 "binary_next_line_true", 

87 "switch_case_indent_true", 

88 "space_redirects_true", 

89 "language_dialect_bash", 

90 "language_dialect_posix", 

91 "language_dialect_mksh", 

92 "language_dialect_bats", 

93 "simplify_true", 

94 ], 

95) 

96def test_set_options_valid( 

97 shfmt_plugin: ShfmtPlugin, 

98 option_name: str, 

99 option_value: object, 

100) -> None: 

101 """Set valid options correctly. 

102 

103 Args: 

104 shfmt_plugin: The ShfmtPlugin instance to test. 

105 option_name: The name of the option to set. 

106 option_value: The value to set for the option. 

107 """ 

108 shfmt_plugin.set_options(**{option_name: option_value}) # type: ignore[arg-type] 

109 assert_that(shfmt_plugin.options.get(option_name)).is_equal_to(option_value) 

110 

111 

112def test_set_options_language_dialect_case_insensitive( 

113 shfmt_plugin: ShfmtPlugin, 

114) -> None: 

115 """Set language_dialect with different case normalizes to lowercase. 

116 

117 Args: 

118 shfmt_plugin: The ShfmtPlugin instance to test. 

119 """ 

120 shfmt_plugin.set_options(language_dialect="BASH") 

121 assert_that(shfmt_plugin.options.get("language_dialect")).is_equal_to("bash") 

122 

123 

124# ============================================================================= 

125# Tests for ShfmtPlugin.set_options method - invalid types 

126# ============================================================================= 

127 

128 

129@pytest.mark.parametrize( 

130 ("option_name", "invalid_value", "error_match"), 

131 [ 

132 ("indent", "four", "indent must be an integer"), 

133 ("indent", 4.5, "indent must be an integer"), 

134 ("binary_next_line", "yes", "binary_next_line must be a boolean"), 

135 ("binary_next_line", 1, "binary_next_line must be a boolean"), 

136 ("switch_case_indent", "true", "switch_case_indent must be a boolean"), 

137 ("space_redirects", "no", "space_redirects must be a boolean"), 

138 ("language_dialect", 123, "language_dialect must be a string"), 

139 ("language_dialect", "invalid", "Invalid language_dialect"), 

140 ("language_dialect", "sh", "Invalid language_dialect"), 

141 ("simplify", "yes", "simplify must be a boolean"), 

142 ], 

143 ids=[ 

144 "invalid_indent_string", 

145 "invalid_indent_float", 

146 "invalid_binary_next_line_string", 

147 "invalid_binary_next_line_int", 

148 "invalid_switch_case_indent_string", 

149 "invalid_space_redirects_string", 

150 "invalid_language_dialect_int", 

151 "invalid_language_dialect_value", 

152 "invalid_language_dialect_sh", 

153 "invalid_simplify_string", 

154 ], 

155) 

156def test_set_options_invalid_type( 

157 shfmt_plugin: ShfmtPlugin, 

158 option_name: str, 

159 invalid_value: object, 

160 error_match: str, 

161) -> None: 

162 """Raise ValueError for invalid option types. 

163 

164 Args: 

165 shfmt_plugin: The ShfmtPlugin instance to test. 

166 option_name: The name of the option being tested. 

167 invalid_value: An invalid value for the option. 

168 error_match: Pattern expected in the error message. 

169 """ 

170 with pytest.raises(ValueError, match=error_match): 

171 shfmt_plugin.set_options(**{option_name: invalid_value}) # type: ignore[arg-type] 

172 

173 

174# ============================================================================= 

175# Tests for ShfmtPlugin._build_common_args method 

176# ============================================================================= 

177 

178 

179def test_build_common_args_no_options(shfmt_plugin: ShfmtPlugin) -> None: 

180 """Build common args with no options set returns empty list. 

181 

182 Args: 

183 shfmt_plugin: The ShfmtPlugin instance to test. 

184 """ 

185 args = shfmt_plugin._build_common_args() 

186 assert_that(args).is_empty() 

187 

188 

189def test_build_common_args_with_indent(shfmt_plugin: ShfmtPlugin) -> None: 

190 """Build common args with indent option. 

191 

192 Args: 

193 shfmt_plugin: The ShfmtPlugin instance to test. 

194 """ 

195 shfmt_plugin.set_options(indent=4) 

196 args = shfmt_plugin._build_common_args() 

197 

198 assert_that(args).contains("-i") 

199 indent_idx = args.index("-i") 

200 assert_that(args[indent_idx + 1]).is_equal_to("4") 

201 

202 

203def test_build_common_args_with_indent_zero(shfmt_plugin: ShfmtPlugin) -> None: 

204 """Build common args with indent=0 for tabs. 

205 

206 Args: 

207 shfmt_plugin: The ShfmtPlugin instance to test. 

208 """ 

209 shfmt_plugin.set_options(indent=0) 

210 args = shfmt_plugin._build_common_args() 

211 

212 assert_that(args).contains("-i") 

213 indent_idx = args.index("-i") 

214 assert_that(args[indent_idx + 1]).is_equal_to("0") 

215 

216 

217def test_build_common_args_with_binary_next_line(shfmt_plugin: ShfmtPlugin) -> None: 

218 """Build common args with binary_next_line option. 

219 

220 Args: 

221 shfmt_plugin: The ShfmtPlugin instance to test. 

222 """ 

223 shfmt_plugin.set_options(binary_next_line=True) 

224 args = shfmt_plugin._build_common_args() 

225 

226 assert_that(args).contains("-bn") 

227 

228 

229def test_build_common_args_with_switch_case_indent(shfmt_plugin: ShfmtPlugin) -> None: 

230 """Build common args with switch_case_indent option. 

231 

232 Args: 

233 shfmt_plugin: The ShfmtPlugin instance to test. 

234 """ 

235 shfmt_plugin.set_options(switch_case_indent=True) 

236 args = shfmt_plugin._build_common_args() 

237 

238 assert_that(args).contains("-ci") 

239 

240 

241def test_build_common_args_with_space_redirects(shfmt_plugin: ShfmtPlugin) -> None: 

242 """Build common args with space_redirects option. 

243 

244 Args: 

245 shfmt_plugin: The ShfmtPlugin instance to test. 

246 """ 

247 shfmt_plugin.set_options(space_redirects=True) 

248 args = shfmt_plugin._build_common_args() 

249 

250 assert_that(args).contains("-sr") 

251 

252 

253def test_build_common_args_with_language_dialect(shfmt_plugin: ShfmtPlugin) -> None: 

254 """Build common args with language_dialect option. 

255 

256 Args: 

257 shfmt_plugin: The ShfmtPlugin instance to test. 

258 """ 

259 shfmt_plugin.set_options(language_dialect="bash") 

260 args = shfmt_plugin._build_common_args() 

261 

262 assert_that(args).contains("-ln") 

263 ln_idx = args.index("-ln") 

264 assert_that(args[ln_idx + 1]).is_equal_to("bash") 

265 

266 

267def test_build_common_args_with_simplify(shfmt_plugin: ShfmtPlugin) -> None: 

268 """Build common args with simplify option. 

269 

270 Args: 

271 shfmt_plugin: The ShfmtPlugin instance to test. 

272 """ 

273 shfmt_plugin.set_options(simplify=True) 

274 args = shfmt_plugin._build_common_args() 

275 

276 assert_that(args).contains("-s") 

277 

278 

279def test_build_common_args_with_all_options(shfmt_plugin: ShfmtPlugin) -> None: 

280 """Build common args with all options set. 

281 

282 Args: 

283 shfmt_plugin: The ShfmtPlugin instance to test. 

284 """ 

285 shfmt_plugin.set_options( 

286 indent=2, 

287 binary_next_line=True, 

288 switch_case_indent=True, 

289 space_redirects=True, 

290 language_dialect="posix", 

291 simplify=True, 

292 ) 

293 args = shfmt_plugin._build_common_args() 

294 

295 assert_that(args).contains("-i") 

296 assert_that(args).contains("-bn") 

297 assert_that(args).contains("-ci") 

298 assert_that(args).contains("-sr") 

299 assert_that(args).contains("-ln") 

300 assert_that(args).contains("-s") 

301 

302 # Verify values 

303 indent_idx = args.index("-i") 

304 assert_that(args[indent_idx + 1]).is_equal_to("2") 

305 

306 ln_idx = args.index("-ln") 

307 assert_that(args[ln_idx + 1]).is_equal_to("posix")