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

Define a stability policy (#2529)
[etc/vim.git] / tests / test_blackd.py
1 import re
2 from unittest.mock import patch
3
4 from click.testing import CliRunner
5 import pytest
6
7 from tests.util import read_data, DETERMINISTIC_HEADER
8
9 try:
10     import blackd
11     from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
12     from aiohttp import web
13 except ImportError:
14     has_blackd_deps = False
15 else:
16     has_blackd_deps = True
17
18
19 @pytest.mark.blackd
20 class BlackDTestCase(AioHTTPTestCase):
21     def test_blackd_main(self) -> None:
22         with patch("blackd.web.run_app"):
23             result = CliRunner().invoke(blackd.main, [])
24             if result.exception is not None:
25                 raise result.exception
26             self.assertEqual(result.exit_code, 0)
27
28     async def get_application(self) -> web.Application:
29         return blackd.make_app()
30
31     @unittest_run_loop
32     async def test_blackd_request_needs_formatting(self) -> None:
33         response = await self.client.post("/", data=b"print('hello world')")
34         self.assertEqual(response.status, 200)
35         self.assertEqual(response.charset, "utf8")
36         self.assertEqual(await response.read(), b'print("hello world")\n')
37
38     @unittest_run_loop
39     async def test_blackd_request_no_change(self) -> None:
40         response = await self.client.post("/", data=b'print("hello world")\n')
41         self.assertEqual(response.status, 204)
42         self.assertEqual(await response.read(), b"")
43
44     @unittest_run_loop
45     async def test_blackd_request_syntax_error(self) -> None:
46         response = await self.client.post("/", data=b"what even ( is")
47         self.assertEqual(response.status, 400)
48         content = await response.text()
49         self.assertTrue(
50             content.startswith("Cannot parse"),
51             msg=f"Expected error to start with 'Cannot parse', got {repr(content)}",
52         )
53
54     @unittest_run_loop
55     async def test_blackd_unsupported_version(self) -> None:
56         response = await self.client.post(
57             "/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "2"}
58         )
59         self.assertEqual(response.status, 501)
60
61     @unittest_run_loop
62     async def test_blackd_supported_version(self) -> None:
63         response = await self.client.post(
64             "/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "1"}
65         )
66         self.assertEqual(response.status, 200)
67
68     @unittest_run_loop
69     async def test_blackd_invalid_python_variant(self) -> None:
70         async def check(header_value: str, expected_status: int = 400) -> None:
71             response = await self.client.post(
72                 "/", data=b"what", headers={blackd.PYTHON_VARIANT_HEADER: header_value}
73             )
74             self.assertEqual(response.status, expected_status)
75
76         await check("lol")
77         await check("ruby3.5")
78         await check("pyi3.6")
79         await check("py1.5")
80         await check("2.8")
81         await check("py2.8")
82         await check("3.0")
83         await check("pypy3.0")
84         await check("jython3.4")
85
86     @unittest_run_loop
87     async def test_blackd_pyi(self) -> None:
88         source, expected = read_data("stub.pyi")
89         response = await self.client.post(
90             "/", data=source, headers={blackd.PYTHON_VARIANT_HEADER: "pyi"}
91         )
92         self.assertEqual(response.status, 200)
93         self.assertEqual(await response.text(), expected)
94
95     @unittest_run_loop
96     async def test_blackd_diff(self) -> None:
97         diff_header = re.compile(
98             r"(In|Out)\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d\d\d\d \+\d\d\d\d"
99         )
100
101         source, _ = read_data("blackd_diff.py")
102         expected, _ = read_data("blackd_diff.diff")
103
104         response = await self.client.post(
105             "/", data=source, headers={blackd.DIFF_HEADER: "true"}
106         )
107         self.assertEqual(response.status, 200)
108
109         actual = await response.text()
110         actual = diff_header.sub(DETERMINISTIC_HEADER, actual)
111         self.assertEqual(actual, expected)
112
113     @unittest_run_loop
114     async def test_blackd_python_variant(self) -> None:
115         code = (
116             "def f(\n"
117             "    and_has_a_bunch_of,\n"
118             "    very_long_arguments_too,\n"
119             "    and_lots_of_them_as_well_lol,\n"
120             "    **and_very_long_keyword_arguments\n"
121             "):\n"
122             "    pass\n"
123         )
124
125         async def check(header_value: str, expected_status: int) -> None:
126             response = await self.client.post(
127                 "/", data=code, headers={blackd.PYTHON_VARIANT_HEADER: header_value}
128             )
129             self.assertEqual(
130                 response.status, expected_status, msg=await response.text()
131             )
132
133         await check("3.6", 200)
134         await check("py3.6", 200)
135         await check("3.6,3.7", 200)
136         await check("3.6,py3.7", 200)
137         await check("py36,py37", 200)
138         await check("36", 200)
139         await check("3.6.4", 200)
140
141         await check("2", 204)
142         await check("2.7", 204)
143         await check("py2.7", 204)
144         await check("3.4", 204)
145         await check("py3.4", 204)
146         await check("py34,py36", 204)
147         await check("34", 204)
148
149     @unittest_run_loop
150     async def test_blackd_line_length(self) -> None:
151         response = await self.client.post(
152             "/", data=b'print("hello")\n', headers={blackd.LINE_LENGTH_HEADER: "7"}
153         )
154         self.assertEqual(response.status, 200)
155
156     @unittest_run_loop
157     async def test_blackd_invalid_line_length(self) -> None:
158         response = await self.client.post(
159             "/", data=b'print("hello")\n', headers={blackd.LINE_LENGTH_HEADER: "NaN"}
160         )
161         self.assertEqual(response.status, 400)
162
163     @unittest_run_loop
164     async def test_blackd_response_black_version_header(self) -> None:
165         response = await self.client.post("/")
166         self.assertIsNotNone(response.headers.get(blackd.BLACK_VERSION_HEADER))
167
168     @unittest_run_loop
169     async def test_cors_preflight(self) -> None:
170         response = await self.client.options(
171             "/",
172             headers={
173                 "Access-Control-Request-Method": "POST",
174                 "Origin": "*",
175                 "Access-Control-Request-Headers": "Content-Type",
176             },
177         )
178         self.assertEqual(response.status, 200)
179         self.assertIsNotNone(response.headers.get("Access-Control-Allow-Origin"))
180         self.assertIsNotNone(response.headers.get("Access-Control-Allow-Headers"))
181         self.assertIsNotNone(response.headers.get("Access-Control-Allow-Methods"))
182
183     @unittest_run_loop
184     async def test_cors_headers_present(self) -> None:
185         response = await self.client.post("/", headers={"Origin": "*"})
186         self.assertIsNotNone(response.headers.get("Access-Control-Allow-Origin"))
187         self.assertIsNotNone(response.headers.get("Access-Control-Expose-Headers"))