|
| 1 | +import ast |
| 2 | +import os |
1 | 3 | from pathlib import Path |
| 4 | +import site |
2 | 5 | import subprocess |
3 | 6 | import unittest |
4 | 7 |
|
5 | | -from bugbear import BugBearChecker |
| 8 | +from hypothesis import given |
| 9 | +from hypothesmith import from_grammar |
| 10 | + |
| 11 | +from bugbear import BugBearChecker, BugBearVisitor |
6 | 12 | from bugbear import ( |
7 | 13 | B001, |
8 | 14 | B002, |
@@ -262,5 +268,24 @@ def test_selfclean_test_bugbear(self): |
262 | 268 | self.assertEqual(proc.stderr, b"") |
263 | 269 |
|
264 | 270 |
|
| 271 | +class TestFuzz(unittest.TestCase): |
| 272 | + @given(from_grammar().map(ast.parse)) |
| 273 | + def test_does_not_crash_on_any_valid_code(self, syntax_tree): |
| 274 | + # Given any syntatically-valid source code, flake8-bugbear should |
| 275 | + # not crash. This tests doesn't check that we do the *right* thing, |
| 276 | + # just that we don't crash on valid-if-poorly-styled code! |
| 277 | + BugBearVisitor(filename="<string>", lines=[]).visit(syntax_tree) |
| 278 | + |
| 279 | + def test_does_not_crash_on_site_code(self): |
| 280 | + # Because the generator isn't perfect, we'll also test on all the code |
| 281 | + # we can easily find in our current Python environment - this includes |
| 282 | + # the standard library, and all installed packages. |
| 283 | + for base in sorted(set(site.PREFIXES)): |
| 284 | + for dirname, _, files in os.walk(base): |
| 285 | + for f in files: |
| 286 | + if f.endswith(".py"): |
| 287 | + BugBearChecker(filename=str(Path(dirname) / f)) |
| 288 | + |
| 289 | + |
265 | 290 | if __name__ == "__main__": |
266 | 291 | unittest.main() |
0 commit comments