X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/cae7ae3a4d32dc51e0752d4a4e885a7792a0286d..9ce100ba61b6738298d86818a3d0eee7b18bfed7:/tests/test_black.py?ds=sidebyside diff --git a/tests/test_black.py b/tests/test_black.py index b04c0a6..74334d2 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -10,7 +10,7 @@ import sys import types import unittest from concurrent.futures import ThreadPoolExecutor -from contextlib import contextmanager +from contextlib import contextmanager, redirect_stderr from dataclasses import replace from io import BytesIO from pathlib import Path @@ -63,6 +63,7 @@ from tests.util import ( ) THIS_FILE = Path(__file__) +EMPTY_CONFIG = THIS_DIR / "data" / "empty_pyproject.toml" PY36_ARGS = [f"--target-version={version.name.lower()}" for version in PY36_VERSIONS] DEFAULT_EXCLUDE = black.re_compile_maybe_verbose(black.const.DEFAULT_EXCLUDES) DEFAULT_INCLUDE = black.re_compile_maybe_verbose(black.const.DEFAULT_INCLUDES) @@ -159,7 +160,12 @@ class BlackTestCase(BlackBaseTestCase): source, expected = read_data("src/black/__init__", data=False) result = BlackRunner().invoke( black.main, - ["-", "--fast", f"--line-length={black.DEFAULT_LINE_LENGTH}"], + [ + "-", + "--fast", + f"--line-length={black.DEFAULT_LINE_LENGTH}", + f"--config={EMPTY_CONFIG}", + ], input=BytesIO(source.encode("utf8")), ) self.assertEqual(result.exit_code, 0) @@ -175,13 +181,12 @@ class BlackTestCase(BlackBaseTestCase): ) source, _ = read_data("expression.py") expected, _ = read_data("expression.diff") - config = THIS_DIR / "data" / "empty_pyproject.toml" args = [ "-", "--fast", f"--line-length={black.DEFAULT_LINE_LENGTH}", "--diff", - f"--config={config}", + f"--config={EMPTY_CONFIG}", ] result = BlackRunner().invoke( black.main, args, input=BytesIO(source.encode("utf8")) @@ -193,14 +198,13 @@ class BlackTestCase(BlackBaseTestCase): def test_piping_diff_with_color(self) -> None: source, _ = read_data("expression.py") - config = THIS_DIR / "data" / "empty_pyproject.toml" args = [ "-", "--fast", f"--line-length={black.DEFAULT_LINE_LENGTH}", "--diff", "--color", - f"--config={config}", + f"--config={EMPTY_CONFIG}", ] result = BlackRunner().invoke( black.main, args, input=BytesIO(source.encode("utf8")) @@ -252,7 +256,6 @@ class BlackTestCase(BlackBaseTestCase): def test_expression_diff(self) -> None: source, _ = read_data("expression.py") - config = THIS_DIR / "data" / "empty_pyproject.toml" expected, _ = read_data("expression.diff") tmp_file = Path(black.dump_to_file(source)) diff_header = re.compile( @@ -261,7 +264,7 @@ class BlackTestCase(BlackBaseTestCase): ) try: result = BlackRunner().invoke( - black.main, ["--diff", str(tmp_file), f"--config={config}"] + black.main, ["--diff", str(tmp_file), f"--config={EMPTY_CONFIG}"] ) self.assertEqual(result.exit_code, 0) finally: @@ -279,12 +282,12 @@ class BlackTestCase(BlackBaseTestCase): def test_expression_diff_with_color(self) -> None: source, _ = read_data("expression.py") - config = THIS_DIR / "data" / "empty_pyproject.toml" expected, _ = read_data("expression.diff") tmp_file = Path(black.dump_to_file(source)) try: result = BlackRunner().invoke( - black.main, ["--diff", "--color", str(tmp_file), f"--config={config}"] + black.main, + ["--diff", "--color", str(tmp_file), f"--config={EMPTY_CONFIG}"], ) finally: os.unlink(tmp_file) @@ -325,7 +328,9 @@ class BlackTestCase(BlackBaseTestCase): r"\d\d:\d\d:\d\d\.\d\d\d\d\d\d \+\d\d\d\d" ) try: - result = BlackRunner().invoke(black.main, ["-C", "--diff", str(tmp_file)]) + result = BlackRunner().invoke( + black.main, ["-C", "--diff", str(tmp_file), f"--config={EMPTY_CONFIG}"] + ) self.assertEqual(result.exit_code, 0) finally: os.unlink(tmp_file) @@ -789,6 +794,12 @@ class BlackTestCase(BlackBaseTestCase): self.assertEqual( black.get_features_used(node), {Feature.ANN_ASSIGN_EXTENDED_RHS} ) + node = black.lib2to3_parse("try: pass\nexcept Something: pass") + self.assertEqual(black.get_features_used(node), set()) + node = black.lib2to3_parse("try: pass\nexcept (*Something,): pass") + self.assertEqual(black.get_features_used(node), set()) + node = black.lib2to3_parse("try: pass\nexcept *Group: pass") + self.assertEqual(black.get_features_used(node), {Feature.EXCEPT_STAR}) def test_get_features_used_for_future_flags(self) -> None: for src, features in [ @@ -911,7 +922,7 @@ class BlackTestCase(BlackBaseTestCase): self.assertEqual("".join(err_lines), "") @event_loop() - @patch("black.ProcessPoolExecutor", MagicMock(side_effect=OSError)) + @patch("concurrent.futures.ProcessPoolExecutor", MagicMock(side_effect=OSError)) def test_works_in_mono_process_only_environment(self) -> None: with cache_dir() as workspace: for f in [ @@ -1251,23 +1262,25 @@ class BlackTestCase(BlackBaseTestCase): def test_shhh_click(self) -> None: try: - from click import _unicodefun - except ModuleNotFoundError: + from click import _unicodefun # type: ignore + except ImportError: self.skipTest("Incompatible Click version") - if not hasattr(_unicodefun, "_verify_python3_env"): + + if not hasattr(_unicodefun, "_verify_python_env"): self.skipTest("Incompatible Click version") + # First, let's see if Click is crashing with a preferred ASCII charset. with patch("locale.getpreferredencoding") as gpe: gpe.return_value = "ASCII" with self.assertRaises(RuntimeError): - _unicodefun._verify_python3_env() # type: ignore + _unicodefun._verify_python_env() # Now, let's silence Click... black.patch_click() # ...and confirm it's silent. with patch("locale.getpreferredencoding") as gpe: gpe.return_value = "ASCII" try: - _unicodefun._verify_python3_env() # type: ignore + _unicodefun._verify_python_env() except RuntimeError as re: self.fail(f"`patch_click()` failed, exception still raised: {re}") @@ -1353,6 +1366,21 @@ class BlackTestCase(BlackBaseTestCase): (src_dir.resolve(), "pyproject.toml"), ) + @patch( + "black.files.find_user_pyproject_toml", + ) + def test_find_pyproject_toml(self, find_user_pyproject_toml: MagicMock) -> None: + find_user_pyproject_toml.side_effect = RuntimeError() + + with redirect_stderr(io.StringIO()) as stderr: + result = black.files.find_pyproject_toml( + path_search_start=(str(Path.cwd().root),) + ) + + assert result is None + err = stderr.getvalue() + assert "Ignoring user configuration" in err + @patch( "black.files.find_user_pyproject_toml", black.files.find_user_pyproject_toml.__wrapped__, @@ -1398,6 +1426,25 @@ class BlackTestCase(BlackBaseTestCase): normalized_path = black.normalize_path_maybe_ignore(path, root, report) self.assertEqual(normalized_path, "workspace/project") + def test_normalize_path_ignore_windows_junctions_outside_of_root(self) -> None: + if system() != "Windows": + return + + with TemporaryDirectory() as workspace: + root = Path(workspace) + junction_dir = root / "junction" + junction_target_outside_of_root = root / ".." + os.system(f"mklink /J {junction_dir} {junction_target_outside_of_root}") + + report = black.Report(verbose=True) + normalized_path = black.normalize_path_maybe_ignore( + junction_dir, root, report + ) + # Manually delete for Python < 3.8 + os.system(f"rmdir {junction_dir}") + + self.assertEqual(normalized_path, None) + def test_newline_comment_interaction(self) -> None: source = "class A:\\\r\n# type: ignore\n pass\n" output = black.format_str(source, mode=DEFAULT_MODE) @@ -1636,7 +1683,7 @@ class TestCaching: def test_cache_multiple_files(self) -> None: mode = DEFAULT_MODE with cache_dir() as workspace, patch( - "black.ProcessPoolExecutor", new=ThreadPoolExecutor + "concurrent.futures.ProcessPoolExecutor", new=ThreadPoolExecutor ): one = (workspace / "one.py").resolve() with one.open("w") as fobj: @@ -1745,7 +1792,7 @@ class TestCaching: def test_failed_formatting_does_not_get_cached(self) -> None: mode = DEFAULT_MODE with cache_dir() as workspace, patch( - "black.ProcessPoolExecutor", new=ThreadPoolExecutor + "concurrent.futures.ProcessPoolExecutor", new=ThreadPoolExecutor ): failing = (workspace / "failing.py").resolve() with failing.open("w") as fobj: @@ -1974,7 +2021,6 @@ class TestFileCollection: path.iterdir.return_value = [child] child.resolve.return_value = Path("/a/b/c") child.as_posix.return_value = "/a/b/c" - child.is_symlink.return_value = True try: list( black.gen_python_files( @@ -1994,31 +2040,6 @@ class TestFileCollection: pytest.fail(f"`get_python_files_in_dir()` failed: {ve}") path.iterdir.assert_called_once() child.resolve.assert_called_once() - child.is_symlink.assert_called_once() - # `child` should behave like a strange file which resolved path is clearly - # outside of the `root` directory. - child.is_symlink.return_value = False - with pytest.raises(ValueError): - list( - black.gen_python_files( - path.iterdir(), - root, - include, - exclude, - None, - None, - report, - gitignore, - verbose=False, - quiet=False, - ) - ) - path.iterdir.assert_called() - assert path.iterdir.call_count == 2 - child.resolve.assert_called() - assert child.resolve.call_count == 2 - child.is_symlink.assert_called() - assert child.is_symlink.call_count == 2 @patch("black.find_project_root", lambda *args: (THIS_DIR.resolve(), None)) def test_get_sources_with_stdin(self) -> None: