import os
import sys
import pytest
from devtools.pytest_plugin import load_black
pytestmark = pytest.mark.skipif(sys.version_info < (3, 8), reason='requires Python 3.8+')
config = "pytest_plugins = ['devtools.pytest_plugin']"
# language=Python
default_test = """\
def test_ok():
assert 1 + 2 == 3
def test_string_assert(insert_assert):
thing = 'foobar'
insert_assert(thing)\
"""
def test_insert_assert(pytester_pretty):
os.environ.pop('CI', None)
pytester_pretty.makeconftest(config)
test_file = pytester_pretty.makepyfile(default_test)
result = pytester_pretty.runpytest()
result.assert_outcomes(passed=2)
# print(result.outlines)
assert test_file.read_text() == (
'def test_ok():\n'
' assert 1 + 2 == 3\n'
'\n'
'def test_string_assert(insert_assert):\n'
" thing = 'foobar'\n"
' # insert_assert(thing)\n'
' assert thing == "foobar"'
)
def test_insert_assert_no_pretty(pytester):
os.environ.pop('CI', None)
pytester.makeconftest(config)
test_file = pytester.makepyfile(default_test)
result = pytester.runpytest('-p', 'no:pretty')
result.assert_outcomes(passed=2)
assert test_file.read_text() == (
'def test_ok():\n'
' assert 1 + 2 == 3\n'
'\n'
'def test_string_assert(insert_assert):\n'
" thing = 'foobar'\n"
' # insert_assert(thing)\n'
' assert thing == "foobar"'
)
def test_insert_assert_print(pytester_pretty, capsys):
os.environ.pop('CI', None)
pytester_pretty.makeconftest(config)
test_file = pytester_pretty.makepyfile(default_test)
# assert r == 0
result = pytester_pretty.runpytest('--insert-assert-print')
result.assert_outcomes(passed=2)
assert test_file.read_text() == default_test
captured = capsys.readouterr()
assert 'test_insert_assert_print.py - 6:' in captured.out
assert 'Printed 1 insert_assert() call in 1 file\n' in captured.out
def test_insert_assert_fail(pytester_pretty):
os.environ.pop('CI', None)
pytester_pretty.makeconftest(config)
test_file = pytester_pretty.makepyfile(default_test)
# assert r == 0
result = pytester_pretty.runpytest()
assert result.parseoutcomes() == {'passed': 2, 'warning': 1, 'insert': 1}
assert test_file.read_text() != default_test
def test_deep(pytester_pretty):
os.environ.pop('CI', None)
pytester_pretty.makeconftest(config)
# language=Python
test_file = pytester_pretty.makepyfile(
"""
def test_deep(insert_assert):
insert_assert([{'a': i, 'b': 2 * 2} for i in range(3)])
"""
)
result = pytester_pretty.runpytest()
result.assert_outcomes(passed=1)
assert test_file.read_text() == (
'def test_deep(insert_assert):\n'
" # insert_assert([{'a': i, 'b': 2 * 2} for i in range(3)])\n"
' assert [{"a": i, "b": 2 * 2} for i in range(3)] == [\n'
' {"a": 0, "b": 4},\n'
' {"a": 1, "b": 4},\n'
' {"a": 2, "b": 4},\n'
' ]'
)
def test_enum(pytester_pretty, capsys):
os.environ.pop('CI', None)
pytester_pretty.makeconftest(config)
# language=Python
pytester_pretty.makepyfile(
"""
from enum import Enum
class Foo(Enum):
A = 1
B = 2
def test_deep(insert_assert):
x = Foo.A
insert_assert(x)
"""
)
result = pytester_pretty.runpytest('--insert-assert-print')
result.assert_outcomes(passed=1)
captured = capsys.readouterr()
assert ' assert x == Foo.A\n' in captured.out
def test_insert_assert_black(tmp_path):
old_wd = os.getcwd()
try:
os.chdir(tmp_path)
(tmp_path / 'pyproject.toml').write_text(
"""\
[tool.black]
target-version = ["py39"]
skip-string-normalization = true"""
)
load_black.cache_clear()
finally:
os.chdir(old_wd)
f = load_black()
# no string normalization
assert f("'foobar'") == "'foobar'\n"
def test_insert_assert_repeat(pytester_pretty, capsys):
os.environ.pop('CI', None)
pytester_pretty.makeconftest(config)
test_file = pytester_pretty.makepyfile(
"""\
import pytest
@pytest.mark.parametrize('x', [1, 2, 3])
def test_string_assert(x, insert_assert):
insert_assert(x)\
"""
)
result = pytester_pretty.runpytest()
result.assert_outcomes(passed=3)
assert test_file.read_text() == (
'import pytest\n'
'\n'
"@pytest.mark.parametrize('x', [1, 2, 3])\n"
'def test_string_assert(x, insert_assert):\n'
' # insert_assert(x)\n'
' assert x == 1'
)
captured = capsys.readouterr()
assert '2 insert skipped because an assert statement on that line had already be inserted!\n' in captured.out