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 pathlib import Path
4 from typing import Any, List, Tuple
6 from unittest.mock import patch
8 from click import unstyle
13 ff = partial(black.format_file, line_length=ll, fast=True)
14 fs = partial(black.format_str, line_length=ll)
15 THIS_FILE = Path(__file__)
16 THIS_DIR = THIS_FILE.parent
19 def dump_to_stderr(*output: str) -> str:
20 return '\n' + '\n'.join(output) + '\n'
23 def read_data(name: str) -> Tuple[str, str]:
24 """read_data('test_name') -> 'input', 'output'"""
25 if not name.endswith('.py'):
27 _input: List[str] = []
28 _output: List[str] = []
29 with open(THIS_DIR / name, 'r', encoding='utf8') as test:
30 lines = test.readlines()
33 if line.rstrip() == '# output':
38 if _input and not _output:
39 # If there's no output marker, treat the entire file as already pre-formatted.
41 return ''.join(_input).strip() + '\n', ''.join(_output).strip() + '\n'
44 class BlackTestCase(unittest.TestCase):
47 def assertFormatEqual(self, expected: str, actual: str) -> None:
48 if actual != expected:
49 bdv: black.DebugVisitor[Any]
50 black.out('Expected tree:', fg='green')
52 exp_node = black.lib2to3_parse(expected)
53 bdv = black.DebugVisitor()
54 list(bdv.visit(exp_node))
55 except Exception as ve:
57 black.out('Actual tree:', fg='red')
59 exp_node = black.lib2to3_parse(actual)
60 bdv = black.DebugVisitor()
61 list(bdv.visit(exp_node))
62 except Exception as ve:
64 self.assertEqual(expected, actual)
66 @patch("black.dump_to_file", dump_to_stderr)
67 def test_self(self) -> None:
68 source, expected = read_data('test_black')
70 self.assertFormatEqual(expected, actual)
71 black.assert_equivalent(source, actual)
72 black.assert_stable(source, actual, line_length=ll)
73 with self.assertRaises(black.NothingChanged):
76 @patch("black.dump_to_file", dump_to_stderr)
77 def test_black(self) -> None:
78 source, expected = read_data('../black')
80 self.assertFormatEqual(expected, actual)
81 black.assert_equivalent(source, actual)
82 black.assert_stable(source, actual, line_length=ll)
83 with self.assertRaises(black.NothingChanged):
86 @patch("black.dump_to_file", dump_to_stderr)
87 def test_setup(self) -> None:
88 source, expected = read_data('../setup')
90 self.assertFormatEqual(expected, actual)
91 black.assert_equivalent(source, actual)
92 black.assert_stable(source, actual, line_length=ll)
93 with self.assertRaises(black.NothingChanged):
96 @patch("black.dump_to_file", dump_to_stderr)
97 def test_function(self) -> None:
98 source, expected = read_data('function')
100 self.assertFormatEqual(expected, actual)
101 black.assert_equivalent(source, actual)
102 black.assert_stable(source, actual, line_length=ll)
104 @patch("black.dump_to_file", dump_to_stderr)
105 def test_expression(self) -> None:
106 source, expected = read_data('expression')
108 self.assertFormatEqual(expected, actual)
109 black.assert_equivalent(source, actual)
110 black.assert_stable(source, actual, line_length=ll)
112 @patch("black.dump_to_file", dump_to_stderr)
113 def test_fstring(self) -> None:
114 source, expected = read_data('fstring')
116 self.assertFormatEqual(expected, actual)
117 black.assert_equivalent(source, actual)
118 black.assert_stable(source, actual, line_length=ll)
120 @patch("black.dump_to_file", dump_to_stderr)
121 def test_comments(self) -> None:
122 source, expected = read_data('comments')
124 self.assertFormatEqual(expected, actual)
125 black.assert_equivalent(source, actual)
126 black.assert_stable(source, actual, line_length=ll)
128 @patch("black.dump_to_file", dump_to_stderr)
129 def test_comments2(self) -> None:
130 source, expected = read_data('comments2')
132 self.assertFormatEqual(expected, actual)
133 black.assert_equivalent(source, actual)
134 black.assert_stable(source, actual, line_length=ll)
136 @patch("black.dump_to_file", dump_to_stderr)
137 def test_cantfit(self) -> None:
138 source, expected = read_data('cantfit')
140 self.assertFormatEqual(expected, actual)
141 black.assert_equivalent(source, actual)
142 black.assert_stable(source, actual, line_length=ll)
144 @patch("black.dump_to_file", dump_to_stderr)
145 def test_import_spacing(self) -> None:
146 source, expected = read_data('import_spacing')
148 self.assertFormatEqual(expected, actual)
149 black.assert_equivalent(source, actual)
150 black.assert_stable(source, actual, line_length=ll)
152 @patch("black.dump_to_file", dump_to_stderr)
153 def test_composition(self) -> None:
154 source, expected = read_data('composition')
156 self.assertFormatEqual(expected, actual)
157 black.assert_equivalent(source, actual)
158 black.assert_stable(source, actual, line_length=ll)
160 def test_report(self) -> None:
161 report = black.Report()
165 def out(msg: str, **kwargs: Any) -> None:
166 out_lines.append(msg)
168 def err(msg: str, **kwargs: Any) -> None:
169 err_lines.append(msg)
171 with patch("black.out", out), patch("black.err", err):
172 report.done(Path('f1'), changed=False)
173 self.assertEqual(len(out_lines), 1)
174 self.assertEqual(len(err_lines), 0)
175 self.assertEqual(out_lines[-1], 'f1 already well formatted, good job.')
176 self.assertEqual(unstyle(str(report)), '1 file left unchanged.')
177 self.assertEqual(report.return_code, 0)
178 report.done(Path('f2'), changed=True)
179 self.assertEqual(len(out_lines), 2)
180 self.assertEqual(len(err_lines), 0)
181 self.assertEqual(out_lines[-1], 'reformatted f2')
183 unstyle(str(report)), '1 file reformatted, 1 file left unchanged.'
185 self.assertEqual(report.return_code, 1)
186 report.failed(Path('e1'), 'boom')
187 self.assertEqual(len(out_lines), 2)
188 self.assertEqual(len(err_lines), 1)
189 self.assertEqual(err_lines[-1], 'error: cannot format e1: boom')
191 unstyle(str(report)),
192 '1 file reformatted, 1 file left unchanged, '
193 '1 file failed to reformat.',
195 self.assertEqual(report.return_code, 123)
196 report.done(Path('f3'), changed=True)
197 self.assertEqual(len(out_lines), 3)
198 self.assertEqual(len(err_lines), 1)
199 self.assertEqual(out_lines[-1], 'reformatted f3')
201 unstyle(str(report)),
202 '2 files reformatted, 1 file left unchanged, '
203 '1 file failed to reformat.',
205 self.assertEqual(report.return_code, 123)
206 report.failed(Path('e2'), 'boom')
207 self.assertEqual(len(out_lines), 3)
208 self.assertEqual(len(err_lines), 2)
209 self.assertEqual(err_lines[-1], 'error: cannot format e2: boom')
211 unstyle(str(report)),
212 '2 files reformatted, 1 file left unchanged, '
213 '2 files failed to reformat.',
215 self.assertEqual(report.return_code, 123)
216 report.done(Path('f4'), changed=False)
217 self.assertEqual(len(out_lines), 4)
218 self.assertEqual(len(err_lines), 2)
219 self.assertEqual(out_lines[-1], 'f4 already well formatted, good job.')
221 unstyle(str(report)),
222 '2 files reformatted, 2 files left unchanged, '
223 '2 files failed to reformat.',
225 self.assertEqual(report.return_code, 123)
227 def test_is_python36(self) -> None:
228 node = black.lib2to3_parse("def f(*, arg): ...\n")
229 self.assertFalse(black.is_python36(node))
230 node = black.lib2to3_parse("def f(*, arg,): ...\n")
231 self.assertTrue(black.is_python36(node))
232 node = black.lib2to3_parse("def f(*, arg): f'string'\n")
233 self.assertTrue(black.is_python36(node))
234 source, expected = read_data('function')
235 node = black.lib2to3_parse(source)
236 self.assertTrue(black.is_python36(node))
237 node = black.lib2to3_parse(expected)
238 self.assertTrue(black.is_python36(node))
239 source, expected = read_data('expression')
240 node = black.lib2to3_parse(source)
241 self.assertFalse(black.is_python36(node))
242 node = black.lib2to3_parse(expected)
243 self.assertFalse(black.is_python36(node))
246 if __name__ == '__main__':