Skip to content

Commit 4070527

Browse files
authored
Switch to pytest and tox (#1763)
* Add venv to .gitignore * Use tox to run tests * Make fuzz run in tox * Split tests files * Fix import error
1 parent 3be0aa7 commit 4070527

File tree

8 files changed

+275
-233
lines changed

8 files changed

+275
-233
lines changed

.github/workflows/fuzz.yml

+2-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,8 @@ jobs:
2121
- name: Install dependencies
2222
run: |
2323
python -m pip install --upgrade pip
24-
python -m pip install --upgrade coverage
25-
python -m pip install --upgrade hypothesmith
26-
python -m pip install -e ".[d]"
24+
python -m pip install --upgrade tox
2725
2826
- name: Run fuzz tests
2927
run: |
30-
coverage run fuzz.py
31-
coverage report
28+
tox -e fuzz

.github/workflows/test.yml

+2-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@ jobs:
2222
- name: Install dependencies
2323
run: |
2424
python -m pip install --upgrade pip
25-
python -m pip install --upgrade coverage
26-
python -m pip install -e ".[d]"
25+
python -m pip install --upgrade tox
2726
2827
- name: Unit tests
2928
run: |
30-
coverage run -m unittest
29+
tox -e py

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ src/_black_version.py
1515
.dmypy.json
1616
*.swp
1717
.hypothesis/
18+
venv/

test_requirements.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pytest >= 6.0.1
2+
pytest-mock >= 3.2.0
3+
pytest-cases >= 2.1.2
4+
coverage >= 5.2.1

tests/test_black.py

+5-225
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
Dict,
2323
Generator,
2424
List,
25-
Tuple,
2625
Iterator,
2726
TypeVar,
2827
)
@@ -36,29 +35,17 @@
3635
import black
3736
from black import Feature, TargetVersion
3837

39-
try:
40-
import blackd
41-
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
42-
from aiohttp import web
43-
except ImportError:
44-
has_blackd_deps = False
45-
else:
46-
has_blackd_deps = True
47-
4838
from pathspec import PathSpec
4939

5040
# Import other test classes
41+
from tests.util import THIS_DIR, read_data, DETERMINISTIC_HEADER
5142
from .test_primer import PrimerCLITests # noqa: F401
5243

5344

5445
DEFAULT_MODE = black.FileMode(experimental_string_processing=True)
5546
ff = partial(black.format_file_in_place, mode=DEFAULT_MODE, fast=True)
5647
fs = partial(black.format_str, mode=DEFAULT_MODE)
5748
THIS_FILE = Path(__file__)
58-
THIS_DIR = THIS_FILE.parent
59-
PROJECT_ROOT = THIS_DIR.parent
60-
DETERMINISTIC_HEADER = "[Deterministic header]"
61-
EMPTY_LINE = "# EMPTY LINE WITH WHITESPACE" + " (this comment will be removed)"
6249
PY36_VERSIONS = {
6350
TargetVersion.PY36,
6451
TargetVersion.PY37,
@@ -74,29 +61,6 @@ def dump_to_stderr(*output: str) -> str:
7461
return "\n" + "\n".join(output) + "\n"
7562

7663

77-
def read_data(name: str, data: bool = True) -> Tuple[str, str]:
78-
"""read_data('test_name') -> 'input', 'output'"""
79-
if not name.endswith((".py", ".pyi", ".out", ".diff")):
80-
name += ".py"
81-
_input: List[str] = []
82-
_output: List[str] = []
83-
base_dir = THIS_DIR / "data" if data else PROJECT_ROOT
84-
with open(base_dir / name, "r", encoding="utf8") as test:
85-
lines = test.readlines()
86-
result = _input
87-
for line in lines:
88-
line = line.replace(EMPTY_LINE, "")
89-
if line.rstrip() == "# output":
90-
result = _output
91-
continue
92-
93-
result.append(line)
94-
if _input and not _output:
95-
# If there's no output marker, treat the entire file as already pre-formatted.
96-
_output = _input[:]
97-
return "".join(_input).strip() + "\n", "".join(_output).strip() + "\n"
98-
99-
10064
@contextmanager
10165
def cache_dir(exists: bool = True) -> Iterator[Path]:
10266
with TemporaryDirectory() as workspace:
@@ -119,17 +83,6 @@ def event_loop() -> Iterator[None]:
11983
loop.close()
12084

12185

122-
@contextmanager
123-
def skip_if_exception(e: str) -> Iterator[None]:
124-
try:
125-
yield
126-
except Exception as exc:
127-
if exc.__class__.__name__ == e:
128-
unittest.skip(f"Encountered expected exception {exc}, skipping")
129-
else:
130-
raise
131-
132-
13386
class FakeContext(click.Context):
13487
"""A fake click Context for when calling functions that need it."""
13588

@@ -239,9 +192,12 @@ def test_empty_ff(self) -> None:
239192
os.unlink(tmp_file)
240193
self.assertFormatEqual(expected, actual)
241194

242-
def test_self(self) -> None:
195+
def test_run_on_test_black(self) -> None:
243196
self.checkSourceFile("tests/test_black.py")
244197

198+
def test_run_on_test_blackd(self) -> None:
199+
self.checkSourceFile("tests/test_blackd.py")
200+
245201
def test_black(self) -> None:
246202
self.checkSourceFile("src/black/__init__.py")
247203

@@ -1969,14 +1925,6 @@ def fail(*args: Any, **kwargs: Any) -> None:
19691925
):
19701926
ff(THIS_FILE)
19711927

