def test_setup(self) -> None: source, expected = read_data("../setup") actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll) self.assertFalse(ff(THIS_DIR / ".." / "setup.py"))
def test_self(self) -> None: source, expected = read_data("test_black") actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll) self.assertFalse(ff(THIS_FILE))
def check_file(self, filename: str, mode: black.Mode, kwargs: dict, *, data: bool = True) -> None: source, expected = read_data(filename, data=data) result: Result with TemporaryPathPlus() as tmp_pathplus: (tmp_pathplus / filename).write_text(source) toml_data = dom_toml.load( PathPlus(__file__).parent / "example_formate.toml") toml_data["hooks"]["black"]["kwargs"] = kwargs dom_toml.dump(toml_data, tmp_pathplus / "formate.toml") with in_directory(tmp_pathplus): runner = CliRunner(mix_stderr=False) result = runner.invoke( main, args=[ filename, "--no-colour", "--diff", "--verbose", "-v" ], ) # TODO: check stdout actual = (tmp_pathplus / filename).read_text() self.assertFormatEqual(expected, actual) if source != actual: black.assert_equivalent(source, actual) black.assert_stable(source, actual, mode)
def assert_format( source: str, expected: str, mode: black.Mode = DEFAULT_MODE, *, fast: bool = False, minimum_version: Optional[Tuple[int, int]] = None, ) -> None: """Convenience function to check that Black formats as expected. You can pass @minimum_version if you're passing code with newer syntax to guard safety guards so they don't just crash with a SyntaxError. Please note this is separate from TargetVerson Mode configuration. """ actual = black.format_str(source, mode=mode) _assert_format_equal(expected, actual) # It's not useful to run safety checks if we're expecting no changes anyway. The # assertion right above will raise if reality does actually make changes. This just # avoids wasted CPU cycles. if not fast and source != expected: # Unfortunately the AST equivalence check relies on the built-in ast module # being able to parse the code being formatted. This doesn't always work out # when checking modern code on older versions. if minimum_version is None or sys.version_info >= minimum_version: black.assert_equivalent(source, actual) black.assert_stable(source, actual, mode=mode)
def test_idempotent_any_syntatically_valid_python( src_contents: str, mode: black.FileMode) -> None: # Before starting, let's confirm that the input string is valid Python: compile(src_contents, "<string>", "exec") # else the bug is in hypothesmith # Then format the code... try: dst_contents = black.format_str(src_contents, mode=mode) except black.InvalidInput: # This is a bug - if it's valid Python code, as above, Black should be # able to cope with it. See issues #970, #1012, #1358, and #1557. # TODO: remove this try-except block when issues are resolved. return except TokenError as e: if ( # Special-case logic for backslashes followed by newlines or end-of-input e.args[0] == "EOF in multi-line statement" and re.search(r"\\($|\r?\n)", src_contents) is not None): # This is a bug - if it's valid Python code, as above, Black should be # able to cope with it. See issue #1012. # TODO: remove this block when the issue is resolved. return raise # And check that we got equivalent and stable output. black.assert_equivalent(src_contents, dst_contents) black.assert_stable(src_contents, dst_contents, mode=mode)
def check_file(self, filename: str, mode: black.Mode, *, data: bool = True) -> None: source, expected = read_data(filename, data=data) actual = fs(source, mode=mode) self.assertFormatEqual(expected, actual) if source != actual: black.assert_equivalent(source, actual) black.assert_stable(source, actual, mode)
def test_black(self) -> None: source, expected = read_data('../black') actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll) self.assertFalse(ff(THIS_DIR / '..' / 'black.py'))
def test_source_is_formatted(self, filename: str) -> None: path = THIS_DIR.parent / filename source, expected = read_data(str(path), data=False) actual = fs(source, mode=DEFAULT_MODE) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, DEFAULT_MODE) self.assertFalse(ff(path))
def test_setup(self) -> None: source, expected = read_data('../setup') actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll) with self.assertRaises(black.NothingChanged): ff(THIS_FILE)
def test_async_endpoint_module(template, mocker): path_param = mocker.MagicMock(python_name="path_param_1") path_param.name = "pathParam1" path_param.to_string.return_value = "path_param_1: str" query_param = mocker.MagicMock(template=None, python_name="query_param_1") query_param.name = "queryParam" query_param.to_string.return_value = "query_param_1: str" get_response = mocker.MagicMock(status_code=200) get_response.return_string.return_value = "str" get_response.constructor.return_value = "str(response.text)" get_endpoint = mocker.MagicMock( requires_security=False, path_parameters=[path_param], query_parameters=[query_param], form_body_reference=None, multipart_body_reference=None, json_body=None, responses=[get_response], description="GET endpoint", path="/get/{pathParam1}", method="get", ) get_endpoint.name = "PascalCase" form_body_reference = mocker.MagicMock(class_name="FormBody") multipart_body_reference = mocker.MagicMock(class_name="MultiPartBody") json_body = mocker.MagicMock(template=None, python_name="json_body") json_body.get_type_string.return_value = "Json" post_response_1 = mocker.MagicMock(status_code=200) post_response_1.return_string.return_value = "str" post_response_1.constructor.return_value = "str(response.text)" post_response_2 = mocker.MagicMock(status_code=201) post_response_2.return_string.return_value = "int" post_response_2.constructor.return_value = "int(response.text)" post_endpoint = mocker.MagicMock( name="camelCase", requires_security=True, path_parameters=[], query_parameters=[], form_body_reference=form_body_reference, multipart_body_reference=multipart_body_reference, json_body=json_body, responses=[post_response_1, post_response_2], description="POST endpoint", path="/post/", method="post", ) post_endpoint.name = "camelCase" collection = mocker.MagicMock( relative_imports=["import this", "from __future__ import braces"], endpoints=[get_endpoint, post_endpoint], ) result = template.render(collection=collection) import black expected = (Path(__file__).parent / "async_endpoint_module.py").read_text() black.assert_equivalent(result, expected)
def test_piping(self) -> None: source, expected = read_data("../black", data=False) stderrbuf = BytesIO() result = BlackRunner(stderrbuf).invoke( black.main, ["-", "--fast", f"--line-length={ll}"], input=source) self.assertEqual(result.exit_code, 0) self.assertFormatEqual(expected, result.output) black.assert_equivalent(source, result.output) black.assert_stable(source, result.output, line_length=ll)
def test_python39() -> None: source_path = (THIS_DIR / "data" / "python39.py").resolve() source, expected = read_data("python39") actual = black_hook(source, formate_filename=source_path) assert expected == actual major, minor = sys.version_info[:2] if major > 3 or (major == 3 and minor >= 9): black.assert_equivalent(source, actual) black.assert_stable(source, actual, DEFAULT_MODE)
def test_string_quotes(self) -> None: source, expected = read_data("string_quotes") actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll) mode = black.FileMode.NO_STRING_NORMALIZATION not_normalized = fs(source, mode=mode) self.assertFormatEqual(source, not_normalized) black.assert_equivalent(source, not_normalized) black.assert_stable(source, not_normalized, line_length=ll, mode=mode)
def verify_ast_unchanged( edited_to_file: TextDocument, reformatted: TextDocument, black_chunks: List[DiffChunk], edited_linenums: List[int], ) -> None: """Verify that source code parses to the same AST before and after reformat""" try: assert_equivalent(edited_to_file.string, reformatted.string) except AssertionError as exc_info: debug_dump(black_chunks, edited_to_file, reformatted, edited_linenums) raise NotEquivalentError(str(exc_info))
def verify_ast_unchanged( edited_to_file_str: str, reformatted_str: str, black_chunks: List[Tuple[int, List[str], List[str]]], edited_linenums: List[int], ) -> None: """Verify that source code parses to the same AST before and after reformat""" try: assert_equivalent(edited_to_file_str, reformatted_str) except AssertionError as exc_info: debug_dump(black_chunks, edited_to_file_str, reformatted_str, edited_linenums) raise NotEquivalentError(str(exc_info))
def test_expression_ff(self) -> None: source, expected = read_data("expression") tmp_file = Path(black.dump_to_file(source)) try: self.assertTrue(ff(tmp_file, write_back=black.WriteBack.YES)) with open(tmp_file, encoding="utf8") as f: actual = f.read() finally: os.unlink(tmp_file) self.assertFormatEqual(expected, actual) with patch("black.dump_to_file", dump_to_stderr): black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)
def test_async_module(template, mocker): path_param = mocker.MagicMock(python_name="path_param_1") path_param.name = "pathParam1" path_param.to_string.return_value = "path_param_1: str" query_param = mocker.MagicMock(template=None, python_name="query_param_1") query_param.name = "queryParam" query_param.to_string.return_value = "query_param_1: str" header_param = mocker.MagicMock(template=None, python_name="header_param_1") header_param.name = "headerParam" header_param.to_string.return_value = "header_param_1: str" form_body_reference = mocker.MagicMock(class_name="FormBody") multipart_body_reference = mocker.MagicMock(class_name="MultiPartBody") json_body = mocker.MagicMock(template=None, python_name="json_body") json_body.get_type_string.return_value = "Json" post_response_1 = mocker.MagicMock(status_code=200, source="response.json()", prop=mocker.MagicMock( template=None, python_name="response_one")) post_response_1.prop.get_type_string.return_value = "str" post_response_2 = mocker.MagicMock(status_code=201, source="response.json()", prop=mocker.MagicMock( template=None, python_name="response_one")) post_response_2.prop.get_type_string.return_value = "int" post_endpoint = mocker.MagicMock( name="camelCase", requires_security=True, path_parameters=[], query_parameters=[], form_body_reference=form_body_reference, multipart_body_reference=multipart_body_reference, json_body=json_body, responses=[post_response_1, post_response_2], description="POST endpoint", path="/post/", method="post", relative_imports=["import this", "from __future__ import braces"], ) post_endpoint.name = "camelCase" result = template.render(endpoint=post_endpoint) import black expected = (Path(__file__).parent / "endpoint_module.py").read_text() black.assert_equivalent(result, expected)
def test_piping(self) -> None: source, expected = read_data('../black') hold_stdin, hold_stdout = sys.stdin, sys.stdout try: sys.stdin, sys.stdout = StringIO(source), StringIO() sys.stdin.name = '<stdin>' black.format_stdin_to_stdout(line_length=ll, fast=True, write_back=True) sys.stdout.seek(0) actual = sys.stdout.read() finally: sys.stdin, sys.stdout = hold_stdin, hold_stdout self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)
def format_code(source, line_length): parts = [] for kind, src in chunks(source): if kind == "code": dst = black.format_str(src, line_length=79) black.assert_equivalent(src, dst) black.assert_stable(src, dst, line_length=line_length) parts.append(dst) else: parts.append(src) return "\n".join(parts)
def _black_roundtrip(path): import black with open(path, "r", encoding='utf8') as f: contents = f.read() output = _run_black(contents) again = _run_black(output) assert output == again, ("Black not idempotent on file %s" % path) # Now we decode both versions with the traditional codec and compare. orig_pyxl = pyxl_transform_string(contents, invertible=False) new_pyxl = pyxl_transform_string(output, invertible=False) black.assert_equivalent(orig_pyxl, new_pyxl)
def test_piping(self) -> None: source, expected = read_data("../black") hold_stdin, hold_stdout = sys.stdin, sys.stdout try: sys.stdin, sys.stdout = StringIO(source), StringIO() sys.stdin.name = "<stdin>" black.format_stdin_to_stdout( line_length=ll, fast=True, write_back=black.WriteBack.YES ) sys.stdout.seek(0) actual = sys.stdout.read() finally: sys.stdin, sys.stdout = hold_stdin, hold_stdout self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)
def test_piping(self) -> None: source, expected = read_data("../black") hold_stdin, hold_stdout = sys.stdin, sys.stdout try: sys.stdin = TextIOWrapper(BytesIO(source.encode("utf8")), encoding="utf8") sys.stdout = TextIOWrapper(BytesIO(), encoding="utf8") sys.stdin.buffer.name = "<stdin>" # type: ignore black.format_stdin_to_stdout(line_length=ll, fast=True, write_back=black.WriteBack.YES) sys.stdout.seek(0) actual = sys.stdout.read() finally: sys.stdin, sys.stdout = hold_stdin, hold_stdout self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)
def test_idempotent_any_syntatically_valid_python( src_contents: str, mode: black.FileMode ) -> None: # Before starting, let's confirm that the input string is valid Python: compile(src_contents, "<string>", "exec") # else the bug is in hypothesmith # Then format the code... try: dst_contents = black.format_str(src_contents, mode=mode) except black.InvalidInput: # This is a bug - if it's valid Python code, as above, Black should be # able to cope with it. See issues #970, #1012, #1358, and #1557. # TODO: remove this try-except block when issues are resolved. return # And check that we got equivalent and stable output. black.assert_equivalent(src_contents, dst_contents) black.assert_stable(src_contents, dst_contents, mode=mode)
def test_async_as_identifier() -> None: source_path = (THIS_DIR / "data" / "async_as_identifier.py").resolve() source, expected = read_data("async_as_identifier") actual = black_hook(source, formate_filename=source_path) assert expected == actual major, minor = sys.version_info[:2] if major < 3 or (major <= 3 and minor < 7): black.assert_equivalent(source, actual) black.assert_stable(source, actual, DEFAULT_MODE) # ensure black can parse this when the target is 3.6 black_hook(source, formate_filename=source_path, target_version="py36") # but not on 3.7, because async/await is no longer an identifier with pytest.raises(InvalidInput, match="Cannot parse: 1:4: def async()"): black_hook(source, formate_filename=source_path, target_version="py37")
def test_python37() -> None: source_path = (THIS_DIR / "data" / "python37.py").resolve() source, expected = read_data("python37") actual = black_hook(source, formate_filename=source_path) assert expected == actual major, minor = sys.version_info[:2] if major < 3 or (major <= 3 and minor < 7): black.assert_equivalent(source, actual) black.assert_stable(source, actual, DEFAULT_MODE) # ensure black can parse this when the target is 3.7 black_hook(source, formate_filename=source_path, target_version="py37") # but not on 3.6, because we use async as a reserved keyword with pytest.raises( InvalidInput, match=re.escape("Cannot parse: 26:18: return (await awaitable for awaitable in awaitable_list)"), ): black_hook(source, formate_filename=source_path, target_version="py36")
def _fmt(code: str) -> str: code = _(code) # NOTE (mb 2018-12-16): We're not testing arbitrary # formatting here, rather we're testing # _align_formatted_str specifically, which expects input # which has already been formatted by black.format_str. # Accordingly, the first thing we do is to check that the # test is valid code as would have been produced by # black.format_str. line_length = max(len(line) + 1 for line in code.splitlines()) mode = black.FileMode.NO_STRING_NORMALIZATION | black.FileMode.PYTHON36 blackend_code = black.format_str(code, line_length=line_length, mode=mode) assert blackend_code == code sjfmt.DEBUG_LVL = 0 try: sjfmt_out_code = sjfmt._align_formatted_str(code) finally: sjfmt.DEBUG_LVL = 0 black.assert_equivalent(code, sjfmt_out_code) return sjfmt_out_code
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)
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)
def test_fmtonoff(self) -> None: source, expected = read_data('fmtonoff') actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)
def test_import_spacing(self) -> None: source, expected = read_data('import_spacing') actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)
def assert_equivalent(src: str, dst: str) -> None: black.assert_equivalent(hide_magic(src), hide_magic(dst))
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_composition(self) -> None: source, expected = read_data("composition") actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)
def test_string_quotes(self) -> None: source, expected = read_data("string_quotes") actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)
def test_import_spacing(self) -> None: source, expected = read_data("import_spacing") actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)
def test_fmtonoff(self) -> None: source, expected = read_data("fmtonoff") actual = fs(source) self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, line_length=ll)