]> git.madduck.net Git - etc/vim.git/blob - tests/test_black.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:

Add Python 3-only classifier
[etc/vim.git] / tests / test_black.py
1 #!/usr/bin/env python3
2 from functools import partial
3 from pathlib import Path
4 from typing import List, Tuple
5 import unittest
6 from unittest.mock import patch
7
8 from click import unstyle
9
10 import black
11
12 ll = 88
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
17
18
19 def dump_to_stderr(*output: str) -> str:
20     return '\n' + '\n'.join(output) + '\n'
21
22
23 def read_data(name: str) -> Tuple[str, str]:
24     """read_data('test_name') -> 'input', 'output'"""
25     if not name.endswith('.py'):
26         name += '.py'
27     _input: List[str] = []
28     _output: List[str] = []
29     with open(THIS_DIR / name, 'r', encoding='utf8') as test:
30         lines = test.readlines()
31     result = _input
32     for line in lines:
33         if line.rstrip() == '# output':
34             result = _output
35             continue
36
37         result.append(line)
38     if _input and not _output:
39         # If there's no output marker, treat the entire file as already pre-formatted.
40         _output = _input[:]
41     return ''.join(_input).strip() + '\n', ''.join(_output).strip() + '\n'
42
43
44 class BlackTestCase(unittest.TestCase):
45     maxDiff = None
46
47     def assertFormatEqual(self, expected: str, actual: str) -> None:
48         if actual != expected:
49             black.out('Expected tree:', fg='green')
50             try:
51                 exp_node = black.lib2to3_parse(expected)
52                 bdv = black.DebugVisitor()
53                 list(bdv.visit(exp_node))
54             except Exception as ve:
55                 black.err(str(ve))
56             black.out('Actual tree:', fg='red')
57             try:
58                 exp_node = black.lib2to3_parse(actual)
59                 bdv = black.DebugVisitor()
60                 list(bdv.visit(exp_node))
61             except Exception as ve:
62                 black.err(str(ve))
63         self.assertEqual(expected, actual)
64
65     @patch("black.dump_to_file", dump_to_stderr)
66     def test_self(self) -> None:
67         source, expected = read_data('test_black')
68         actual = fs(source)
69         self.assertFormatEqual(expected, actual)
70         black.assert_equivalent(source, actual)
71         black.assert_stable(source, actual, line_length=ll)
72         with self.assertRaises(black.NothingChanged):
73             ff(THIS_FILE)
74
75     @patch("black.dump_to_file", dump_to_stderr)
76     def test_black(self) -> None:
77         source, expected = read_data('../black')
78         actual = fs(source)
79         self.assertFormatEqual(expected, actual)
80         black.assert_equivalent(source, actual)
81         black.assert_stable(source, actual, line_length=ll)
82         with self.assertRaises(black.NothingChanged):
83             ff(THIS_FILE)
84
85     @patch("black.dump_to_file", dump_to_stderr)
86     def test_setup(self) -> None:
87         source, expected = read_data('../setup')
88         actual = fs(source)
89         self.assertFormatEqual(expected, actual)
90         black.assert_equivalent(source, actual)
91         black.assert_stable(source, actual, line_length=ll)
92         with self.assertRaises(black.NothingChanged):
93             ff(THIS_FILE)
94
95     @patch("black.dump_to_file", dump_to_stderr)
96     def test_function(self) -> None:
97         source, expected = read_data('function')
98         actual = fs(source)
99         self.assertFormatEqual(expected, actual)
100         black.assert_equivalent(source, actual)
101         black.assert_stable(source, actual, line_length=ll)
102
103     @patch("black.dump_to_file", dump_to_stderr)
104     def test_expression(self) -> None:
105         source, expected = read_data('expression')
106         actual = fs(source)
107         self.assertFormatEqual(expected, actual)
108         black.assert_equivalent(source, actual)
109         black.assert_stable(source, actual, line_length=ll)
110
111     @patch("black.dump_to_file", dump_to_stderr)
112     def test_comments(self) -> None:
113         source, expected = read_data('comments')
114         actual = fs(source)
115         self.assertFormatEqual(expected, actual)
116         black.assert_equivalent(source, actual)
117         black.assert_stable(source, actual, line_length=ll)
118
119     @patch("black.dump_to_file", dump_to_stderr)
120     def test_comments2(self) -> None:
121         source, expected = read_data('comments2')
122         actual = fs(source)
123         self.assertFormatEqual(expected, actual)
124         black.assert_equivalent(source, actual)
125         black.assert_stable(source, actual, line_length=ll)
126
127     @patch("black.dump_to_file", dump_to_stderr)
128     def test_cantfit(self) -> None:
129         source, expected = read_data('cantfit')
130         actual = fs(source)
131         self.assertFormatEqual(expected, actual)
132         black.assert_equivalent(source, actual)
133         black.assert_stable(source, actual, line_length=ll)
134
135     @patch("black.dump_to_file", dump_to_stderr)
136     def test_import_spacing(self) -> None:
137         source, expected = read_data('import_spacing')
138         actual = fs(source)
139         self.assertFormatEqual(expected, actual)
140         black.assert_equivalent(source, actual)
141         black.assert_stable(source, actual, line_length=ll)
142
143     @patch("black.dump_to_file", dump_to_stderr)
144     def test_composition(self) -> None:
145         source, expected = read_data('composition')
146         actual = fs(source)
147         self.assertFormatEqual(expected, actual)
148         black.assert_equivalent(source, actual)
149         black.assert_stable(source, actual, line_length=ll)
150
151     def test_report(self) -> None:
152         report = black.Report()
153         out_lines = []
154         err_lines = []
155
156         def out(msg: str, **kwargs):
157             out_lines.append(msg)
158
159         def err(msg: str, **kwargs):
160             err_lines.append(msg)
161
162         with patch("black.out", out), patch("black.err", err):
163             report.done(Path('f1'), changed=True)
164             self.assertEqual(len(out_lines), 1)
165             self.assertEqual(len(err_lines), 0)
166             self.assertEqual(out_lines[-1], 'reformatted f1')
167             self.assertEqual(unstyle(str(report)), '1 file reformatted.')
168             self.assertEqual(report.return_code, 0)
169             report.failed(Path('e1'), 'boom')
170             self.assertEqual(len(out_lines), 1)
171             self.assertEqual(len(err_lines), 1)
172             self.assertEqual(err_lines[-1], 'error: cannot format e1: boom')
173             self.assertEqual(
174                 unstyle(str(report)), '1 file reformatted, 1 file failed to reformat.'
175             )
176             self.assertEqual(report.return_code, 1)
177             report.done(Path('f2'), changed=False)
178             self.assertEqual(len(out_lines), 2)
179             self.assertEqual(len(err_lines), 1)
180             self.assertEqual(out_lines[-1], 'f2 already well formatted, good job.')
181             self.assertEqual(
182                 unstyle(str(report)),
183                 '1 file reformatted, 1 file left unchanged, '
184                 '1 file failed to reformat.',
185             )
186             self.assertEqual(report.return_code, 1)
187             report.done(Path('f3'), changed=True)
188             self.assertEqual(len(out_lines), 3)
189             self.assertEqual(len(err_lines), 1)
190             self.assertEqual(out_lines[-1], 'reformatted f3')
191             self.assertEqual(
192                 unstyle(str(report)),
193                 '2 files reformatted, 1 file left unchanged, '
194                 '1 file failed to reformat.',
195             )
196             self.assertEqual(report.return_code, 1)
197             report.failed(Path('e2'), 'boom')
198             self.assertEqual(len(out_lines), 3)
199             self.assertEqual(len(err_lines), 2)
200             self.assertEqual(err_lines[-1], 'error: cannot format e2: boom')
201             self.assertEqual(
202                 unstyle(str(report)),
203                 '2 files reformatted, 1 file left unchanged, '
204                 '2 files failed to reformat.',
205             )
206             self.assertEqual(report.return_code, 1)
207             report.done(Path('f4'), changed=False)
208             self.assertEqual(len(out_lines), 4)
209             self.assertEqual(len(err_lines), 2)
210             self.assertEqual(out_lines[-1], 'f4 already well formatted, good job.')
211             self.assertEqual(
212                 unstyle(str(report)),
213                 '2 files reformatted, 2 files left unchanged, '
214                 '2 files failed to reformat.',
215             )
216             self.assertEqual(report.return_code, 1)
217
218
219 if __name__ == '__main__':
220     unittest.main()