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

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