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

Bump docker/login-action from 1 to 2 (#3059)
[etc/vim.git] / tests / test_format.py
1 from dataclasses import replace
2 from typing import Any, Iterator, List
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     all_data_cases,
16 )
17
18 PY310_CASES: List[str] = [
19     "starred_for_target",
20     "pattern_matching_simple",
21     "pattern_matching_complex",
22     "pattern_matching_extras",
23     "pattern_matching_style",
24     "pattern_matching_generic",
25     "parenthesized_context_managers",
26 ]
27
28 PY311_CASES: List[str] = [
29     "pep_654",
30     "pep_654_style",
31 ]
32
33 PREVIEW_CASES: List[str] = [
34     # string processing
35     "cantfit",
36     "comments7",
37     "comments8",
38     "long_strings",
39     "long_strings__edge_case",
40     "long_strings__regression",
41     "percent_precedence",
42     "remove_except_parens",
43     "remove_for_brackets",
44     "one_element_subscript",
45     "remove_await_parens",
46     "return_annotation_brackets",
47     "docstring_preview",
48 ]
49
50 SOURCES: List[str] = [
51     "src/black/__init__.py",
52     "src/black/__main__.py",
53     "src/black/brackets.py",
54     "src/black/cache.py",
55     "src/black/comments.py",
56     "src/black/concurrency.py",
57     "src/black/const.py",
58     "src/black/debug.py",
59     "src/black/files.py",
60     "src/black/linegen.py",
61     "src/black/lines.py",
62     "src/black/mode.py",
63     "src/black/nodes.py",
64     "src/black/numerics.py",
65     "src/black/output.py",
66     "src/black/parsing.py",
67     "src/black/report.py",
68     "src/black/rusty.py",
69     "src/black/strings.py",
70     "src/black/trans.py",
71     "src/blackd/__init__.py",
72     "src/blib2to3/pygram.py",
73     "src/blib2to3/pytree.py",
74     "src/blib2to3/pgen2/conv.py",
75     "src/blib2to3/pgen2/driver.py",
76     "src/blib2to3/pgen2/grammar.py",
77     "src/blib2to3/pgen2/literals.py",
78     "src/blib2to3/pgen2/parse.py",
79     "src/blib2to3/pgen2/pgen.py",
80     "src/blib2to3/pgen2/tokenize.py",
81     "src/blib2to3/pgen2/token.py",
82     "setup.py",
83     "tests/test_black.py",
84     "tests/test_blackd.py",
85     "tests/test_format.py",
86     "tests/optional.py",
87     "tests/util.py",
88     "tests/conftest.py",
89 ]
90
91
92 @pytest.fixture(autouse=True)
93 def patch_dump_to_file(request: Any) -> Iterator[None]:
94     with patch("black.dump_to_file", dump_to_stderr):
95         yield
96
97
98 def check_file(filename: str, mode: black.Mode, *, data: bool = True) -> None:
99     source, expected = read_data(filename, data=data)
100     assert_format(source, expected, mode, fast=False)
101
102
103 @pytest.mark.parametrize("filename", all_data_cases("simple_cases"))
104 def test_simple_format(filename: str) -> None:
105     check_file(filename, DEFAULT_MODE)
106
107
108 @pytest.mark.parametrize("filename", PREVIEW_CASES)
109 def test_preview_format(filename: str) -> None:
110     check_file(filename, black.Mode(preview=True))
111
112
113 @pytest.mark.parametrize("filename", SOURCES)
114 def test_source_is_formatted(filename: str) -> None:
115     path = THIS_DIR.parent / filename
116     check_file(str(path), DEFAULT_MODE, data=False)
117
118
119 # =============== #
120 # Complex cases
121 # ============= #
122
123
124 def test_empty() -> None:
125     source = expected = ""
126     assert_format(source, expected)
127
128
129 def test_pep_572() -> None:
130     source, expected = read_data("pep_572")
131     assert_format(source, expected, minimum_version=(3, 8))
132
133
134 def test_pep_572_remove_parens() -> None:
135     source, expected = read_data("pep_572_remove_parens")
136     assert_format(source, expected, minimum_version=(3, 8))
137
138
139 def test_pep_572_do_not_remove_parens() -> None:
140     source, expected = read_data("pep_572_do_not_remove_parens")
141     # the AST safety checks will fail, but that's expected, just make sure no
142     # parentheses are touched
143     assert_format(source, expected, fast=True)
144
145
146 @pytest.mark.parametrize("major, minor", [(3, 9), (3, 10)])
147 def test_pep_572_newer_syntax(major: int, minor: int) -> None:
148     source, expected = read_data(f"pep_572_py{major}{minor}")
149     assert_format(source, expected, minimum_version=(major, minor))
150
151
152 def test_pep_570() -> None:
153     source, expected = read_data("pep_570")
154     assert_format(source, expected, minimum_version=(3, 8))
155
156
157 def test_remove_with_brackets() -> None:
158     source, expected = read_data("remove_with_brackets")
159     assert_format(
160         source,
161         expected,
162         black.Mode(preview=True),
163         minimum_version=(3, 9),
164     )
165
166
167 @pytest.mark.parametrize("filename", PY310_CASES)
168 def test_python_310(filename: str) -> None:
169     source, expected = read_data(filename)
170     mode = black.Mode(target_versions={black.TargetVersion.PY310})
171     assert_format(source, expected, mode, minimum_version=(3, 10))
172
173
174 def test_python_310_without_target_version() -> None:
175     source, expected = read_data("pattern_matching_simple")
176     mode = black.Mode()
177     assert_format(source, expected, mode, minimum_version=(3, 10))
178
179
180 def test_patma_invalid() -> None:
181     source, expected = read_data("pattern_matching_invalid")
182     mode = black.Mode(target_versions={black.TargetVersion.PY310})
183     with pytest.raises(black.parsing.InvalidInput) as exc_info:
184         assert_format(source, expected, mode, minimum_version=(3, 10))
185
186     exc_info.match("Cannot parse: 10:11")
187
188
189 @pytest.mark.parametrize("filename", PY311_CASES)
190 def test_python_311(filename: str) -> None:
191     source, expected = read_data(filename)
192     mode = black.Mode(target_versions={black.TargetVersion.PY311})
193     assert_format(source, expected, mode, minimum_version=(3, 11))
194
195
196 def test_python_2_hint() -> None:
197     with pytest.raises(black.parsing.InvalidInput) as exc_info:
198         assert_format("print 'daylily'", "print 'daylily'")
199     exc_info.match(black.parsing.PY2_HINT)
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 def test_stub() -> None:
229     mode = replace(DEFAULT_MODE, is_pyi=True)
230     source, expected = read_data("stub.pyi")
231     assert_format(source, expected, mode)
232
233
234 def test_python38() -> None:
235     source, expected = read_data("python38")
236     assert_format(source, expected, minimum_version=(3, 8))
237
238
239 def test_python39() -> None:
240     source, expected = read_data("python39")
241     assert_format(source, expected, minimum_version=(3, 9))
242
243
244 def test_power_op_newline() -> None:
245     # requires line_length=0
246     source, expected = read_data("power_op_newline")
247     assert_format(source, expected, mode=black.Mode(line_length=0))