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.
2 from functools import partial
3 from io import StringIO
5 from pathlib import Path
7 from typing import Any, List, Tuple
9 from unittest.mock import patch
11 from click import unstyle
16 ff = partial(black.format_file_in_place, line_length=ll, fast=True)
17 fs = partial(black.format_str, line_length=ll)
18 THIS_FILE = Path(__file__)
19 THIS_DIR = THIS_FILE.parent
22 def dump_to_stderr(*output: str) -> str:
23 return '\n' + '\n'.join(output) + '\n'
26 def read_data(name: str) -> Tuple[str, str]:
27 """read_data('test_name') -> 'input', 'output'"""
28 if not name.endswith('.py'):
30 _input: List[str] = []
31 _output: List[str] = []
32 with open(THIS_DIR / name, 'r', encoding='utf8') as test:
33 lines = test.readlines()
36 if line.rstrip() == '# output':
41 if _input and not _output:
42 # If there's no output marker, treat the entire file as already pre-formatted.
44 return ''.join(_input).strip() + '\n', ''.join(_output).strip() + '\n'
47 class BlackTestCase(unittest.TestCase):
50 def assertFormatEqual(self, expected: str, actual: str) -> None:
51 if actual != expected and not os.environ.get('SKIP_AST_PRINT'):
52 bdv: black.DebugVisitor[Any]
53 black.out('Expected tree:', fg='green')
55 exp_node = black.lib2to3_parse(expected)
56 bdv = black.DebugVisitor()
57 list(bdv.visit(exp_node))
58 except Exception as ve:
60 black.out('Actual tree:', fg='red')
62 exp_node = black.lib2to3_parse(actual)
63 bdv = black.DebugVisitor()
64 list(bdv.visit(exp_node))
65 except Exception as ve:
67 self.assertEqual(expected, actual)
69 @patch("black.dump_to_file", dump_to_stderr)
70 def test_self(self) -> None:
71 source, expected = read_data('test_black')
73 self.assertFormatEqual(expected, actual)
74 black.assert_equivalent(source, actual)
75 black.assert_stable(source, actual, line_length=ll)
76 self.assertFalse(ff(THIS_FILE))
78 @patch("black.dump_to_file", dump_to_stderr)
79 def test_black(self) -> None:
80 source, expected = read_data('../black')
82 self.assertFormatEqual(expected, actual)
83 black.assert_equivalent(source, actual)
84 black.assert_stable(source, actual, line_length=ll)
85 self.assertFalse(ff(THIS_DIR / '..' / 'black.py'))
87 def test_piping(self) -> None:
88 source, expected = read_data('../black')
89 hold_stdin, hold_stdout = sys.stdin, sys.stdout
91 sys.stdin, sys.stdout = StringIO(source), StringIO()
92 sys.stdin.name = '<stdin>'
93 black.format_stdin_to_stdout(line_length=ll, fast=True, write_back=True)
95 actual = sys.stdout.read()
97 sys.stdin, sys.stdout = hold_stdin, hold_stdout
98 self.assertFormatEqual(expected, actual)
99 black.assert_equivalent(source, actual)
100 black.assert_stable(source, actual, line_length=ll)
102 @patch("black.dump_to_file", dump_to_stderr)
103 def test_setup(self) -> None:
104 source, expected = read_data('../setup')
106 self.assertFormatEqual(expected, actual)
107 black.assert_equivalent(source, actual)
108 black.assert_stable(source, actual, line_length=ll)
109 self.assertFalse(ff(THIS_DIR / '..' / 'setup.py'))
111 @patch("black.dump_to_file", dump_to_stderr)
112 def test_function(self) -> None:
113 source, expected = read_data('function')
115 self.assertFormatEqual(expected, actual)
116 black.assert_equivalent(source, actual)
117 black.assert_stable(source, actual, line_length=ll)
119 @patch("black.dump_to_file", dump_to_stderr)
120 def test_expression(self) -> None:
121 source, expected = read_data('expression')
123 self.assertFormatEqual(expected, actual)
124 black.assert_equivalent(source, actual)
125 black.assert_stable(source, actual, line_length=ll)
127 @patch("black.dump_to_file", dump_to_stderr)
128 def test_fstring(self) -> None:
129 source, expected = read_data('fstring')
131 self.assertFormatEqual(expected, actual)
132 black.assert_equivalent(source, actual)
133 black.assert_stable(source, actual, line_length=ll)
135 @patch("black.dump_to_file", dump_to_stderr)
136 def test_comments(self) -> None:
137 source, expected = read_data('comments')
139 self.assertFormatEqual(expected, actual)
140 black.assert_equivalent(source, actual)
141 black.assert_stable(source, actual, line_length=ll)
143 @patch("black.dump_to_file", dump_to_stderr)
144 def test_comments2(self) -> None:
145 source, expected = read_data('comments2')
147 self.assertFormatEqual(expected, actual)
148 black.assert_equivalent(source, actual)
149 black.assert_stable(source, actual, line_length=ll)
151 @patch("black.dump_to_file", dump_to_stderr)
152 def test_cantfit(self) -> None:
153 source, expected = read_data('cantfit')
155 self.assertFormatEqual(expected, actual)
156 black.assert_equivalent(source, actual)
157 black.assert_stable(source, actual, line_length=ll)
159 @patch("black.dump_to_file", dump_to_stderr)
160 def test_import_spacing(self) -> None:
161 source, expected = read_data('import_spacing')
163 self.assertFormatEqual(expected, actual)
164 black.assert_equivalent(source, actual)
165 black.assert_stable(source, actual, line_length=ll)
167 @patch("black.dump_to_file", dump_to_stderr)
168 def test_composition(self) -> None:
169 source, expected = read_data('composition')
171 self.assertFormatEqual(expected, actual)
172 black.assert_equivalent(source, actual)
173 black.assert_stable(source, actual, line_length=ll)
175 @patch("black.dump_to_file", dump_to_stderr)
176 def test_empty_lines(self) -> None:
177 source, expected = read_data('empty_lines')
179 self.assertFormatEqual(expected, actual)
180 black.assert_equivalent(source, actual)
181 black.assert_stable(source, actual, line_length=ll)
183 @patch("black.dump_to_file", dump_to_stderr)
184 def test_python2(self) -> None:
185 source, expected = read_data('python2')
187 self.assertFormatEqual(expected, actual)
188 # black.assert_equivalent(source, actual)
189 black.assert_stable(source, actual, line_length=ll)
191 def test_report(self) -> None:
192 report = black.Report()
196 def out(msg: str, **kwargs: Any) -> None:
197 out_lines.append(msg)
199 def err(msg: str, **kwargs: Any) -> None:
200 err_lines.append(msg)
202 with patch("black.out", out), patch("black.err", err):
203 report.done(Path('f1'), changed=False)
204 self.assertEqual(len(out_lines), 1)
205 self.assertEqual(len(err_lines), 0)
206 self.assertEqual(out_lines[-1], 'f1 already well formatted, good job.')
207 self.assertEqual(unstyle(str(report)), '1 file left unchanged.')
208 self.assertEqual(report.return_code, 0)
209 report.done(Path('f2'), changed=True)
210 self.assertEqual(len(out_lines), 2)
211 self.assertEqual(len(err_lines), 0)
212 self.assertEqual(out_lines[-1], 'reformatted f2')
214 unstyle(str(report)), '1 file reformatted, 1 file left unchanged.'
216 self.assertEqual(report.return_code, 0)
218 self.assertEqual(report.return_code, 1)
220 report.failed(Path('e1'), 'boom')
221 self.assertEqual(len(out_lines), 2)
222 self.assertEqual(len(err_lines), 1)
223 self.assertEqual(err_lines[-1], 'error: cannot format e1: boom')
225 unstyle(str(report)),
226 '1 file reformatted, 1 file left unchanged, '
227 '1 file failed to reformat.',
229 self.assertEqual(report.return_code, 123)
230 report.done(Path('f3'), changed=True)
231 self.assertEqual(len(out_lines), 3)
232 self.assertEqual(len(err_lines), 1)
233 self.assertEqual(out_lines[-1], 'reformatted f3')
235 unstyle(str(report)),
236 '2 files reformatted, 1 file left unchanged, '
237 '1 file failed to reformat.',
239 self.assertEqual(report.return_code, 123)
240 report.failed(Path('e2'), 'boom')
241 self.assertEqual(len(out_lines), 3)
242 self.assertEqual(len(err_lines), 2)
243 self.assertEqual(err_lines[-1], 'error: cannot format e2: boom')
245 unstyle(str(report)),
246 '2 files reformatted, 1 file left unchanged, '
247 '2 files failed to reformat.',
249 self.assertEqual(report.return_code, 123)
250 report.done(Path('f4'), changed=False)
251 self.assertEqual(len(out_lines), 4)
252 self.assertEqual(len(err_lines), 2)
253 self.assertEqual(out_lines[-1], 'f4 already well formatted, good job.')
255 unstyle(str(report)),
256 '2 files reformatted, 2 files left unchanged, '
257 '2 files failed to reformat.',
259 self.assertEqual(report.return_code, 123)
262 unstyle(str(report)),
263 '2 files would be reformatted, 2 files would be left unchanged, '
264 '2 files would fail to reformat.',
267 def test_is_python36(self) -> None:
268 node = black.lib2to3_parse("def f(*, arg): ...\n")
269 self.assertFalse(black.is_python36(node))
270 node = black.lib2to3_parse("def f(*, arg,): ...\n")
271 self.assertTrue(black.is_python36(node))
272 node = black.lib2to3_parse("def f(*, arg): f'string'\n")
273 self.assertTrue(black.is_python36(node))
274 source, expected = read_data('function')
275 node = black.lib2to3_parse(source)
276 self.assertTrue(black.is_python36(node))
277 node = black.lib2to3_parse(expected)
278 self.assertTrue(black.is_python36(node))
279 source, expected = read_data('expression')
280 node = black.lib2to3_parse(source)
281 self.assertFalse(black.is_python36(node))
282 node = black.lib2to3_parse(expected)
283 self.assertFalse(black.is_python36(node))
286 if __name__ == '__main__':