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

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