1972-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
1973-
def test_blackd_main(self) -> None:
1974-
with patch("blackd.web.run_app"):
1975-
result = CliRunner().invoke(blackd.main, [])
1976-
if result.exception is not None:
1977-
raise result.exception
1978-
self.assertEqual(result.exit_code, 0)
1979-
19801928
def test_invalid_config_return_code(self) -> None:
19811929
tmp_file = Path(black.dump_to_file())
19821930
try:
@@ -2053,174 +2001,6 @@ def test_bpo_33660_workaround(self) -> None:
20532001
os.chdir(str(old_cwd))
20542002

20552003

2056-
class BlackDTestCase(AioHTTPTestCase):
2057-
async def get_application(self) -> web.Application:
2058-
return blackd.make_app()
2059-
2060-
# TODO: remove these decorators once the below is released
2061-
# https://github.com/aio-libs/aiohttp/pull/3727
2062-
@skip_if_exception("ClientOSError")
2063-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2064-
@unittest_run_loop
2065-
async def test_blackd_request_needs_formatting(self) -> None:
2066-
response = await self.client.post("/", data=b"print('hello world')")
2067-
self.assertEqual(response.status, 200)
2068-
self.assertEqual(response.charset, "utf8")
2069-
self.assertEqual(await response.read(), b'print("hello world")\n')
2070-
2071-
@skip_if_exception("ClientOSError")
2072-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2073-
@unittest_run_loop
2074-
async def test_blackd_request_no_change(self) -> None:
2075-
response = await self.client.post("/", data=b'print("hello world")\n')
2076-
self.assertEqual(response.status, 204)
2077-
self.assertEqual(await response.read(), b"")
2078-
2079-
@skip_if_exception("ClientOSError")
2080-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2081-
@unittest_run_loop
2082-
async def test_blackd_request_syntax_error(self) -> None:
2083-
response = await self.client.post("/", data=b"what even ( is")
2084-
self.assertEqual(response.status, 400)
2085-
content = await response.text()
2086-
self.assertTrue(
2087-
content.startswith("Cannot parse"),
2088-
msg=f"Expected error to start with 'Cannot parse', got {repr(content)}",
2089-
)
2090-
2091-
@skip_if_exception("ClientOSError")
2092-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2093-
@unittest_run_loop
2094-
async def test_blackd_unsupported_version(self) -> None:
2095-
response = await self.client.post(
2096-
"/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "2"}
2097-
)
2098-
self.assertEqual(response.status, 501)
2099-
2100-
@skip_if_exception("ClientOSError")
2101-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2102-
@unittest_run_loop
2103-
async def test_blackd_supported_version(self) -> None:
2104-
response = await self.client.post(
2105-
"/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "1"}
2106-
)
2107-
self.assertEqual(response.status, 200)
2108-
2109-
@skip_if_exception("ClientOSError")
2110-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2111-
@unittest_run_loop
2112-
async def test_blackd_invalid_python_variant(self) -> None:
2113-
async def check(header_value: str, expected_status: int = 400) -> None:
2114-
response = await self.client.post(
2115-
"/", data=b"what", headers={blackd.PYTHON_VARIANT_HEADER: header_value}
2116-
)
2117-
self.assertEqual(response.status, expected_status)
2118-
2119-
await check("lol")
2120-
await check("ruby3.5")
2121-
await check("pyi3.6")
2122-
await check("py1.5")
2123-
await check("2.8")
2124-
await check("py2.8")
2125-
await check("3.0")
2126-
await check("pypy3.0")
2127-
await check("jython3.4")
2128-
2129-
@skip_if_exception("ClientOSError")
2130-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2131-
@unittest_run_loop
2132-
async def test_blackd_pyi(self) -> None:
2133-
source, expected = read_data("stub.pyi")
2134-
response = await self.client.post(
2135-
"/", data=source, headers={blackd.PYTHON_VARIANT_HEADER: "pyi"}
2136-
)
2137-
self.assertEqual(response.status, 200)
2138-
self.assertEqual(await response.text(), expected)
2139-
2140-
@skip_if_exception("ClientOSError")
2141-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2142-
@unittest_run_loop
2143-
async def test_blackd_diff(self) -> None:
2144-
diff_header = re.compile(
2145-
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"
2146-
)
2147-
2148-
source, _ = read_data("blackd_diff.py")
2149-
expected, _ = read_data("blackd_diff.diff")
2150-
2151-
response = await self.client.post(
2152-
"/", data=source, headers={blackd.DIFF_HEADER: "true"}
2153-
)
2154-
self.assertEqual(response.status, 200)
2155-
2156-
actual = await response.text()
2157-
actual = diff_header.sub(DETERMINISTIC_HEADER, actual)
2158-
self.assertEqual(actual, expected)
2159-
2160-
@skip_if_exception("ClientOSError")
2161-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2162-
@unittest_run_loop
2163-
async def test_blackd_python_variant(self) -> None:
2164-
code = (
2165-
"def f(\n"
2166-
" and_has_a_bunch_of,\n"
2167-
" very_long_arguments_too,\n"
2168-
" and_lots_of_them_as_well_lol,\n"
2169-
" **and_very_long_keyword_arguments\n"
2170-
"):\n"
2171-
" pass\n"
2172-
)
2173-
2174-
async def check(header_value: str, expected_status: int) -> None:
2175-
response = await self.client.post(
2176-
"/", data=code, headers={blackd.PYTHON_VARIANT_HEADER: header_value}
2177-
)
2178-
self.assertEqual(
2179-
response.status, expected_status, msg=await response.text()
2180-
)
2181-
2182-
await check("3.6", 200)
2183-
await check("py3.6", 200)
2184-
await check("3.6,3.7", 200)
2185-
await check("3.6,py3.7", 200)
2186-
await check("py36,py37", 200)
2187-
await check("36", 200)
2188-
await check("3.6.4", 200)
2189-
2190-
await check("2", 204)
2191-
await check("2.7", 204)
2192-
await check("py2.7", 204)
2193-
await check("3.4", 204)
2194-
await check("py3.4", 204)
2195-
await check("py34,py36", 204)
2196-
await check("34", 204)
2197-
2198-
@skip_if_exception("ClientOSError")
2199-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2200-
@unittest_run_loop
2201-
async def test_blackd_line_length(self) -> None:
2202-
response = await self.client.post(
2203-
"/", data=b'print("hello")\n', headers={blackd.LINE_LENGTH_HEADER: "7"}
2204-
)
2205-
self.assertEqual(response.status, 200)
2206-
2207-
@skip_if_exception("ClientOSError")
2208-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2209-
@unittest_run_loop
2210-
async def test_blackd_invalid_line_length(self) -> None:
2211-
response = await self.client.post(
2212-
"/", data=b'print("hello")\n', headers={blackd.LINE_LENGTH_HEADER: "NaN"}
2213-
)
2214-
self.assertEqual(response.status, 400)
2215-
2216-
@skip_if_exception("ClientOSError")
2217-
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
2218-
@unittest_run_loop
2219-
async def test_blackd_response_black_version_header(self) -> None:
2220-
response = await self.client.post("/")
2221-
self.assertIsNotNone(response.headers.get(blackd.BLACK_VERSION_HEADER))
2222-
2223-
22242004
with open(black.__file__, "r", encoding="utf-8") as _bf:
22252005
black_source_lines = _bf.readlines()
22262006

0 commit comments

Comments
 (0)