import re
import sys
import types
-import unittest
from concurrent.futures import ThreadPoolExecutor
from contextlib import contextmanager, redirect_stderr
from dataclasses import replace
)
def test_piping(self) -> None:
- source, expected = read_data_from_file(PROJECT_ROOT / "src/black/__init__.py")
+ _, source, expected = read_data_from_file(
+ PROJECT_ROOT / "src/black/__init__.py"
+ )
result = BlackRunner().invoke(
black.main,
[
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("simple_cases", "expression.py")
- expected, _ = read_data("simple_cases", "expression.diff")
+ source, _ = read_data("cases", "expression.py")
+ expected, _ = read_data("cases", "expression.diff")
args = [
"-",
"--fast",
self.assertEqual(expected, actual)
def test_piping_diff_with_color(self) -> None:
- source, _ = read_data("simple_cases", "expression.py")
+ source, _ = read_data("cases", "expression.py")
args = [
"-",
"--fast",
black.assert_stable(source, actual, black.FileMode())
def test_pep_572_version_detection(self) -> None:
- source, _ = read_data("py_38", "pep_572")
+ source, _ = read_data("cases", "pep_572")
root = black.lib2to3_parse(source)
features = black.get_features_used(root)
self.assertIn(black.Feature.ASSIGNMENT_EXPRESSIONS, features)
def test_pep_695_version_detection(self) -> None:
for file in ("type_aliases", "type_params"):
- source, _ = read_data("py_312", file)
+ source, _ = read_data("cases", file)
root = black.lib2to3_parse(source)
features = black.get_features_used(root)
self.assertIn(black.Feature.TYPE_PARAMS, features)
self.assertIn(black.TargetVersion.PY312, versions)
def test_expression_ff(self) -> None:
- source, expected = read_data("simple_cases", "expression.py")
+ source, expected = read_data("cases", "expression.py")
tmp_file = Path(black.dump_to_file(source))
try:
self.assertTrue(ff(tmp_file, write_back=black.WriteBack.YES))
black.assert_stable(source, actual, DEFAULT_MODE)
def test_expression_diff(self) -> None:
- source, _ = read_data("simple_cases", "expression.py")
- expected, _ = read_data("simple_cases", "expression.diff")
+ source, _ = read_data("cases", "expression.py")
+ expected, _ = read_data("cases", "expression.diff")
tmp_file = Path(black.dump_to_file(source))
diff_header = re.compile(
rf"{re.escape(str(tmp_file))}\t\d\d\d\d-\d\d-\d\d "
self.assertEqual(expected, actual, msg)
def test_expression_diff_with_color(self) -> None:
- source, _ = read_data("simple_cases", "expression.py")
- expected, _ = read_data("simple_cases", "expression.diff")
+ source, _ = read_data("cases", "expression.py")
+ expected, _ = read_data("cases", "expression.diff")
tmp_file = Path(black.dump_to_file(source))
try:
result = BlackRunner().invoke(
self.assertIn("\033[0m", actual)
def test_detect_pos_only_arguments(self) -> None:
- source, _ = read_data("py_38", "pep_570")
+ source, _ = read_data("cases", "pep_570")
root = black.lib2to3_parse(source)
features = black.get_features_used(root)
self.assertIn(black.Feature.POS_ONLY_ARGUMENTS, features)
self.assertEqual(test_file.read_bytes(), expected)
def test_skip_magic_trailing_comma(self) -> None:
- source, _ = read_data("simple_cases", "expression")
+ source, _ = read_data("cases", "expression")
expected, _ = read_data(
"miscellaneous", "expression_skip_magic_trailing_comma.diff"
)
@patch("black.dump_to_file", dump_to_stderr)
def test_async_as_identifier(self) -> None:
source_path = get_case_path("miscellaneous", "async_as_identifier")
- source, expected = read_data_from_file(source_path)
+ _, source, expected = read_data_from_file(source_path)
actual = fs(source)
self.assertFormatEqual(expected, actual)
major, minor = sys.version_info[:2]
@patch("black.dump_to_file", dump_to_stderr)
def test_python37(self) -> None:
- source_path = get_case_path("py_37", "python37")
- source, expected = read_data_from_file(source_path)
+ source_path = get_case_path("cases", "python37")
+ _, source, expected = read_data_from_file(source_path)
actual = fs(source)
self.assertFormatEqual(expected, actual)
major, minor = sys.version_info[:2]
self.assertEqual(black.get_features_used(node), {Feature.NUMERIC_UNDERSCORES})
node = black.lib2to3_parse("123456\n")
self.assertEqual(black.get_features_used(node), set())
- source, expected = read_data("simple_cases", "function")
+ source, expected = read_data("cases", "function")
node = black.lib2to3_parse(source)
expected_features = {
Feature.TRAILING_COMMA_IN_CALL,
self.assertEqual(black.get_features_used(node), expected_features)
node = black.lib2to3_parse(expected)
self.assertEqual(black.get_features_used(node), expected_features)
- source, expected = read_data("simple_cases", "expression")
+ source, expected = read_data("cases", "expression")
node = black.lib2to3_parse(source)
self.assertEqual(black.get_features_used(node), set())
node = black.lib2to3_parse(expected)
self.assertEqual(len(n.children), 1)
self.assertEqual(n.children[0].type, black.token.ENDMARKER)
+ @patch("tests.conftest.PRINT_FULL_TREE", True)
+ @patch("tests.conftest.PRINT_TREE_DIFF", False)
@pytest.mark.incompatible_with_mypyc
- @unittest.skipIf(os.environ.get("SKIP_AST_PRINT"), "user set SKIP_AST_PRINT")
- def test_assertFormatEqual(self) -> None:
+ def test_assertFormatEqual_print_full_tree(self) -> None:
out_lines = []
err_lines = []
self.assertIn("Actual tree:", out_str)
self.assertEqual("".join(err_lines), "")
+ @patch("tests.conftest.PRINT_FULL_TREE", False)
+ @patch("tests.conftest.PRINT_TREE_DIFF", True)
+ @pytest.mark.incompatible_with_mypyc
+ def test_assertFormatEqual_print_tree_diff(self) -> None:
+ out_lines = []
+ err_lines = []
+
+ def out(msg: str, **kwargs: Any) -> None:
+ out_lines.append(msg)
+
+ def err(msg: str, **kwargs: Any) -> None:
+ err_lines.append(msg)
+
+ with patch("black.output._out", out), patch("black.output._err", err):
+ with self.assertRaises(AssertionError):
+ self.assertFormatEqual("j = [1, 2, 3]\n", "j = [1, 2, 3,]\n")
+
+ out_str = "".join(out_lines)
+ self.assertIn("Tree Diff:", out_str)
+ self.assertIn("+ COMMA", out_str)
+ self.assertIn("+ ','", out_str)
+ self.assertEqual("".join(err_lines), "")
+
@event_loop()
@patch("concurrent.futures.ProcessPoolExecutor", MagicMock(side_effect=OSError))
def test_works_in_mono_process_only_environment(self) -> None:
src1 = get_case_path("miscellaneous", "string_quotes")
self.invokeBlack([str(src1), "--diff", "--check"], exit_code=1)
# Files which will not be reformatted.
- src2 = get_case_path("simple_cases", "composition")
+ src2 = get_case_path("cases", "composition")
self.invokeBlack([str(src2), "--diff", "--check"])
# Multi file command.
self.invokeBlack([str(src1), str(src2), "--diff", "--check"], exit_code=1)
report = MagicMock()
# Even with an existing file, since we are forcing stdin, black
# should output to stdout and not modify the file inplace
- p = THIS_DIR / "data" / "simple_cases" / "collections.py"
+ p = THIS_DIR / "data" / "cases" / "collections.py"
# Make sure is_file actually returns True
self.assertTrue(p.is_file())
path = Path(f"__BLACK_STDIN_FILENAME__{p}")
# If BLACK_CACHE_DIR is not set, use user_cache_dir
monkeypatch.delenv("BLACK_CACHE_DIR", raising=False)
with patch_user_cache_dir:
- assert get_cache_dir() == workspace1
+ assert get_cache_dir().parent == workspace1
# If it is set, use the path provided in the env var.
monkeypatch.setenv("BLACK_CACHE_DIR", str(workspace2))
- assert get_cache_dir() == workspace2
+ assert get_cache_dir().parent == workspace2
def test_cache_broken_file(self) -> None:
mode = DEFAULT_MODE
assert not cache.is_changed(one)
assert not cache.is_changed(two)
+ @pytest.mark.incompatible_with_mypyc
@pytest.mark.parametrize("color", [False, True], ids=["no-color", "with-color"])
def test_no_cache_when_writeback_diff(self, color: bool) -> None:
mode = DEFAULT_MODE
read_cache = black.Cache.read(mode)
assert not read_cache.is_changed(src)
+ @pytest.mark.incompatible_with_mypyc
def test_filter_cached(self) -> None:
with TemporaryDirectory() as workspace:
path = Path(workspace)
)
+class TestDeFactoAPI:
+ """Test that certain symbols that are commonly used externally keep working.
+
+ We don't (yet) formally expose an API (see issue #779), but we should endeavor to
+ keep certain functions that external users commonly rely on working.
+
+ """
+
+ def test_format_str(self) -> None:
+ # format_str and Mode should keep working
+ assert (
+ black.format_str("print('hello')", mode=black.Mode()) == 'print("hello")\n'
+ )
+
+ # you can pass line length
+ assert (
+ black.format_str("print('hello')", mode=black.Mode(line_length=42))
+ == 'print("hello")\n'
+ )
+
+ # invalid input raises InvalidInput
+ with pytest.raises(black.InvalidInput):
+ black.format_str("syntax error", mode=black.Mode())
+
+ def test_format_file_contents(self) -> None:
+ # You probably should be using format_str() instead, but let's keep
+ # this one around since people do use it
+ assert (
+ black.format_file_contents("x=1", fast=True, mode=black.Mode()) == "x = 1\n"
+ )
+
+ with pytest.raises(black.NothingChanged):
+ black.format_file_contents("x = 1\n", fast=True, mode=black.Mode())
+
+
try:
with open(black.__file__, "r", encoding="utf-8") as _bf:
black_source_lines = _bf.readlines()