* deprecate py.magic.invoke/revoke in favour of
the new py.code.patch_builtins, py.code.unpatch_builtins * deprecate py.magic.patch/revert * deprecate py.magic.AssertionError in favour of py.code._AssertionError * introduced pytest_assertion plugin. --HG-- branch : trunk
This commit is contained in:
173
py/code/testing/test_assertion.py
Normal file
173
py/code/testing/test_assertion.py
Normal file
@@ -0,0 +1,173 @@
|
||||
import py
|
||||
from py.__.code.assertion import View
|
||||
|
||||
def setup_module(mod):
|
||||
py.code.patch_builtins(assertion=True, compile=False)
|
||||
|
||||
def teardown_module(mod):
|
||||
py.code.unpatch_builtins(assertion=True, compile=False)
|
||||
|
||||
def f():
|
||||
return 2
|
||||
|
||||
def test_assert():
|
||||
try:
|
||||
assert f() == 3
|
||||
except AssertionError, e:
|
||||
s = str(e)
|
||||
assert s.startswith('assert 2 == 3\n')
|
||||
|
||||
def test_assert_with_explicit_message():
|
||||
try:
|
||||
assert f() == 3, "hello"
|
||||
except AssertionError, e:
|
||||
assert e.msg == 'hello'
|
||||
|
||||
def test_assert_within_finally():
|
||||
class A:
|
||||
def f():
|
||||
pass
|
||||
excinfo = py.test.raises(TypeError, """
|
||||
try:
|
||||
A().f()
|
||||
finally:
|
||||
i = 42
|
||||
""")
|
||||
s = excinfo.exconly()
|
||||
assert s.find("takes no argument") != -1
|
||||
|
||||
#def g():
|
||||
# A.f()
|
||||
#excinfo = getexcinfo(TypeError, g)
|
||||
#msg = getmsg(excinfo)
|
||||
#assert msg.find("must be called with A") != -1
|
||||
|
||||
|
||||
def test_assert_multiline_1():
|
||||
try:
|
||||
assert (f() ==
|
||||
3)
|
||||
except AssertionError, e:
|
||||
s = str(e)
|
||||
assert s.startswith('assert 2 == 3\n')
|
||||
|
||||
def test_assert_multiline_2():
|
||||
try:
|
||||
assert (f() == (4,
|
||||
3)[-1])
|
||||
except AssertionError, e:
|
||||
s = str(e)
|
||||
assert s.startswith('assert 2 ==')
|
||||
|
||||
def test_assert_non_string_message():
|
||||
class A:
|
||||
def __str__(self):
|
||||
return "hello"
|
||||
try:
|
||||
assert 0 == 1, A()
|
||||
except AssertionError, e:
|
||||
assert e.msg == "hello"
|
||||
|
||||
|
||||
# These tests should both fail, but should fail nicely...
|
||||
class WeirdRepr:
|
||||
def __repr__(self):
|
||||
return '<WeirdRepr\nsecond line>'
|
||||
|
||||
def bug_test_assert_repr():
|
||||
v = WeirdRepr()
|
||||
try:
|
||||
assert v == 1
|
||||
except AssertionError, e:
|
||||
assert e.msg.find('WeirdRepr') != -1
|
||||
assert e.msg.find('second line') != -1
|
||||
assert 0
|
||||
|
||||
def test_assert_non_string():
|
||||
try:
|
||||
assert 0, ['list']
|
||||
except AssertionError, e:
|
||||
assert e.msg.find("list") != -1
|
||||
|
||||
def test_assert_implicit_multiline():
|
||||
try:
|
||||
x = [1,2,3]
|
||||
assert x != [1,
|
||||
2, 3]
|
||||
except AssertionError, e:
|
||||
assert e.msg.find('assert [1, 2, 3] !=') != -1
|
||||
|
||||
|
||||
def test_assert_with_brokenrepr_arg():
|
||||
class BrokenRepr:
|
||||
def __repr__(self): 0 / 0
|
||||
e = AssertionError(BrokenRepr())
|
||||
if e.msg.find("broken __repr__") == -1:
|
||||
py.test.fail("broken __repr__ not handle correctly")
|
||||
|
||||
|
||||
class TestView:
|
||||
def test_class_dispatch(self):
|
||||
### Use a custom class hierarchy with existing instances
|
||||
|
||||
class Picklable(View):
|
||||
pass
|
||||
|
||||
class Simple(Picklable):
|
||||
__view__ = object
|
||||
def pickle(self):
|
||||
return repr(self.__obj__)
|
||||
|
||||
class Seq(Picklable):
|
||||
__view__ = list, tuple, dict
|
||||
def pickle(self):
|
||||
return ';'.join(
|
||||
[Picklable(item).pickle() for item in self.__obj__])
|
||||
|
||||
class Dict(Seq):
|
||||
__view__ = dict
|
||||
def pickle(self):
|
||||
return Seq.pickle(self) + '!' + Seq(self.values()).pickle()
|
||||
|
||||
assert Picklable(123).pickle() == '123'
|
||||
assert Picklable([1,[2,3],4]).pickle() == '1;2;3;4'
|
||||
assert Picklable({1:2}).pickle() == '1!2'
|
||||
|
||||
def test_viewtype_class_hierarchy(self):
|
||||
# Use a custom class hierarchy based on attributes of existing instances
|
||||
class Operation:
|
||||
"Existing class that I don't want to change."
|
||||
def __init__(self, opname, *args):
|
||||
self.opname = opname
|
||||
self.args = args
|
||||
|
||||
existing = [Operation('+', 4, 5),
|
||||
Operation('getitem', '', 'join'),
|
||||
Operation('setattr', 'x', 'y', 3),
|
||||
Operation('-', 12, 1)]
|
||||
|
||||
class PyOp(View):
|
||||
def __viewkey__(self):
|
||||
return self.opname
|
||||
def generate(self):
|
||||
return '%s(%s)' % (self.opname, ', '.join(map(repr, self.args)))
|
||||
|
||||
class PyBinaryOp(PyOp):
|
||||
__view__ = ('+', '-', '*', '/')
|
||||
def generate(self):
|
||||
return '%s %s %s' % (self.args[0], self.opname, self.args[1])
|
||||
|
||||
codelines = [PyOp(op).generate() for op in existing]
|
||||
assert codelines == ["4 + 5", "getitem('', 'join')",
|
||||
"setattr('x', 'y', 3)", "12 - 1"]
|
||||
|
||||
def test_AssertionError(testdir):
|
||||
testdir.makepyfile("""
|
||||
import py
|
||||
def test_hello(recwarn):
|
||||
err = py.magic.AssertionError
|
||||
recwarn.pop(DeprecationWarning)
|
||||
assert err is py.code._AssertionError
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
assert "1 passed" in result.stdout.str()
|
||||
@@ -164,5 +164,18 @@ class TestSafeRepr:
|
||||
s = safe_repr(Function())
|
||||
except Exception, e:
|
||||
py.test.fail("saferepr failed for newstyle class")
|
||||
|
||||
|
||||
|
||||
def test_builtin_patch_unpatch(monkeypatch):
|
||||
import __builtin__ as cpy_builtin
|
||||
comp = cpy_builtin.compile
|
||||
def mycompile(*args, **kwargs):
|
||||
return comp(*args, **kwargs)
|
||||
monkeypatch.setattr(cpy_builtin, 'AssertionError', None)
|
||||
monkeypatch.setattr(cpy_builtin, 'compile', mycompile)
|
||||
py.code.patch_builtins()
|
||||
assert cpy_builtin.AssertionError
|
||||
assert cpy_builtin.compile != mycompile
|
||||
py.code.unpatch_builtins()
|
||||
assert cpy_builtin.AssertionError is None
|
||||
assert cpy_builtin.compile == mycompile
|
||||
|
||||
|
||||
@@ -577,11 +577,11 @@ raise ValueError()
|
||||
x = 1
|
||||
assert x == 2
|
||||
""")
|
||||
py.magic.invoke(assertion=True)
|
||||
py.code.patch_builtins(assertion=True)
|
||||
try:
|
||||
excinfo = py.test.raises(AssertionError, mod.somefunc)
|
||||
finally:
|
||||
py.magic.revoke(assertion=True)
|
||||
py.code.unpatch_builtins(assertion=True)
|
||||
|
||||
p = FormattedExcinfo()
|
||||
reprentry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
|
||||
64
py/code/testing/test_oldmagic.py
Normal file
64
py/code/testing/test_oldmagic.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import py
|
||||
|
||||
def check_assertion():
|
||||
excinfo = py.test.raises(AssertionError, "assert 1 == 2")
|
||||
s = excinfo.exconly(tryshort=True)
|
||||
if not s == "assert 1 == 2":
|
||||
raise ValueError("assertion not enabled: got %s" % s)
|
||||
|
||||
def test_invoke_assertion(recwarn, monkeypatch):
|
||||
monkeypatch.setattr(py.std.__builtin__, 'AssertionError', None)
|
||||
py.magic.invoke(assertion=True)
|
||||
try:
|
||||
check_assertion()
|
||||
finally:
|
||||
py.magic.revoke(assertion=True)
|
||||
recwarn.pop(DeprecationWarning)
|
||||
|
||||
def test_invoke_compile(recwarn, monkeypatch):
|
||||
monkeypatch.setattr(py.std.__builtin__, 'compile', None)
|
||||
py.magic.invoke(compile=True)
|
||||
try:
|
||||
co = compile("""if 1:
|
||||
def f():
|
||||
return 1
|
||||
\n""", '', 'exec')
|
||||
d = {}
|
||||
exec co in d
|
||||
assert py.code.Source(d['f'])
|
||||
finally:
|
||||
py.magic.revoke(compile=True)
|
||||
recwarn.pop(DeprecationWarning)
|
||||
|
||||
def test_patch_revert(recwarn):
|
||||
class a:
|
||||
pass
|
||||
py.test.raises(AttributeError, "py.magic.patch(a, 'i', 42)")
|
||||
|
||||
a.i = 42
|
||||
py.magic.patch(a, 'i', 23)
|
||||
assert a.i == 23
|
||||
recwarn.pop(DeprecationWarning)
|
||||
py.magic.revert(a, 'i')
|
||||
assert a.i == 42
|
||||
recwarn.pop(DeprecationWarning)
|
||||
|
||||
def test_double_patch(recwarn):
|
||||
class a:
|
||||
i = 42
|
||||
assert py.magic.patch(a, 'i', 2) == 42
|
||||
recwarn.pop(DeprecationWarning)
|
||||
assert py.magic.patch(a, 'i', 3) == 2
|
||||
assert a.i == 3
|
||||
assert py.magic.revert(a, 'i') == 3
|
||||
recwarn.pop(DeprecationWarning)
|
||||
assert a.i == 2
|
||||
assert py.magic.revert(a, 'i') == 2
|
||||
assert a.i == 42
|
||||
|
||||
def test_valueerror(recwarn):
|
||||
class a:
|
||||
i = 2
|
||||
pass
|
||||
py.test.raises(ValueError, "py.magic.revert(a, 'i')")
|
||||
recwarn.pop(DeprecationWarning)
|
||||
Reference in New Issue
Block a user