1"""Tests for the flake8.style_guide.DecisionEngine class.""" 2import argparse 3 4import pytest 5 6from flake8 import defaults 7from flake8 import style_guide 8 9 10def create_options(**kwargs): 11 """Create and return an instance of argparse.Namespace.""" 12 kwargs.setdefault("select", []) 13 kwargs.setdefault("extended_default_ignore", []) 14 kwargs.setdefault("extended_default_select", []) 15 kwargs.setdefault("extend_select", []) 16 kwargs.setdefault("ignore", []) 17 kwargs.setdefault("extend_ignore", []) 18 kwargs.setdefault("disable_noqa", False) 19 kwargs.setdefault("enable_extensions", []) 20 return argparse.Namespace(**kwargs) 21 22 23@pytest.mark.parametrize( 24 "ignore_list,extend_ignore,error_code", 25 [ 26 (["E111", "E121"], [], "E111"), 27 (["E111", "E121"], [], "E121"), 28 (["E111"], ["E121"], "E121"), 29 (["E11", "E12"], [], "E121"), 30 (["E2", "E12"], [], "E121"), 31 (["E2", "E12"], [], "E211"), 32 (["E2", "E3"], ["E12"], "E211"), 33 ], 34) 35def test_was_ignored_ignores_errors(ignore_list, extend_ignore, error_code): 36 """Verify we detect users explicitly ignoring an error.""" 37 decider = style_guide.DecisionEngine( 38 create_options(ignore=ignore_list, extend_ignore=extend_ignore) 39 ) 40 41 assert decider.was_ignored(error_code) is style_guide.Ignored.Explicitly 42 43 44@pytest.mark.parametrize( 45 "ignore_list,extend_ignore,error_code", 46 [ 47 (["E111", "E121"], [], "E112"), 48 (["E111", "E121"], [], "E122"), 49 (["E11", "E12"], ["E121"], "W121"), 50 (["E2", "E12"], [], "E112"), 51 (["E2", "E12"], [], "E111"), 52 (["E2", "E12"], ["W11", "E3"], "E111"), 53 ], 54) 55def test_was_ignored_implicitly_selects_errors( 56 ignore_list, extend_ignore, error_code 57): 58 """Verify we detect users does not explicitly ignore an error.""" 59 decider = style_guide.DecisionEngine( 60 create_options(ignore=ignore_list, extend_ignore=extend_ignore) 61 ) 62 63 assert decider.was_ignored(error_code) is style_guide.Selected.Implicitly 64 65 66@pytest.mark.parametrize( 67 "select_list,extend_select,enable_extensions,error_code", 68 [ 69 (["E111", "E121"], [], [], "E111"), 70 (["E111", "E121"], [], [], "E121"), 71 (["E11", "E12"], [], [], "E121"), 72 (["E2", "E12"], [], [], "E121"), 73 (["E2", "E12"], [], [], "E211"), 74 (["E1"], ["E2"], [], "E211"), 75 (["E1"], [], ["E2"], "E211"), 76 ([], ["E2"], [], "E211"), 77 ([], [], ["E2"], "E211"), 78 (["E1"], ["E2"], [], "E211"), 79 (["E111"], ["E121"], ["E2"], "E121"), 80 ], 81) 82def test_was_selected_selects_errors( 83 select_list, extend_select, enable_extensions, error_code 84): 85 """Verify we detect users explicitly selecting an error.""" 86 decider = style_guide.DecisionEngine( 87 options=create_options( 88 select=select_list, 89 extend_select=extend_select, 90 enable_extensions=enable_extensions, 91 ), 92 ) 93 94 assert decider.was_selected(error_code) is style_guide.Selected.Explicitly 95 96 97def test_was_selected_implicitly_selects_errors(): 98 """Verify we detect users implicitly selecting an error.""" 99 error_code = "E121" 100 decider = style_guide.DecisionEngine( 101 create_options( 102 select=[], 103 extended_default_select=["E"], 104 ), 105 ) 106 107 assert decider.was_selected(error_code) is style_guide.Selected.Implicitly 108 109 110@pytest.mark.parametrize( 111 "select_list,error_code", 112 [ 113 (["E111", "E121"], "E112"), 114 (["E111", "E121"], "E122"), 115 (["E11", "E12"], "E132"), 116 (["E2", "E12"], "E321"), 117 (["E2", "E12"], "E410"), 118 ], 119) 120def test_was_selected_excludes_errors(select_list, error_code): 121 """Verify we detect users implicitly excludes an error.""" 122 decider = style_guide.DecisionEngine(create_options(select=select_list)) 123 124 assert decider.was_selected(error_code) is style_guide.Ignored.Implicitly 125 126 127@pytest.mark.parametrize( 128 "select_list,ignore_list,extend_ignore,error_code,expected", 129 [ 130 (["E111", "E121"], [], [], "E111", style_guide.Decision.Selected), 131 (["E111", "E121"], [], [], "E112", style_guide.Decision.Ignored), 132 (["E111", "E121"], [], [], "E121", style_guide.Decision.Selected), 133 (["E111", "E121"], [], [], "E122", style_guide.Decision.Ignored), 134 (["E11", "E12"], [], [], "E132", style_guide.Decision.Ignored), 135 (["E2", "E12"], [], [], "E321", style_guide.Decision.Ignored), 136 (["E2", "E12"], [], [], "E410", style_guide.Decision.Ignored), 137 (["E11", "E121"], ["E1"], [], "E112", style_guide.Decision.Selected), 138 (["E11", "E121"], [], ["E1"], "E112", style_guide.Decision.Selected), 139 ( 140 ["E111", "E121"], 141 ["E2"], 142 ["E3"], 143 "E122", 144 style_guide.Decision.Ignored, 145 ), 146 (["E11", "E12"], ["E13"], [], "E132", style_guide.Decision.Ignored), 147 (["E1", "E3"], ["E32"], [], "E321", style_guide.Decision.Ignored), 148 ([], ["E2", "E12"], [], "E410", style_guide.Decision.Ignored), 149 ( 150 ["E4"], 151 ["E2", "E12", "E41"], 152 [], 153 "E410", 154 style_guide.Decision.Ignored, 155 ), 156 ( 157 ["E41"], 158 ["E2", "E12", "E4"], 159 [], 160 "E410", 161 style_guide.Decision.Selected, 162 ), 163 (["E"], ["F"], [], "E410", style_guide.Decision.Selected), 164 (["F"], [], [], "E410", style_guide.Decision.Ignored), 165 (["E"], defaults.IGNORE, [], "E126", style_guide.Decision.Selected), 166 (["W"], defaults.IGNORE, [], "E126", style_guide.Decision.Ignored), 167 (["E"], defaults.IGNORE, [], "W391", style_guide.Decision.Ignored), 168 (["E", "W"], ["E13"], [], "E131", style_guide.Decision.Ignored), 169 (defaults.SELECT, ["E13"], [], "E131", style_guide.Decision.Ignored), 170 ( 171 defaults.SELECT, 172 defaults.IGNORE, 173 ["W391"], 174 "E126", 175 style_guide.Decision.Ignored, 176 ), 177 ( 178 defaults.SELECT, 179 defaults.IGNORE, 180 [], 181 "W391", 182 style_guide.Decision.Selected, 183 ), 184 ], 185) 186def test_decision_for( 187 select_list, ignore_list, extend_ignore, error_code, expected 188): 189 """Verify we decide when to report an error.""" 190 decider = style_guide.DecisionEngine( 191 create_options( 192 select=select_list, 193 ignore=ignore_list, 194 extend_ignore=extend_ignore, 195 ) 196 ) 197 198 assert decider.decision_for(error_code) is expected 199 200 201@pytest.mark.parametrize( 202 "select,ignore,extended_default_ignore,extended_default_select," 203 "enabled_extensions,error_code,expected", 204 [ 205 ( 206 defaults.SELECT, 207 [], 208 [], 209 ["I1"], 210 [], 211 "I100", 212 style_guide.Decision.Selected, 213 ), 214 ( 215 defaults.SELECT, 216 [], 217 [], 218 ["I1"], 219 [], 220 "I201", 221 style_guide.Decision.Ignored, 222 ), 223 ( 224 defaults.SELECT, 225 ["I2"], 226 [], 227 ["I1"], 228 [], 229 "I101", 230 style_guide.Decision.Selected, 231 ), 232 ( 233 defaults.SELECT, 234 ["I2"], 235 [], 236 ["I1"], 237 [], 238 "I201", 239 style_guide.Decision.Ignored, 240 ), 241 ( 242 defaults.SELECT, 243 ["I1"], 244 [], 245 ["I10"], 246 [], 247 "I101", 248 style_guide.Decision.Selected, 249 ), 250 ( 251 defaults.SELECT, 252 ["I10"], 253 [], 254 ["I1"], 255 [], 256 "I101", 257 style_guide.Decision.Ignored, 258 ), 259 ( 260 defaults.SELECT, 261 [], 262 [], 263 [], 264 ["U4"], 265 "U401", 266 style_guide.Decision.Selected, 267 ), 268 ( 269 defaults.SELECT, 270 ["U401"], 271 [], 272 [], 273 ["U4"], 274 "U401", 275 style_guide.Decision.Ignored, 276 ), 277 ( 278 defaults.SELECT, 279 ["U401"], 280 [], 281 [], 282 ["U4"], 283 "U402", 284 style_guide.Decision.Selected, 285 ), 286 ( 287 ["E", "W"], 288 ["E13"], 289 [], 290 [], 291 [], 292 "E131", 293 style_guide.Decision.Ignored, 294 ), 295 ( 296 ["E", "W"], 297 ["E13"], 298 [], 299 [], 300 [], 301 "E126", 302 style_guide.Decision.Selected, 303 ), 304 (["E2"], ["E21"], [], [], [], "E221", style_guide.Decision.Selected), 305 (["E2"], ["E21"], [], [], [], "E212", style_guide.Decision.Ignored), 306 ( 307 ["F", "W"], 308 ["C90"], 309 [], 310 ["I1"], 311 [], 312 "C901", 313 style_guide.Decision.Ignored, 314 ), 315 ( 316 ["E", "W"], 317 ["C"], 318 [], 319 [], 320 [], 321 "E131", 322 style_guide.Decision.Selected, 323 ), 324 ( 325 defaults.SELECT, 326 defaults.IGNORE, 327 [], 328 [], 329 ["I"], 330 "I101", 331 style_guide.Decision.Selected, 332 ), 333 ( 334 defaults.SELECT, 335 defaults.IGNORE, 336 [], 337 ["G"], 338 ["I"], 339 "G101", 340 style_guide.Decision.Selected, 341 ), 342 ( 343 defaults.SELECT, 344 ["G1"], 345 [], 346 ["G"], 347 ["I"], 348 "G101", 349 style_guide.Decision.Ignored, 350 ), 351 ( 352 defaults.SELECT, 353 ["E126"], 354 [], 355 [], 356 ["I"], 357 "I101", 358 style_guide.Decision.Selected, 359 ), 360 ( 361 ["E", "W"], 362 defaults.IGNORE, 363 [], 364 ["I"], 365 [], 366 "I101", 367 style_guide.Decision.Ignored, 368 ), 369 ( 370 ["E", "W", "I101"], 371 defaults.IGNORE + ("I101",), 372 ["I101"], 373 [], 374 [], 375 "I101", 376 style_guide.Decision.Selected, 377 ), 378 ( 379 ["E", "W"], 380 defaults.IGNORE + ("I101",), 381 ["I101"], 382 [], 383 [], 384 "I101", 385 style_guide.Decision.Ignored, 386 ), 387 # TODO(sigmavirus24) Figure out how to exercise the final catch-all 388 # return statement 389 ], 390) 391def test_more_specific_decision_for_logic( 392 select, 393 ignore, 394 extended_default_ignore, 395 extended_default_select, 396 enabled_extensions, 397 error_code, 398 expected, 399): 400 """Verify the logic of DecisionEngine.more_specific_decision_for.""" 401 decider = style_guide.DecisionEngine( 402 create_options( 403 select=select, 404 ignore=ignore, 405 extended_default_select=extended_default_select, 406 extended_default_ignore=extended_default_ignore, 407 enable_extensions=enabled_extensions, 408 ), 409 ) 410 411 assert decider.more_specific_decision_for(error_code) is expected 412