]> 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:

black/parser: partial support for pattern matching (#2586)
[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     "parenthesized_context_managers",
77 ]
78
79 SOURCES = [
80     "src/black/__init__.py",
81     "src/black/__main__.py",
82     "src/black/brackets.py",
83     "src/black/cache.py",
84     "src/black/comments.py",
85     "src/black/concurrency.py",
86     "src/black/const.py",
87     "src/black/debug.py",
88     "src/black/files.py",
89     "src/black/linegen.py",
90     "src/black/lines.py",
91     "src/black/mode.py",
92     "src/black/nodes.py",
93     "src/black/numerics.py",
94     "src/black/output.py",
95     "src/black/parsing.py",
96     "src/black/report.py",
97     "src/black/rusty.py",
98     "src/black/strings.py",
99     "src/black/trans.py",
100     "src/blackd/__init__.py",
101     "src/black_primer/cli.py",
102     "src/black_primer/lib.py",
103     "src/blib2to3/pygram.py",
104     "src/blib2to3/pytree.py",
105     "src/blib2to3/pgen2/conv.py",
106     "src/blib2to3/pgen2/driver.py",
107     "src/blib2to3/pgen2/grammar.py",
108     "src/blib2to3/pgen2/literals.py",
109     "src/blib2to3/pgen2/parse.py",
110     "src/blib2to3/pgen2/pgen.py",
111     "src/blib2to3/pgen2/tokenize.py",
112     "src/blib2to3/pgen2/token.py",
113     "setup.py",
114     "tests/test_black.py",
115     "tests/test_blackd.py",
116     "tests/test_format.py",
117     "tests/test_primer.py",
118     "tests/optional.py",
119     "tests/util.py",
120     "tests/conftest.py",
121 ]
122
123
124 @pytest.fixture(autouse=True)
125 def patch_dump_to_file(request: Any) -> Iterator[None]:
126     with patch("black.dump_to_file", dump_to_stderr):
127         yield
128
129
130 def check_file(filename: str, mode: black.Mode, *, data: bool = True) -> None:
131     source, expected = read_data(filename, data=data)
132     assert_format(source, expected, mode, fast=False)
133
134
135 @pytest.mark.parametrize("filename", SIMPLE_CASES_PY2)
136 @pytest.mark.python2
137 def test_simple_format_py2(filename: str) -> None:
138     check_file(filename, DEFAULT_MODE)
139
140
141 @pytest.mark.parametrize("filename", SIMPLE_CASES)
142 def test_simple_format(filename: str) -> None:
143     check_file(filename, DEFAULT_MODE)
144
145
146 @pytest.mark.parametrize("filename", EXPERIMENTAL_STRING_PROCESSING_CASES)
147 def test_experimental_format(filename: str) -> None:
148     check_file(filename, black.Mode(experimental_string_processing=True))
149
150
151 @pytest.mark.parametrize("filename", SOURCES)
152 def test_source_is_formatted(filename: str) -> None:
153     path = THIS_DIR.parent / filename
154     check_file(str(path), DEFAULT_MODE, data=False)
155
156
157 # =============== #
158 # Complex cases
159 # ============= #
160
161
162 def test_empty() -> None:
163     source = expected = ""
164     assert_format(source, expected)
165
166
167 def test_pep_572() -> None:
168     source, expected = read_data("pep_572")
169     assert_format(source, expected, minimum_version=(3, 8))
170
171
172 def test_pep_572_remove_parens() -> None:
173     source, expected = read_data("pep_572_remove_parens")
174     assert_format(source, expected, minimum_version=(3, 8))
175
176
177 def test_pep_572_do_not_remove_parens() -> None:
178     source, expected = read_data("pep_572_do_not_remove_parens")
179     # the AST safety checks will fail, but that's expected, just make sure no
180     # parentheses are touched
181     assert_format(source, expected, fast=True)
182
183
184 @pytest.mark.parametrize("major, minor", [(3, 9), (3, 10)])
185 def test_pep_572_newer_syntax(major: int, minor: int) -> None:
186     source, expected = read_data(f"pep_572_py{major}{minor}")
187     assert_format(source, expected, minimum_version=(major, minor))
188
189
190 def test_pep_570() -> None:
191     source, expected = read_data("pep_570")
192     assert_format(source, expected, minimum_version=(3, 8))
193
194
195 @pytest.mark.parametrize("filename", PY310_CASES)
196 def test_python_310(filename: str) -> None:
197     source, expected = read_data(filename)
198     mode = black.Mode(target_versions={black.TargetVersion.PY310})
199     assert_format(source, expected, mode, minimum_version=(3, 10))
200
201
202 def test_docstring_no_string_normalization() -> None:
203     """Like test_docstring but with string normalization off."""
204     source, expected = read_data("docstring_no_string_normalization")
205     mode = replace(DEFAULT_MODE, string_normalization=False)
206     assert_format(source, expected, mode)
207
208
209 def test_long_strings_flag_disabled() -> None:
210     """Tests for turning off the string processing logic."""
211     source, expected = read_data("long_strings_flag_disabled")
212     mode = replace(DEFAULT_MODE, experimental_string_processing=False)
213     assert_format(source, expected, mode)
214
215
216 def test_numeric_literals() -> None:
217     source, expected = read_data("numeric_literals")
218     mode = replace(DEFAULT_MODE, target_versions=PY36_VERSIONS)
219     assert_format(source, expected, mode)
220
221
222 def test_numeric_literals_ignoring_underscores() -> None:
223     source, expected = read_data("numeric_literals_skip_underscores")
224     mode = replace(DEFAULT_MODE, target_versions=PY36_VERSIONS)
225     assert_format(source, expected, mode)
226
227
228 @pytest.mark.python2
229 def test_python2_print_function() -> None:
230     source, expected = read_data("python2_print_function")
231     mode = replace(DEFAULT_MODE, target_versions={black.TargetVersion.PY27})
232     assert_format(source, expected, mode)
233
234
235 def test_stub() -> None:
236     mode = replace(DEFAULT_MODE, is_pyi=True)
237     source, expected = read_data("stub.pyi")
238     assert_format(source, expected, mode)
239
240
241 def test_python38() -> None:
242     source, expected = read_data("python38")
243     assert_format(source, expected, minimum_version=(3, 8))
244
245
246 def test_python39() -> None:
247     source, expected = read_data("python39")
248     assert_format(source, expected, minimum_version=(3, 9))