]> git.madduck.net Git - etc/vim.git/blob - tests/test_format.py

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

add FAQ entry about undetected syntax errors (#2645)
[etc/vim.git] / tests / test_format.py
1 from dataclasses import replace
2 from typing import Any, Iterator
3 from unittest.mock import patch
4
5 import pytest
6
7 import black
8 from tests.util import (
9     DEFAULT_MODE,
10     PY36_VERSIONS,
11     THIS_DIR,
12     assert_format,
13     dump_to_stderr,
14     read_data,
15 )
16
17 SIMPLE_CASES = [
18     "beginning_backslash",
19     "bracketmatch",
20     "class_blank_parentheses",
21     "class_methods_new_line",
22     "collections",
23     "comments",
24     "comments2",
25     "comments3",
26     "comments4",
27     "comments5",
28     "comments6",
29     "comments_non_breaking_space",
30     "comment_after_escaped_newline",
31     "composition",
32     "composition_no_trailing_comma",
33     "docstring",
34     "empty_lines",
35     "expression",
36     "fmtonoff",
37     "fmtonoff2",
38     "fmtonoff3",
39     "fmtonoff4",
40     "fmtskip",
41     "fmtskip2",
42     "fmtskip3",
43     "fmtskip4",
44     "fmtskip5",
45     "fmtskip6",
46     "fstring",
47     "function",
48     "function2",
49     "function_trailing_comma",
50     "import_spacing",
51     "remove_parens",
52     "slices",
53     "string_prefixes",
54     "tricky_unicode_symbols",
55     "tupleassign",
56 ]
57
58 SIMPLE_CASES_PY2 = [
59     "numeric_literals_py2",
60     "python2",
61     "python2_unicode_literals",
62 ]
63
64 EXPERIMENTAL_STRING_PROCESSING_CASES = [
65     "cantfit",
66     "comments7",
67     "long_strings",
68     "long_strings__edge_case",
69     "long_strings__regression",
70     "percent_precedence",
71 ]
72
73 PY310_CASES = [
74     "pattern_matching_simple",
75     "pattern_matching_complex",
76     "pattern_matching_extras",
77     "parenthesized_context_managers",
78 ]
79
80 SOURCES = [
81     "src/black/__init__.py",
82     "src/black/__main__.py",
83     "src/black/brackets.py",
84     "src/black/cache.py",
85     "src/black/comments.py",
86     "src/black/concurrency.py",
87     "src/black/const.py",
88     "src/black/debug.py",
89     "src/black/files.py",
90     "src/black/linegen.py",
91     "src/black/lines.py",
92     "src/black/mode.py",
93     "src/black/nodes.py",
94     "src/black/numerics.py",
95     "src/black/output.py",
96     "src/black/parsing.py",
97     "src/black/report.py",
98     "src/black/rusty.py",
99     "src/black/strings.py",
100     "src/black/trans.py",
101     "src/blackd/__init__.py",
102     "src/black_primer/cli.py",
103     "src/black_primer/lib.py",
104     "src/blib2to3/pygram.py",
105     "src/blib2to3/pytree.py",
106     "src/blib2to3/pgen2/conv.py",
107     "src/blib2to3/pgen2/driver.py",
108     "src/blib2to3/pgen2/grammar.py",
109     "src/blib2to3/pgen2/literals.py",
110     "src/blib2to3/pgen2/parse.py",
111     "src/blib2to3/pgen2/pgen.py",
112     "src/blib2to3/pgen2/tokenize.py",
113     "src/blib2to3/pgen2/token.py",
114     "setup.py",
115     "tests/test_black.py",
116     "tests/test_blackd.py",
117     "tests/test_format.py",
118     "tests/test_primer.py",
119     "tests/optional.py",
120     "tests/util.py",
121     "tests/conftest.py",
122 ]
123
124
125 @pytest.fixture(autouse=True)
126 def patch_dump_to_file(request: Any) -> Iterator[None]:
127     with patch("black.dump_to_file", dump_to_stderr):
128         yield
129
130
131 def check_file(filename: str, mode: black.Mode, *, data: bool = True) -> None:
132     source, expected = read_data(filename, data=data)
133     assert_format(source, expected, mode, fast=False)
134
135
136 @pytest.mark.parametrize("filename", SIMPLE_CASES_PY2)
137 @pytest.mark.python2
138 def test_simple_format_py2(filename: str) -> None:
139     check_file(filename, DEFAULT_MODE)
140
141
142 @pytest.mark.parametrize("filename", SIMPLE_CASES)
143 def test_simple_format(filename: str) -> None:
144     check_file(filename, DEFAULT_MODE)
145
146
147 @pytest.mark.parametrize("filename", EXPERIMENTAL_STRING_PROCESSING_CASES)
148 def test_experimental_format(filename: str) -> None:
149     check_file(filename, black.Mode(experimental_string_processing=True))
150
151
152 @pytest.mark.parametrize("filename", SOURCES)
153 def test_source_is_formatted(filename: str) -> None:
154     path = THIS_DIR.parent / filename
155     check_file(str(path), DEFAULT_MODE, data=False)
156
157
158 # =============== #
159 # Complex cases
160 # ============= #
161
162
163 def test_empty() -> None:
164     source = expected = ""
165     assert_format(source, expected)
166
167
168 def test_pep_572() -> None:
169     source, expected = read_data("pep_572")
170     assert_format(source, expected, minimum_version=(3, 8))
171
172
173 def test_pep_572_remove_parens() -> None:
174     source, expected = read_data("pep_572_remove_parens")
175     assert_format(source, expected, minimum_version=(3, 8))
176
177
178 def test_pep_572_do_not_remove_parens() -> None:
179     source, expected = read_data("pep_572_do_not_remove_parens")
180     # the AST safety checks will fail, but that's expected, just make sure no
181     # parentheses are touched
182     assert_format(source, expected, fast=True)
183
184
185 @pytest.mark.parametrize("major, minor", [(3, 9), (3, 10)])
186 def test_pep_572_newer_syntax(major: int, minor: int) -> None:
187     source, expected = read_data(f"pep_572_py{major}{minor}")
188     assert_format(source, expected, minimum_version=(major, minor))
189
190
191 def test_pep_570() -> None:
192     source, expected = read_data("pep_570")
193     assert_format(source, expected, minimum_version=(3, 8))
194
195
196 @pytest.mark.parametrize("filename", PY310_CASES)
197 def test_python_310(filename: str) -> None:
198     source, expected = read_data(filename)
199     mode = black.Mode(target_versions={black.TargetVersion.PY310})
200     assert_format(source, expected, mode, minimum_version=(3, 10))
201
202
203 def test_docstring_no_string_normalization() -> None:
204     """Like test_docstring but with string normalization off."""
205     source, expected = read_data("docstring_no_string_normalization")
206     mode = replace(DEFAULT_MODE, string_normalization=False)
207     assert_format(source, expected, mode)
208
209
210 def test_long_strings_flag_disabled() -> None:
211     """Tests for turning off the string processing logic."""
212     source, expected = read_data("long_strings_flag_disabled")
213     mode = replace(DEFAULT_MODE, experimental_string_processing=False)
214     assert_format(source, expected, mode)
215
216
217 def test_numeric_literals() -> None:
218     source, expected = read_data("numeric_literals")
219     mode = replace(DEFAULT_MODE, target_versions=PY36_VERSIONS)
220     assert_format(source, expected, mode)
221
222
223 def test_numeric_literals_ignoring_underscores() -> None:
224     source, expected = read_data("numeric_literals_skip_underscores")
225     mode = replace(DEFAULT_MODE, target_versions=PY36_VERSIONS)
226     assert_format(source, expected, mode)
227
228
229 @pytest.mark.python2
230 def test_python2_print_function() -> None:
231     source, expected = read_data("python2_print_function")
232     mode = replace(DEFAULT_MODE, target_versions={black.TargetVersion.PY27})
233     assert_format(source, expected, mode)
234
235
236 def test_stub() -> None:
237     mode = replace(DEFAULT_MODE, is_pyi=True)
238     source, expected = read_data("stub.pyi")
239     assert_format(source, expected, mode)
240
241
242 def test_python38() -> None:
243     source, expected = read_data("python38")
244     assert_format(source, expected, minimum_version=(3, 8))
245
246
247 def test_python39() -> None:
248     source, expected = read_data("python39")
249     assert_format(source, expected, minimum_version=(3, 9))