X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/7f4b27541330e2ff35b1a010c9de0c5f618f9f4c..80425ca440136002a64e24d6be7c3ba59cc20f9c:/tests/test_black.py diff --git a/tests/test_black.py b/tests/test_black.py index 6fb01f7..3c76633 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -10,10 +10,11 @@ from pathlib import Path import regex as re import sys from tempfile import TemporaryDirectory -from typing import Any, BinaryIO, Generator, List, Tuple, Iterator, TypeVar +from typing import Any, BinaryIO, Dict, Generator, List, Tuple, Iterator, TypeVar import unittest from unittest.mock import patch, MagicMock +import click from click import unstyle from click.testing import CliRunner @@ -31,10 +32,15 @@ else: from pathspec import PathSpec +# Import other test classes +from .test_primer import PrimerCLITests # noqa: F401 + + ff = partial(black.format_file_in_place, mode=black.FileMode(), fast=True) fs = partial(black.format_str, mode=black.FileMode()) THIS_FILE = Path(__file__) THIS_DIR = THIS_FILE.parent +PROJECT_ROOT = THIS_DIR.parent DETERMINISTIC_HEADER = "[Deterministic header]" EMPTY_LINE = "# EMPTY LINE WITH WHITESPACE" + " (this comment will be removed)" PY36_ARGS = [ @@ -54,7 +60,7 @@ def read_data(name: str, data: bool = True) -> Tuple[str, str]: name += ".py" _input: List[str] = [] _output: List[str] = [] - base_dir = THIS_DIR / "data" if data else THIS_DIR + base_dir = THIS_DIR / "data" if data else PROJECT_ROOT with open(base_dir / name, "r", encoding="utf8") as test: lines = test.readlines() result = _input @@ -104,6 +110,20 @@ def skip_if_exception(e: str) -> Iterator[None]: raise +class FakeContext(click.Context): + """A fake click Context for when calling functions that need it.""" + + def __init__(self) -> None: + self.default_map: Dict[str, Any] = {} + + +class FakeParameter(click.Parameter): + """A fake click Parameter for when calling functions that need it.""" + + def __init__(self) -> None: + pass + + class BlackRunner(CliRunner): """Modify CliRunner so that stderr is not merged with stdout. @@ -202,43 +222,43 @@ class BlackTestCase(unittest.TestCase): self.checkSourceFile("tests/test_black.py") def test_black(self) -> None: - self.checkSourceFile("black.py") + self.checkSourceFile("src/black/__init__.py") def test_pygram(self) -> None: - self.checkSourceFile("blib2to3/pygram.py") + self.checkSourceFile("src/blib2to3/pygram.py") def test_pytree(self) -> None: - self.checkSourceFile("blib2to3/pytree.py") + self.checkSourceFile("src/blib2to3/pytree.py") def test_conv(self) -> None: - self.checkSourceFile("blib2to3/pgen2/conv.py") + self.checkSourceFile("src/blib2to3/pgen2/conv.py") def test_driver(self) -> None: - self.checkSourceFile("blib2to3/pgen2/driver.py") + self.checkSourceFile("src/blib2to3/pgen2/driver.py") def test_grammar(self) -> None: - self.checkSourceFile("blib2to3/pgen2/grammar.py") + self.checkSourceFile("src/blib2to3/pgen2/grammar.py") def test_literals(self) -> None: - self.checkSourceFile("blib2to3/pgen2/literals.py") + self.checkSourceFile("src/blib2to3/pgen2/literals.py") def test_parse(self) -> None: - self.checkSourceFile("blib2to3/pgen2/parse.py") + self.checkSourceFile("src/blib2to3/pgen2/parse.py") def test_pgen(self) -> None: - self.checkSourceFile("blib2to3/pgen2/pgen.py") + self.checkSourceFile("src/blib2to3/pgen2/pgen.py") def test_tokenize(self) -> None: - self.checkSourceFile("blib2to3/pgen2/tokenize.py") + self.checkSourceFile("src/blib2to3/pgen2/tokenize.py") def test_token(self) -> None: - self.checkSourceFile("blib2to3/pgen2/token.py") + self.checkSourceFile("src/blib2to3/pgen2/token.py") def test_setup(self) -> None: self.checkSourceFile("setup.py") def test_piping(self) -> None: - source, expected = read_data("../black", data=False) + source, expected = read_data("src/black/__init__", data=False) result = BlackRunner().invoke( black.main, ["-", "--fast", f"--line-length={black.DEFAULT_LINE_LENGTH}"], @@ -251,8 +271,8 @@ class BlackTestCase(unittest.TestCase): def test_piping_diff(self) -> None: diff_header = re.compile( - rf"(STDIN|STDOUT)\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d\d\d\d " - rf"\+\d\d\d\d" + r"(STDIN|STDOUT)\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d\d\d\d " + r"\+\d\d\d\d" ) source, _ = read_data("expression.py") expected, _ = read_data("expression.diff") @@ -481,6 +501,14 @@ class BlackTestCase(unittest.TestCase): black.assert_equivalent(source, actual) black.assert_stable(source, actual, black.FileMode()) + @patch("black.dump_to_file", dump_to_stderr) + def test_percent_precedence(self) -> None: + source, expected = read_data("percent_precedence") + actual = fs(source) + self.assertFormatEqual(expected, actual) + black.assert_equivalent(source, actual) + black.assert_stable(source, actual, black.FileMode()) + @patch("black.dump_to_file", dump_to_stderr) def test_comments(self) -> None: source, expected = read_data("comments") @@ -1545,7 +1573,32 @@ class BlackTestCase(unittest.TestCase): this_abs = THIS_DIR.resolve() sources.extend( black.gen_python_files( - path.iterdir(), this_abs, include, [exclude], report, gitignore + path.iterdir(), this_abs, include, exclude, None, report, gitignore + ) + ) + self.assertEqual(sorted(expected), sorted(sources)) + + @patch("black.find_project_root", lambda *args: THIS_DIR.resolve()) + def test_exclude_for_issue_1572(self) -> None: + # Exclude shouldn't touch files that were explicitly given to Black through the + # CLI. Exclude is supposed to only apply to the recursive discovery of files. + # https://github.com/psf/black/issues/1572 + path = THIS_DIR / "data" / "include_exclude_tests" + include = "" + exclude = r"/exclude/|a\.py" + src = str(path / "b/exclude/a.py") + report = black.Report() + expected = [Path(path / "b/exclude/a.py")] + sources = list( + black.get_sources( + ctx=FakeContext(), + src=(src,), + quiet=True, + verbose=False, + include=include, + exclude=exclude, + force_exclude=None, + report=report, ) ) self.assertEqual(sorted(expected), sorted(sources)) @@ -1566,7 +1619,7 @@ class BlackTestCase(unittest.TestCase): this_abs = THIS_DIR.resolve() sources.extend( black.gen_python_files( - path.iterdir(), this_abs, include, [exclude], report, gitignore + path.iterdir(), this_abs, include, exclude, None, report, gitignore ) ) self.assertEqual(sorted(expected), sorted(sources)) @@ -1594,7 +1647,8 @@ class BlackTestCase(unittest.TestCase): path.iterdir(), this_abs, empty, - [re.compile(black.DEFAULT_EXCLUDES)], + re.compile(black.DEFAULT_EXCLUDES), + None, report, gitignore, ) @@ -1621,7 +1675,8 @@ class BlackTestCase(unittest.TestCase): path.iterdir(), this_abs, re.compile(black.DEFAULT_INCLUDES), - [empty], + empty, + None, report, gitignore, ) @@ -1663,7 +1718,7 @@ class BlackTestCase(unittest.TestCase): def test_symlink_out_of_root_directory(self) -> None: path = MagicMock() - root = THIS_DIR + root = THIS_DIR.resolve() child = MagicMock() include = re.compile(black.DEFAULT_INCLUDES) exclude = re.compile(black.DEFAULT_EXCLUDES) @@ -1678,7 +1733,7 @@ class BlackTestCase(unittest.TestCase): try: list( black.gen_python_files( - path.iterdir(), root, include, exclude, report, gitignore + path.iterdir(), root, include, exclude, None, report, gitignore ) ) except ValueError as ve: @@ -1692,7 +1747,7 @@ class BlackTestCase(unittest.TestCase): with self.assertRaises(ValueError): list( black.gen_python_files( - path.iterdir(), root, include, exclude, report, gitignore + path.iterdir(), root, include, exclude, None, report, gitignore ) ) path.iterdir.assert_called() @@ -1757,6 +1812,56 @@ class BlackTestCase(unittest.TestCase): finally: tmp_file.unlink() + def test_parse_pyproject_toml(self) -> None: + test_toml_file = THIS_DIR / "test.toml" + config = black.parse_pyproject_toml(str(test_toml_file)) + self.assertEqual(config["verbose"], 1) + self.assertEqual(config["check"], "no") + self.assertEqual(config["diff"], "y") + self.assertEqual(config["color"], True) + self.assertEqual(config["line_length"], 79) + self.assertEqual(config["target_version"], ["py36", "py37", "py38"]) + self.assertEqual(config["exclude"], r"\.pyi?$") + self.assertEqual(config["include"], r"\.py?$") + + def test_read_pyproject_toml(self) -> None: + test_toml_file = THIS_DIR / "test.toml" + fake_ctx = FakeContext() + black.read_pyproject_toml( + fake_ctx, FakeParameter(), str(test_toml_file), + ) + config = fake_ctx.default_map + self.assertEqual(config["verbose"], "1") + self.assertEqual(config["check"], "no") + self.assertEqual(config["diff"], "y") + self.assertEqual(config["color"], "True") + self.assertEqual(config["line_length"], "79") + self.assertEqual(config["target_version"], ["py36", "py37", "py38"]) + self.assertEqual(config["exclude"], r"\.pyi?$") + self.assertEqual(config["include"], r"\.py?$") + + def test_find_project_root(self) -> None: + with TemporaryDirectory() as workspace: + root = Path(workspace) + test_dir = root / "test" + test_dir.mkdir() + + src_dir = root / "src" + src_dir.mkdir() + + root_pyproject = root / "pyproject.toml" + root_pyproject.touch() + src_pyproject = src_dir / "pyproject.toml" + src_pyproject.touch() + src_python = src_dir / "foo.py" + src_python.touch() + + self.assertEqual( + black.find_project_root((src_dir, test_dir)), root.resolve() + ) + self.assertEqual(black.find_project_root((src_dir,)), src_dir.resolve()) + self.assertEqual(black.find_project_root((src_python,)), src_dir.resolve()) + class BlackDTestCase(AioHTTPTestCase): async def get_application(self) -> web.Application: @@ -1847,7 +1952,7 @@ class BlackDTestCase(AioHTTPTestCase): @unittest_run_loop async def test_blackd_diff(self) -> None: diff_header = re.compile( - rf"(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")