X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/82e150a13ac78a1f24de27977d8a40883bc3d6e7..37895f8e50486a0fa581f8fb039e536dc6d0d0e4:/tests/test_blackd.py diff --git a/tests/test_blackd.py b/tests/test_blackd.py index 6174c45..325bd7d 100644 --- a/tests/test_blackd.py +++ b/tests/test_blackd.py @@ -1,30 +1,37 @@ import re -from typing import Any +from typing import TYPE_CHECKING, Any, Callable, TypeVar from unittest.mock import patch -from click.testing import CliRunner import pytest +from click.testing import CliRunner -from tests.util import read_data, DETERMINISTIC_HEADER +from tests.util import DETERMINISTIC_HEADER, read_data try: - import blackd - from aiohttp.test_utils import AioHTTPTestCase from aiohttp import web + from aiohttp.test_utils import AioHTTPTestCase + + import blackd except ImportError as e: raise RuntimeError("Please install Black with the 'd' extra") from e -try: - from aiohttp.test_utils import unittest_run_loop -except ImportError: - # unittest_run_loop is unnecessary and a no-op since aiohttp 3.8, and aiohttp 4 - # removed it. To maintain compatibility we can make our own no-op decorator. - def unittest_run_loop(func: Any, *args: Any, **kwargs: Any) -> Any: - return func +if TYPE_CHECKING: + F = TypeVar("F", bound=Callable[..., Any]) + + unittest_run_loop: Callable[[F], F] = lambda x: x +else: + try: + from aiohttp.test_utils import unittest_run_loop + except ImportError: + # unittest_run_loop is unnecessary and a no-op since aiohttp 3.8, and + # aiohttp 4 removed it. To maintain compatibility we can make our own + # no-op decorator. + def unittest_run_loop(func, *args, **kwargs): + return func @pytest.mark.blackd -class BlackDTestCase(AioHTTPTestCase): +class BlackDTestCase(AioHTTPTestCase): # type: ignore[misc] def test_blackd_main(self) -> None: with patch("blackd.web.run_app"): result = CliRunner().invoke(blackd.main, []) @@ -76,7 +83,9 @@ class BlackDTestCase(AioHTTPTestCase): async def test_blackd_invalid_python_variant(self) -> None: async def check(header_value: str, expected_status: int = 400) -> None: response = await self.client.post( - "/", data=b"what", headers={blackd.PYTHON_VARIANT_HEADER: header_value} + "/", + data=b"what", + headers={blackd.PYTHON_VARIANT_HEADER: header_value}, ) self.assertEqual(response.status, expected_status) @@ -95,7 +104,7 @@ class BlackDTestCase(AioHTTPTestCase): @unittest_run_loop async def test_blackd_pyi(self) -> None: - source, expected = read_data("stub.pyi") + source, expected = read_data("miscellaneous", "stub.pyi") response = await self.client.post( "/", data=source, headers={blackd.PYTHON_VARIANT_HEADER: "pyi"} ) @@ -105,11 +114,11 @@ class BlackDTestCase(AioHTTPTestCase): @unittest_run_loop async def test_blackd_diff(self) -> None: diff_header = re.compile( - 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" + 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" ) - source, _ = read_data("blackd_diff.py") - expected, _ = read_data("blackd_diff.diff") + source, _ = read_data("miscellaneous", "blackd_diff") + expected, _ = read_data("miscellaneous", "blackd_diff.diff") response = await self.client.post( "/", data=source, headers={blackd.DIFF_HEADER: "true"} @@ -162,10 +171,33 @@ class BlackDTestCase(AioHTTPTestCase): @unittest_run_loop async def test_blackd_invalid_line_length(self) -> None: response = await self.client.post( - "/", data=b'print("hello")\n', headers={blackd.LINE_LENGTH_HEADER: "NaN"} + "/", + data=b'print("hello")\n', + headers={blackd.LINE_LENGTH_HEADER: "NaN"}, ) self.assertEqual(response.status, 400) + @unittest_run_loop + async def test_blackd_skip_first_source_line(self) -> None: + invalid_first_line = b"Header will be skipped\r\ni = [1,2,3]\nj = [1,2,3]\n" + expected_result = b"Header will be skipped\r\ni = [1, 2, 3]\nj = [1, 2, 3]\n" + response = await self.client.post("/", data=invalid_first_line) + self.assertEqual(response.status, 400) + response = await self.client.post( + "/", + data=invalid_first_line, + headers={blackd.SKIP_SOURCE_FIRST_LINE: "true"}, + ) + self.assertEqual(response.status, 200) + self.assertEqual(await response.read(), expected_result) + + @unittest_run_loop + async def test_blackd_preview(self) -> None: + response = await self.client.post( + "/", data=b'print("hello")\n', headers={blackd.PREVIEW: "true"} + ) + self.assertEqual(response.status, 204) + @unittest_run_loop async def test_blackd_response_black_version_header(self) -> None: response = await self.client.post("/") @@ -191,3 +223,20 @@ class BlackDTestCase(AioHTTPTestCase): response = await self.client.post("/", headers={"Origin": "*"}) self.assertIsNotNone(response.headers.get("Access-Control-Allow-Origin")) self.assertIsNotNone(response.headers.get("Access-Control-Expose-Headers")) + + @unittest_run_loop + async def test_preserves_line_endings(self) -> None: + for data in (b"c\r\nc\r\n", b"l\nl\n"): + # test preserved newlines when reformatted + response = await self.client.post("/", data=data + b" ") + self.assertEqual(await response.text(), data.decode()) + # test 204 when no change + response = await self.client.post("/", data=data) + self.assertEqual(response.status, 204) + + @unittest_run_loop + async def test_normalizes_line_endings(self) -> None: + for data, expected in ((b"c\r\nc\n", "c\r\nc\r\n"), (b"l\nl\r\n", "l\nl\n")): + response = await self.client.post("/", data=data) + self.assertEqual(await response.text(), expected) + self.assertEqual(response.status, 200)