X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/9f096d55365cb63548eef97e254c2793ae2776a0..059cb1227053e3de086076a37c46fa877342b1e4:/tests/test_black.py?ds=inline diff --git a/tests/test_black.py b/tests/test_black.py index 02926d1..595d6cd 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -31,7 +31,7 @@ def dump_to_stderr(*output: str) -> str: def read_data(name: str) -> Tuple[str, str]: """read_data('test_name') -> 'input', 'output'""" - if not name.endswith((".py", ".out", ".diff")): + if not name.endswith((".py", ".pyi", ".out", ".diff")): name += ".py" _input: List[str] = [] _output: List[str] = [] @@ -167,6 +167,14 @@ class BlackTestCase(unittest.TestCase): black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll) + @patch("black.dump_to_file", dump_to_stderr) + def test_function2(self) -> None: + source, expected = read_data("function2") + actual = fs(source) + self.assertFormatEqual(expected, actual) + black.assert_equivalent(source, actual) + black.assert_stable(source, actual, line_length=ll) + @patch("black.dump_to_file", dump_to_stderr) def test_expression(self) -> None: source, expected = read_data("expression") @@ -309,6 +317,14 @@ class BlackTestCase(unittest.TestCase): black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll) + @patch("black.dump_to_file", dump_to_stderr) + def test_string_prefixes(self) -> None: + source, expected = read_data("string_prefixes") + actual = fs(source) + self.assertFormatEqual(expected, actual) + black.assert_equivalent(source, actual) + black.assert_stable(source, actual, line_length=ll) + @patch("black.dump_to_file", dump_to_stderr) def test_python2(self) -> None: source, expected = read_data("python2") @@ -317,6 +333,21 @@ class BlackTestCase(unittest.TestCase): # black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll) + @patch("black.dump_to_file", dump_to_stderr) + def test_python2_unicode_literals(self) -> None: + source, expected = read_data("python2_unicode_literals") + actual = fs(source) + self.assertFormatEqual(expected, actual) + black.assert_stable(source, actual, line_length=ll) + + @patch("black.dump_to_file", dump_to_stderr) + def test_stub(self) -> None: + mode = black.FileMode.PYI + source, expected = read_data("stub.pyi") + actual = fs(source, mode=mode) + self.assertFormatEqual(expected, actual) + black.assert_stable(source, actual, line_length=ll, mode=mode) + @patch("black.dump_to_file", dump_to_stderr) def test_fmtonoff(self) -> None: source, expected = read_data("fmtonoff") @@ -325,6 +356,22 @@ class BlackTestCase(unittest.TestCase): black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll) + @patch("black.dump_to_file", dump_to_stderr) + def test_remove_empty_parentheses_after_class(self) -> None: + source, expected = read_data("class_blank_parentheses") + actual = fs(source) + self.assertFormatEqual(expected, actual) + black.assert_equivalent(source, actual) + black.assert_stable(source, actual, line_length=ll) + + @patch("black.dump_to_file", dump_to_stderr) + def test_new_line_between_class_and_code(self) -> None: + source, expected = read_data("class_methods_new_line") + actual = fs(source) + self.assertFormatEqual(expected, actual) + black.assert_equivalent(source, actual) + black.assert_stable(source, actual, line_length=ll) + def test_report(self) -> None: report = black.Report() out_lines = [] @@ -428,6 +475,28 @@ class BlackTestCase(unittest.TestCase): node = black.lib2to3_parse(expected) self.assertFalse(black.is_python36(node)) + def test_get_future_imports(self) -> None: + node = black.lib2to3_parse("\n") + self.assertEqual(set(), black.get_future_imports(node)) + node = black.lib2to3_parse("from __future__ import black\n") + self.assertEqual({"black"}, black.get_future_imports(node)) + node = black.lib2to3_parse("from __future__ import multiple, imports\n") + self.assertEqual({"multiple", "imports"}, black.get_future_imports(node)) + node = black.lib2to3_parse("from __future__ import (parenthesized, imports)\n") + self.assertEqual({"parenthesized", "imports"}, black.get_future_imports(node)) + node = black.lib2to3_parse( + "from __future__ import multiple\nfrom __future__ import imports\n" + ) + self.assertEqual({"multiple", "imports"}, black.get_future_imports(node)) + node = black.lib2to3_parse("# comment\nfrom __future__ import black\n") + self.assertEqual({"black"}, black.get_future_imports(node)) + node = black.lib2to3_parse('"""docstring"""\nfrom __future__ import black\n') + self.assertEqual({"black"}, black.get_future_imports(node)) + node = black.lib2to3_parse("some(other, code)\nfrom __future__ import black\n") + self.assertEqual(set(), black.get_future_imports(node)) + node = black.lib2to3_parse("from some.module import black\n") + self.assertEqual(set(), black.get_future_imports(node)) + def test_debug_visitor(self) -> None: source, _ = read_data("debug_visitor.py") expected, _ = read_data("debug_visitor.out") @@ -498,25 +567,27 @@ class BlackTestCase(unittest.TestCase): self.assertEqual("".join(err_lines), "") def test_cache_broken_file(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir() as workspace: - cache_file = black.get_cache_file(black.DEFAULT_LINE_LENGTH) + cache_file = black.get_cache_file(black.DEFAULT_LINE_LENGTH, mode) with cache_file.open("w") as fobj: fobj.write("this is not a pickle") - self.assertEqual(black.read_cache(black.DEFAULT_LINE_LENGTH), {}) + self.assertEqual(black.read_cache(black.DEFAULT_LINE_LENGTH, mode), {}) src = (workspace / "test.py").resolve() with src.open("w") as fobj: fobj.write("print('hello')") result = CliRunner().invoke(black.main, [str(src)]) self.assertEqual(result.exit_code, 0) - cache = black.read_cache(black.DEFAULT_LINE_LENGTH) + cache = black.read_cache(black.DEFAULT_LINE_LENGTH, mode) self.assertIn(src, cache) def test_cache_single_file_already_cached(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir() as workspace: src = (workspace / "test.py").resolve() with src.open("w") as fobj: fobj.write("print('hello')") - black.write_cache({}, [src], black.DEFAULT_LINE_LENGTH) + black.write_cache({}, [src], black.DEFAULT_LINE_LENGTH, mode) result = CliRunner().invoke(black.main, [str(src)]) self.assertEqual(result.exit_code, 0) with src.open("r") as fobj: @@ -524,6 +595,7 @@ class BlackTestCase(unittest.TestCase): @event_loop(close=False) def test_cache_multiple_files(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir() as workspace, patch( "black.ProcessPoolExecutor", new=ThreadPoolExecutor ): @@ -533,44 +605,48 @@ class BlackTestCase(unittest.TestCase): two = (workspace / "two.py").resolve() with two.open("w") as fobj: fobj.write("print('hello')") - black.write_cache({}, [one], black.DEFAULT_LINE_LENGTH) + black.write_cache({}, [one], black.DEFAULT_LINE_LENGTH, mode) result = CliRunner().invoke(black.main, [str(workspace)]) self.assertEqual(result.exit_code, 0) with one.open("r") as fobj: self.assertEqual(fobj.read(), "print('hello')") with two.open("r") as fobj: self.assertEqual(fobj.read(), 'print("hello")\n') - cache = black.read_cache(black.DEFAULT_LINE_LENGTH) + cache = black.read_cache(black.DEFAULT_LINE_LENGTH, mode) self.assertIn(one, cache) self.assertIn(two, cache) def test_no_cache_when_writeback_diff(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir() as workspace: src = (workspace / "test.py").resolve() with src.open("w") as fobj: fobj.write("print('hello')") result = CliRunner().invoke(black.main, [str(src), "--diff"]) self.assertEqual(result.exit_code, 0) - cache_file = black.get_cache_file(black.DEFAULT_LINE_LENGTH) + cache_file = black.get_cache_file(black.DEFAULT_LINE_LENGTH, mode) self.assertFalse(cache_file.exists()) def test_no_cache_when_stdin(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir(): result = CliRunner().invoke(black.main, ["-"], input="print('hello')") self.assertEqual(result.exit_code, 0) - cache_file = black.get_cache_file(black.DEFAULT_LINE_LENGTH) + cache_file = black.get_cache_file(black.DEFAULT_LINE_LENGTH, mode) self.assertFalse(cache_file.exists()) def test_read_cache_no_cachefile(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir(): - self.assertEqual(black.read_cache(black.DEFAULT_LINE_LENGTH), {}) + self.assertEqual(black.read_cache(black.DEFAULT_LINE_LENGTH, mode), {}) def test_write_cache_read_cache(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir() as workspace: src = (workspace / "test.py").resolve() src.touch() - black.write_cache({}, [src], black.DEFAULT_LINE_LENGTH) - cache = black.read_cache(black.DEFAULT_LINE_LENGTH) + black.write_cache({}, [src], black.DEFAULT_LINE_LENGTH, mode) + cache = black.read_cache(black.DEFAULT_LINE_LENGTH, mode) self.assertIn(src, cache) self.assertEqual(cache[src], black.get_cache_info(src)) @@ -591,13 +667,15 @@ class BlackTestCase(unittest.TestCase): self.assertEqual(done, [cached]) def test_write_cache_creates_directory_if_needed(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir(exists=False) as workspace: self.assertFalse(workspace.exists()) - black.write_cache({}, [], black.DEFAULT_LINE_LENGTH) + black.write_cache({}, [], black.DEFAULT_LINE_LENGTH, mode) self.assertTrue(workspace.exists()) @event_loop(close=False) def test_failed_formatting_does_not_get_cached(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir() as workspace, patch( "black.ProcessPoolExecutor", new=ThreadPoolExecutor ): @@ -609,15 +687,17 @@ class BlackTestCase(unittest.TestCase): fobj.write('print("hello")\n') result = CliRunner().invoke(black.main, [str(workspace)]) self.assertEqual(result.exit_code, 123) - cache = black.read_cache(black.DEFAULT_LINE_LENGTH) + cache = black.read_cache(black.DEFAULT_LINE_LENGTH, mode) self.assertNotIn(failing, cache) self.assertIn(clean, cache) def test_write_cache_write_fail(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir(), patch.object(Path, "open") as mock: mock.side_effect = OSError - black.write_cache({}, [], black.DEFAULT_LINE_LENGTH) + black.write_cache({}, [], black.DEFAULT_LINE_LENGTH, mode) + @event_loop(close=False) def test_check_diff_use_together(self) -> None: with cache_dir(): # Files which will be reformatted. @@ -634,18 +714,138 @@ class BlackTestCase(unittest.TestCase): result = CliRunner().invoke( black.main, [str(src1), str(src2), "--diff", "--check"] ) - self.assertEqual(result.exit_code, 1) + self.assertEqual(result.exit_code, 1, result.output) + + def test_no_files(self) -> None: + with cache_dir(): + # Without an argument, black exits with error code 0. + result = CliRunner().invoke(black.main, []) + self.assertEqual(result.exit_code, 0) + + def test_broken_symlink(self) -> None: + with cache_dir() as workspace: + symlink = workspace / "broken_link.py" + symlink.symlink_to("nonexistent.py") + result = CliRunner().invoke(black.main, [str(workspace.resolve())]) + self.assertEqual(result.exit_code, 0) def test_read_cache_line_lengths(self) -> None: + mode = black.FileMode.AUTO_DETECT with cache_dir() as workspace: path = (workspace / "file.py").resolve() path.touch() - black.write_cache({}, [path], 1) - one = black.read_cache(1) + black.write_cache({}, [path], 1, mode) + one = black.read_cache(1, mode) self.assertIn(path, one) - two = black.read_cache(2) + two = black.read_cache(2, mode) self.assertNotIn(path, two) + def test_single_file_force_pyi(self) -> None: + reg_mode = black.FileMode.AUTO_DETECT + pyi_mode = black.FileMode.PYI + contents, expected = read_data("force_pyi") + with cache_dir() as workspace: + path = (workspace / "file.py").resolve() + with open(path, "w") as fh: + fh.write(contents) + result = CliRunner().invoke(black.main, [str(path), "--pyi"]) + self.assertEqual(result.exit_code, 0) + with open(path, "r") as fh: + actual = fh.read() + # verify cache with --pyi is separate + pyi_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, pyi_mode) + self.assertIn(path, pyi_cache) + normal_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, reg_mode) + self.assertNotIn(path, normal_cache) + self.assertEqual(actual, expected) + + @event_loop(close=False) + def test_multi_file_force_pyi(self) -> None: + reg_mode = black.FileMode.AUTO_DETECT + pyi_mode = black.FileMode.PYI + contents, expected = read_data("force_pyi") + with cache_dir() as workspace: + paths = [ + (workspace / "file1.py").resolve(), + (workspace / "file2.py").resolve(), + ] + for path in paths: + with open(path, "w") as fh: + fh.write(contents) + result = CliRunner().invoke(black.main, [str(p) for p in paths] + ["--pyi"]) + self.assertEqual(result.exit_code, 0) + for path in paths: + with open(path, "r") as fh: + actual = fh.read() + self.assertEqual(actual, expected) + # verify cache with --pyi is separate + pyi_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, pyi_mode) + normal_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, reg_mode) + for path in paths: + self.assertIn(path, pyi_cache) + self.assertNotIn(path, normal_cache) + + def test_pipe_force_pyi(self) -> None: + source, expected = read_data("force_pyi") + result = CliRunner().invoke(black.main, ["-", "-q", "--pyi"], input=source) + self.assertEqual(result.exit_code, 0) + actual = result.output + self.assertFormatEqual(actual, expected) + + def test_single_file_force_py36(self) -> None: + reg_mode = black.FileMode.AUTO_DETECT + py36_mode = black.FileMode.PYTHON36 + source, expected = read_data("force_py36") + with cache_dir() as workspace: + path = (workspace / "file.py").resolve() + with open(path, "w") as fh: + fh.write(source) + result = CliRunner().invoke(black.main, [str(path), "--py36"]) + self.assertEqual(result.exit_code, 0) + with open(path, "r") as fh: + actual = fh.read() + # verify cache with --py36 is separate + py36_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, py36_mode) + self.assertIn(path, py36_cache) + normal_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, reg_mode) + self.assertNotIn(path, normal_cache) + self.assertEqual(actual, expected) + + @event_loop(close=False) + def test_multi_file_force_py36(self) -> None: + reg_mode = black.FileMode.AUTO_DETECT + py36_mode = black.FileMode.PYTHON36 + source, expected = read_data("force_py36") + with cache_dir() as workspace: + paths = [ + (workspace / "file1.py").resolve(), + (workspace / "file2.py").resolve(), + ] + for path in paths: + with open(path, "w") as fh: + fh.write(source) + result = CliRunner().invoke( + black.main, [str(p) for p in paths] + ["--py36"] + ) + self.assertEqual(result.exit_code, 0) + for path in paths: + with open(path, "r") as fh: + actual = fh.read() + self.assertEqual(actual, expected) + # verify cache with --py36 is separate + pyi_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, py36_mode) + normal_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, reg_mode) + for path in paths: + self.assertIn(path, pyi_cache) + self.assertNotIn(path, normal_cache) + + def test_pipe_force_py36(self) -> None: + source, expected = read_data("force_py36") + result = CliRunner().invoke(black.main, ["-", "-q", "--py36"], input=source) + self.assertEqual(result.exit_code, 0) + actual = result.output + self.assertFormatEqual(actual, expected) + if __name__ == "__main__": unittest.main()