[py-svn] r51497 - in py/branch/event/py: . test2 test2/testing
hpk at codespeak.net
hpk at codespeak.net
Thu Feb 14 22:00:53 CET 2008
Author: hpk
Date: Thu Feb 14 22:00:50 2008
New Revision: 51497
Removed:
py/branch/event/py/test2/deprecate.py
py/branch/event/py/test2/raises.py
py/branch/event/py/test2/testing/test_deprecated.py
py/branch/event/py/test2/testing/test_itemgen.py
Modified:
py/branch/event/py/__init__.py
py/branch/event/py/test2/executor.py
py/branch/event/py/test2/item.py
py/branch/event/py/test2/outcome.py
py/branch/event/py/test2/present.py
py/branch/event/py/test2/session.py
py/branch/event/py/test2/testing/test_executor.py
py/branch/event/py/test2/testing/test_outcome.py
py/branch/event/py/test2/testing/test_present.py
py/branch/event/py/test2/testing/test_session.py
Log:
* refactor Presenter, add many tests
* make ItemTestReport events contain traceback info (at the
place where the exception happens)
* finally delete old SerializableOutcome code
* factor out most py.test helpers into outcome.py
Modified: py/branch/event/py/__init__.py
==============================================================================
--- py/branch/event/py/__init__.py (original)
+++ py/branch/event/py/__init__.py Thu Feb 14 22:00:50 2008
@@ -28,15 +28,15 @@
'test.__doc__' : ('./test/__init__.py', '__doc__'),
'test2.__doc__' : ('./test2/__init__.py', '__doc__'),
'test.raises' : ('./test/raises.py', 'raises'),
- 'test2.raises' : ('./test2/raises.py', 'raises'),
+ 'test2.raises' : ('./test2/outcome.py', 'raises'),
'test.deprecated_call' : ('./test/deprecate.py', 'deprecated_call'),
- 'test2.deprecated_call' : ('./test2/deprecate.py', 'deprecated_call'),
+ 'test2.deprecated_call' : ('./test2/outcome.py', 'deprecated_call'),
'test.skip' : ('./test/item.py', 'skip'),
- 'test2.skip' : ('./test2/item.py', 'skip'),
+ 'test2.skip' : ('./test2/outcome.py', 'skip'),
'test.fail' : ('./test/item.py', 'fail'),
- 'test2.fail' : ('./test2/item.py', 'fail'),
+ 'test2.fail' : ('./test2/outcome.py', 'fail'),
'test.exit' : ('./test/session.py', 'exit'),
- 'test2.exit' : ('./test2/session.py', 'exit'),
+ 'test2.exit' : ('./test2/outcome.py', 'exit'),
'test.pdb' : ('./test/custompdb.py', 'set_trace'),
'test2.pdb' : ('./test2/custompdb.py', 'set_trace'),
Deleted: /py/branch/event/py/test2/deprecate.py
==============================================================================
--- /py/branch/event/py/test2/deprecate.py Thu Feb 14 22:00:50 2008
+++ (empty file)
@@ -1,18 +0,0 @@
-import py
-
-def deprecated_call(func, *args, **kwargs):
- """ assert that calling func(*args, **kwargs)
- triggers a DeprecationWarning.
- """
- l = []
- oldwarn = py.std.warnings.warn_explicit
- def warn_explicit(*args, **kwargs):
- l.append(args)
- oldwarn(*args, **kwargs)
-
- py.magic.patch(py.std.warnings, 'warn_explicit', warn_explicit)
- try:
- _ = func(*args, **kwargs)
- finally:
- py.magic.revert(py.std.warnings, 'warn_explicit')
- assert l
Modified: py/branch/event/py/test2/executor.py
==============================================================================
--- py/branch/event/py/test2/executor.py (original)
+++ py/branch/event/py/test2/executor.py Thu Feb 14 22:00:50 2008
@@ -6,7 +6,7 @@
from py.__.test2.box import Box
from py.__.test2 import repevent
from py.__.test2.outcome import Skipped, Failed
-from py.__.test2 import repevent
+from py.__.test2 import repevent, present
import py.__.test2.custompdb
class RunExecutor(object):
@@ -26,32 +26,33 @@
else:
self.item.run()
+ def _fillreport(self, testrep, excinfo):
+ if excinfo.errisinstance(Skipped):
+ testrep.skipped = True
+ else:
+ testrep.failed = True
+ testrep.exconly = excinfo.exconly()
+ p = present.Presenter(self.config)
+ p.repr_failure(self.item, excinfo)
+ testrep.repr_failure = p.stringio.getvalue()
+
def execute(self, capture=True):
testrep = repevent.ItemTestReport(self.item._get_collector_trail())
- testrep._item = self.item
try:
try:
self.run(capture)
finally:
testrep.stdout, testrep.stderr = self.item._getouterr()
except Skipped:
- testrep.skipped = True
- testrep._excinfo = py.code.ExceptionInfo()
+ self._fillreport(testrep, py.code.ExceptionInfo())
except (SystemExit, KeyboardInterrupt):
raise
except:
- e = sys.exc_info()[1]
- if isinstance(e, Failed) and e.excinfo:
+ excinfo = py.code.ExceptionInfo()
+ if excinfo.errisinstance(Failed) and excinfo.value.excinfo:
excinfo = e.excinfo
- else:
- excinfo = py.code.ExceptionInfo()
- if isinstance(self.item, py.test2.collect.Function):
- fun = self.item.obj # hope this is stable
- code = py.code.Code(fun)
- excinfo.traceback = excinfo.traceback.cut(
- path=code.path, firstlineno=code.firstlineno)
- testrep._excinfo = excinfo
- testrep.failed = True
+ self.config.bus.notify(repevent.ItemFinish(self.item, excinfo))
+ self._fillreport(testrep, excinfo)
if self.config.option.usepdb:
py.__.test2.custompdb.post_mortem(excinfo._excinfo[2])
# XXX hmm, we probably will not like to continue from that
Modified: py/branch/event/py/test2/item.py
==============================================================================
--- py/branch/event/py/test2/item.py (original)
+++ py/branch/event/py/test2/item.py Thu Feb 14 22:00:50 2008
@@ -1,6 +1,5 @@
import py
-from inspect import isclass, ismodule
from py.__.test2 import outcome
from py.__.test2.collect import FunctionMixin
@@ -67,15 +66,3 @@
""" execute the given test function. """
target(*args)
-# whatever comes here....
-
-def skip(msg=""):
- """ skip with the given Message. """
- __tracebackhide__ = True
- raise outcome.Skipped(msg=msg)
-
-def fail(msg="unknown failure"):
- """ fail with the given Message. """
- __tracebackhide__ = True
- raise outcome.Failed(msg=msg)
-
Modified: py/branch/event/py/test2/outcome.py
==============================================================================
--- py/branch/event/py/test2/outcome.py (original)
+++ py/branch/event/py/test2/outcome.py Thu Feb 14 22:00:50 2008
@@ -1,9 +1,11 @@
-"""
- File defining possible outcomes of running and also
- serialization of outcomes
+"""
+ Test Outcomes and helpers for creating them.
+ py.test.skip|fail|raises helper implementations
+
"""
import py
+import sys
class Outcome:
def __init__(self, msg=None, excinfo=None):
@@ -31,126 +33,77 @@
class Skipped(Outcome):
pass
-# XXX
-# XXX
-# XXX the below is not used but needs some porting
-# XXX
-# XXX
-class SerializableOutcome(object):
- def __init__(self, setupfailure=False, excinfo=None, skipped=None,
- is_critical=False):
- self.passed = not excinfo and not skipped
- self.skipped = skipped
- self.setupfailure = setupfailure
- self.excinfo = excinfo
- self.is_critical = is_critical
- self.signal = 0
- self.stdout = "" # XXX temporary
- self.stderr = ""
- assert bool(self.passed) + bool(excinfo) + bool(skipped) == 1
-
- def make_excinfo_repr(self, excinfo, tbstyle):
- if excinfo is None or isinstance(excinfo, basestring):
- return excinfo
- tb_info = [self.traceback_entry_repr(x, tbstyle)
- for x in excinfo.traceback]
- rec_index = excinfo.traceback.recursionindex()
- if hasattr(excinfo, 'type'):
- etype = excinfo.type
- if hasattr(etype, '__name__'):
- etype = etype.__name__
- else:
- etype = excinfo.typename
- val = getattr(excinfo, 'value', None)
- if not val:
- val = excinfo.exconly()
- val = str(val)
- return (etype, val, (tb_info, rec_index))
-
- def traceback_entry_repr(self, tb_entry, tb_style):
- lineno = tb_entry.lineno
- relline = lineno - tb_entry.frame.code.firstlineno
- path = str(tb_entry.path)
- #try:
- try:
- if tb_style == 'long':
- source = str(tb_entry.getsource())
- else:
- source = str(tb_entry.getsource()).split("\n")[relline]
- except py.error.ENOENT:
- source = "[cannot get source]"
- name = str(tb_entry.frame.code.name)
- # XXX: Bare except. What can getsource() raise anyway?
- # SyntaxError, AttributeError, IndentationError for sure, check it
- #except:
- # source = "<could not get source>"
- return (relline, lineno, source, path, name)
-
- def make_repr(self, tbstyle="long"):
- return (self.passed, self.setupfailure,
- self.make_excinfo_repr(self.excinfo, tbstyle),
- self.make_excinfo_repr(self.skipped, tbstyle),
- self.is_critical, 0, self.stdout, self.stderr)
-
-class TracebackEntryRepr(object):
- def __init__(self, tbentry):
- relline, lineno, self.source, self.path, self.name = tbentry
- self.relline = int(relline)
- self.path = py.path.local(self.path)
- self.lineno = int(lineno)
- self.locals = {}
-
- def __repr__(self):
- return "line %s in %s\n %s" %(self.lineno, self.path, self.source[100:])
-
- def getsource(self):
- return py.code.Source(self.source).strip()
-
- def getfirstlinesource(self):
- return self.lineno - self.relline
+class Exit(Exception):
+ """ for immediate program exits without tracebacks and reporter/summary. """
+ def __init__(self, msg="unknown reason", item=None):
+ self.msg = msg
+ Exception.__init__(self, msg)
-class TracebackRepr(list):
- def recursionindex(self):
- return self.recursion_index
-
-class ExcInfoRepr(object):
- def __init__(self, excinfo):
- self.typename, self.value, tb_i = excinfo
- tb, rec_index = tb_i
- self.traceback = TracebackRepr([TracebackEntryRepr(x) for x in tb])
- self.traceback.recursion_index = rec_index
-
- def __repr__(self):
- l = ["%s=%s" %(x, getattr(self, x))
- for x in "typename value traceback".split()]
- return "<ExcInfoRepr %s>" %(" ".join(l),)
-
- def exconly(self, tryshort=False):
- """ Somehow crippled version of original one
- """
- return "%s: %s" % (self.typename, self.value)
-
- def errisinstance(self, exc_t):
- if not isinstance(exc_t, tuple):
- exc_t = (exc_t,)
- for exc in exc_t:
- if self.typename == str(exc).split('.')[-1]:
- return True
- return False
-
-class ReprOutcome(object):
- def __init__(self, repr_tuple):
- (self.passed, self.setupfailure, excinfo, skipped,
- self.is_critical, self.signal, self.stdout, self.stderr) = repr_tuple
- self.excinfo = self.unpack(excinfo)
- self.skipped = self.unpack(skipped)
-
- def unpack(self, what):
- if what is None or isinstance(what, basestring):
- return what
- return ExcInfoRepr(what)
+# exposed helper methods
- def __repr__(self):
- l = ["%s=%s" %(x, getattr(self, x))
- for x in "signal passed skipped setupfailure excinfo stdout stderr".split()]
- return "<ReprOutcome %s>" %(" ".join(l),)
+def exit(msg, item=None):
+ """ exit testing process immediately. """
+ raise Exit(msg=msg, item=item)
+
+def skip(msg=""):
+ """ skip with the given Message. """
+ __tracebackhide__ = True
+ raise Skipped(msg=msg)
+
+def fail(msg="unknown failure"):
+ """ fail with the given Message. """
+ __tracebackhide__ = True
+ raise Failed(msg=msg)
+
+def raises(ExpectedException, *args, **kwargs):
+ """ raise AssertionError, if target code does not raise the expected
+ exception.
+ """
+ assert args
+ __tracebackhide__ = True
+ if isinstance(args[0], str):
+ expr, = args
+ assert isinstance(expr, str)
+ frame = sys._getframe(1)
+ loc = frame.f_locals.copy()
+ loc.update(kwargs)
+ #print "raises frame scope: %r" % frame.f_locals
+ source = py.code.Source(expr)
+ try:
+ exec source.compile() in frame.f_globals, loc
+ #del __traceback__
+ # XXX didn'T mean f_globals == f_locals something special?
+ # this is destroyed here ...
+ except ExpectedException:
+ return py.code.ExceptionInfo()
+ else:
+ func = args[0]
+ assert callable
+ try:
+ func(*args[1:], **kwargs)
+ #del __traceback__
+ except ExpectedException:
+ return py.code.ExceptionInfo()
+ k = ", ".join(["%s=%r" % x for x in kwargs.items()])
+ if k:
+ k = ', ' + k
+ expr = '%s(%r%s)' %(func.__name__, args, k)
+ raise ExceptionFailure(msg="DID NOT RAISE",
+ expr=args, expected=ExpectedException)
+
+def deprecated_call(func, *args, **kwargs):
+ """ assert that calling func(*args, **kwargs)
+ triggers a DeprecationWarning.
+ """
+ l = []
+ oldwarn = py.std.warnings.warn_explicit
+ def warn_explicit(*args, **kwargs):
+ l.append(args)
+ oldwarn(*args, **kwargs)
+
+ py.magic.patch(py.std.warnings, 'warn_explicit', warn_explicit)
+ try:
+ _ = func(*args, **kwargs)
+ finally:
+ py.magic.revert(py.std.warnings, 'warn_explicit')
+ assert l
Modified: py/branch/event/py/test2/present.py
==============================================================================
--- py/branch/event/py/test2/present.py (original)
+++ py/branch/event/py/test2/present.py Thu Feb 14 22:00:50 2008
@@ -7,6 +7,7 @@
import py
from py.__.code import safe_repr
+from py.__.test2.terminal.out import getout
def getrelpath(source, dest):
base = source.common(dest)
@@ -45,12 +46,13 @@
""" Class used for presentation of various objects,
sharing common output style
"""
- def __init__(self, out, config):
- """ out is a file-like object (we can write to it)
- """
- assert hasattr(out, 'write')
- self.out = out
+ def __init__(self, config, out=None):
self.config = config
+ if out is None:
+ self.stringio = py.std.StringIO.StringIO()
+ out = getout(self.stringio)
+ assert hasattr(out, 'write'), out
+ self.out = out
def repr_source(self, source, marker=">", marker_location=-1):
""" This one represents piece of source with possible
@@ -72,11 +74,11 @@
prefix = " "
self.out.line(prefix + source[i])
- def repr_item_info(self, item):
+ def repr_failure_headline(self, item):
""" This method represents py.test2.collect.Item info (path and module)
"""
root = item.fspath
- modpath = item._getmodpath()
+ modpath = getmodpath(item)
try:
fn, lineno = item._getpathlineno()
except TypeError:
@@ -126,20 +128,42 @@
self.out.line("%-10s =\\" % (name,))
py.std.pprint.pprint(value, stream=self.out)
- def repr_failure_tblong(self, item, excinfo, traceback, out_err_reporter):
- if not self.config.option.nomagic and excinfo.errisinstance(RuntimeError):
+ def filtertraceback(self, item, traceback):
+ if item and not self.config.option.fulltrace:
+ path, firstlineno = item._getpathlineno()
+ ntraceback = traceback.cut(path=path, firstlineno=firstlineno)
+ if ntraceback == traceback:
+ ntraceback = ntraceback.cut(path=path)
+ traceback = ntraceback.filter()
+ return traceback
+
+ def repr_failure(self, item, excinfo):
+ traceback = self.filtertraceback(item, excinfo.traceback)
+ if excinfo.errisinstance(RuntimeError):
recursionindex = traceback.recursionindex()
else:
recursionindex = None
+
+ repr_tb = getattr(self, "repr_tb_" + self.config.option.tbstyle)
+ repr_tb(item, excinfo, traceback, recursionindex)
+
+ def repr_out_err(self, colitem):
+ for parent in colitem.listchain():
+ for name, obj in zip(['out', 'err'], parent._getouterr()):
+ if obj:
+ self.out.sep("- ", "%s: recorded std%s" % (parent.name, name))
+ self.out.line(obj)
+
+ def repr_tb_long(self, item, excinfo, traceback, recursionindex):
last = traceback[-1]
first = traceback[0]
for index, entry in py.builtin.enumerate(traceback):
if entry == first:
if item:
- self.repr_item_info(item)
+ self.repr_failure_headline(item)
self.out.line()
else:
- self.out.line("")
+ self.out.line()
source = self.getentrysource(entry)
firstsourceline = entry.getfirstlinesource()
marker_location = entry.lineno - firstsourceline
@@ -154,7 +178,7 @@
# trailing info
if entry == last:
- out_err_reporter()
+ self.repr_out_err(item)
self.out.sep("_")
else:
self.out.sep("_ ")
@@ -163,15 +187,9 @@
self.out.sep("!")
break
- def repr_failure_tbshort(self, item, excinfo, traceback, out_err_reporter):
- # print a Python-style short traceback
- if not self.config.option.nomagic and excinfo.errisinstance(RuntimeError):
- recursionindex = traceback.recursionindex()
- else:
- recursionindex = None
- last = traceback[-1]
- first = traceback[0]
+ def repr_tb_short(self, item, excinfo, traceback, recursionindex):
self.out.line()
+ last = traceback[-1]
for index, entry in py.builtin.enumerate(traceback):
path = entry.path.basename
firstsourceline = entry.getfirstlinesource()
@@ -199,7 +217,7 @@
# trailing info
if entry == last:
- out_err_reporter()
+ self.repr_out_err(item)
self.out.sep("_")
else:
if index == recursionindex:
@@ -208,5 +226,5 @@
break
# the following is only used by the combination '--pdb --tb=no'
- repr_failure_tbno = repr_failure_tbshort
+ repr_tb_no = repr_tb_short
Deleted: /py/branch/event/py/test2/raises.py
==============================================================================
--- /py/branch/event/py/test2/raises.py Thu Feb 14 22:00:50 2008
+++ (empty file)
@@ -1,39 +0,0 @@
-import sys
-import py
-from py.__.test2.outcome import ExceptionFailure
-
-def raises(ExpectedException, *args, **kwargs):
- """ raise AssertionError, if target code does not raise the expected
- exception.
- """
- assert args
- __tracebackhide__ = True
- if isinstance(args[0], str):
- expr, = args
- assert isinstance(expr, str)
- frame = sys._getframe(1)
- loc = frame.f_locals.copy()
- loc.update(kwargs)
- #print "raises frame scope: %r" % frame.f_locals
- source = py.code.Source(expr)
- try:
- exec source.compile() in frame.f_globals, loc
- #del __traceback__
- # XXX didn'T mean f_globals == f_locals something special?
- # this is destroyed here ...
- except ExpectedException:
- return py.code.ExceptionInfo()
- else:
- func = args[0]
- assert callable
- try:
- func(*args[1:], **kwargs)
- #del __traceback__
- except ExpectedException:
- return py.code.ExceptionInfo()
- k = ", ".join(["%s=%r" % x for x in kwargs.items()])
- if k:
- k = ', ' + k
- expr = '%s(%r%s)' %(func.__name__, args, k)
- raise ExceptionFailure(msg="DID NOT RAISE",
- expr=args, expected=ExpectedException)
Modified: py/branch/event/py/test2/session.py
==============================================================================
--- py/branch/event/py/test2/session.py (original)
+++ py/branch/event/py/test2/session.py Thu Feb 14 22:00:50 2008
@@ -8,7 +8,6 @@
import py
from py.__.test2.genitem import genitems
from py.__.test2 import repevent
-from py.__.test2.outcome import ReprOutcome
from py.__.test2.executor import RunExecutor, BoxExecutor
class Session(object):
@@ -88,22 +87,5 @@
cls = BoxExecutor
executor = cls(item, self.config)
testrep = executor.execute()
- excinfo = None
- if testrep.failed:
- # XXX excinfo
- try:
- raise ValueError
- except ValueError:
- excinfo = py.code.ExceptionInfo()
- self.config.bus.notify(repevent.ItemFinish(item, excinfo))
self.config.bus.notify(testrep)
-class Exit(Exception):
- """ for immediate program exits without tracebacks and reporter/summary. """
- def __init__(self, msg="unknown reason", item=None):
- self.msg = msg
- Exception.__init__(self, msg)
-
-def exit(msg, item=None):
- raise Exit(msg=msg, item=item)
-
Deleted: /py/branch/event/py/test2/testing/test_deprecated.py
==============================================================================
--- /py/branch/event/py/test2/testing/test_deprecated.py Thu Feb 14 22:00:50 2008
+++ (empty file)
@@ -1,35 +0,0 @@
-import py
-
-def dep(i):
- if i == 0:
- py.std.warnings.warn("is deprecated", DeprecationWarning)
-
-reg = {}
-def dep_explicit(i):
- if i == 0:
- py.std.warnings.warn_explicit("dep_explicit", category=DeprecationWarning,
- filename="hello", lineno=3)
-
-def test_deprecated_call_raises():
- py.test2.raises(AssertionError,
- "py.test2.deprecated_call(dep, 3)")
-
-def test_deprecated_call():
- py.test2.deprecated_call(dep, 0)
-
-def test_deprecated_call_preserves():
- r = py.std.warnings.onceregistry.copy()
- f = py.std.warnings.filters[:]
- test_deprecated_call_raises()
- test_deprecated_call()
- assert r == py.std.warnings.onceregistry
- assert f == py.std.warnings.filters
-
-def test_deprecated_explicit_call_raises():
- py.test2.raises(AssertionError,
- "py.test2.deprecated_call(dep_explicit, 3)")
-
-def test_deprecated_explicit_call():
- py.test2.deprecated_call(dep_explicit, 0)
- py.test2.deprecated_call(dep_explicit, 0)
-
Modified: py/branch/event/py/test2/testing/test_executor.py
==============================================================================
--- py/branch/event/py/test2/testing/test_executor.py (original)
+++ py/branch/event/py/test2/testing/test_executor.py Thu Feb 14 22:00:50 2008
@@ -1,11 +1,9 @@
import py
-from py.__.test2.executor import RunExecutor, BoxExecutor,\
- AsyncExecutor, ApigenExecutor
-from py.__.test2.outcome import ReprOutcome
+from py.__.test2.executor import RunExecutor, BoxExecutor
+from py.__.test2.executor import AsyncExecutor, ApigenExecutor
from py.__.test2.rsession.testing.basetest import BasicRsessionTest
-from py.__.test2.outcome import Failed
def setup_module(mod):
if py.std.sys.platform == "win32":
Deleted: /py/branch/event/py/test2/testing/test_itemgen.py
==============================================================================
--- /py/branch/event/py/test2/testing/test_itemgen.py Thu Feb 14 22:00:50 2008
+++ (empty file)
@@ -1,39 +0,0 @@
-
-import py
-from py.__.test2 import repevent
-
-class TestItemgen:
- def setup_class(cls):
- tmp = py.test.ensuretemp('itemgentest')
- tmp.ensure("__init__.py")
- tmp.ensure("test_one.py").write(py.code.Source("""
- def test_one():
- pass
-
- class TestX:
- def test_method_one(self):
- pass
-
- class TestY(TestX):
- pass
- """))
- tmp.ensure("test_two.py").write(py.code.Source("""
- import py
- py.test2.skip('xxx')
- """))
- tmp.ensure("test_three.py").write("xxxdsadsadsadsa")
- cls.tmp = tmp
-
- def test_itemgen(self):
- py.test.skip("itemgen test needs revamp but itemgen needs refactoring anyway")
- l = []
- colitems = [py.test2.collect.Directory(self.tmp)]
- gen = itemgen(None, colitems, l.append)
- items = [i for i in gen]
- assert len([i for i in l if isinstance(i, repevent.DeselectedTest)]) == 1
- assert len([i for i in l if isinstance(i, repevent.FailedTryiter)]) == 1
- assert len(items) == 3
- assert items[0].name == 'test_one'
- assert items[1].name == 'test_method_one'
- assert items[2].name == 'test_method_one'
-
Modified: py/branch/event/py/test2/testing/test_outcome.py
==============================================================================
--- py/branch/event/py/test2/testing/test_outcome.py (original)
+++ py/branch/event/py/test2/testing/test_outcome.py Thu Feb 14 22:00:50 2008
@@ -1,7 +1,5 @@
import py
-from py.__.test2.outcome import SerializableOutcome, ReprOutcome, ExcInfoRepr
-
import marshal
import py
@@ -21,31 +19,6 @@
def f4():
py.test.skip("argh!")
-def test_exception_info_repr():
- py.test.skip("exception infos need fixing")
- try:
- f3()
- except:
- outcome = SerializableOutcome(excinfo=py.code.ExceptionInfo())
-
- repr = outcome.make_excinfo_repr(outcome.excinfo, "long")
- assert marshal.dumps(repr)
- excinfo = ExcInfoRepr(repr)
-
- assert str(excinfo.typename) == "ValueError"
- assert str(excinfo.value) == "42"
- assert len(excinfo.traceback) == 4
- myfile = py.magic.autopath()
- assert excinfo.traceback[3].path == myfile
- assert excinfo.traceback[3].lineno == f1.func_code.co_firstlineno + 4
- assert excinfo.traceback[3].relline == 5
- assert excinfo.traceback[2].path == myfile
- assert excinfo.traceback[2].lineno == f2.func_code.co_firstlineno
- assert excinfo.traceback[2].relline == 1
- assert excinfo.traceback[1].path == myfile
- assert excinfo.traceback[1].lineno == f3.func_code.co_firstlineno
- assert excinfo.traceback[1].relline == 1
-
class TestRaises:
def test_raises(self):
py.test2.raises(ValueError, "int('qwe')")
@@ -59,3 +32,40 @@
def test_raises_function(self):
py.test2.raises(ValueError, int, 'hello')
+#
+# ============ test py.test.deprecated_call() ==============
+#
+
+def dep(i):
+ if i == 0:
+ py.std.warnings.warn("is deprecated", DeprecationWarning)
+
+reg = {}
+def dep_explicit(i):
+ if i == 0:
+ py.std.warnings.warn_explicit("dep_explicit", category=DeprecationWarning,
+ filename="hello", lineno=3)
+
+def test_deprecated_call_raises():
+ py.test2.raises(AssertionError,
+ "py.test2.deprecated_call(dep, 3)")
+
+def test_deprecated_call():
+ py.test2.deprecated_call(dep, 0)
+
+def test_deprecated_call_preserves():
+ r = py.std.warnings.onceregistry.copy()
+ f = py.std.warnings.filters[:]
+ test_deprecated_call_raises()
+ test_deprecated_call()
+ assert r == py.std.warnings.onceregistry
+ assert f == py.std.warnings.filters
+
+def test_deprecated_explicit_call_raises():
+ py.test2.raises(AssertionError,
+ "py.test2.deprecated_call(dep_explicit, 3)")
+
+def test_deprecated_explicit_call():
+ py.test2.deprecated_call(dep_explicit, 0)
+ py.test2.deprecated_call(dep_explicit, 0)
+
Modified: py/branch/event/py/test2/testing/test_present.py
==============================================================================
--- py/branch/event/py/test2/testing/test_present.py (original)
+++ py/branch/event/py/test2/testing/test_present.py Thu Feb 14 22:00:50 2008
@@ -1,9 +1,8 @@
import py
from py.__.test2 import present, repevent
-from py.__.test2.terminal.out import getout
import suptest, setupdata
-import sys
+import re, sys
def test_getmodpath_cases():
tmpdir = py.test.ensuretemp("test_getmodpath_cases")
@@ -46,11 +45,24 @@
def getpresenter(self, cmdlinearg=""):
config = self.getconfig(cmdlinearg.split())
- stringio = py.std.StringIO.StringIO()
- out = getout(stringio)
- p = present.Presenter(out, config)
- p.stringio = stringio
- return p
+ return present.Presenter(config)
+
+ def getfailing(self, source):
+ tfile = suptest.makeuniquepyfile(source)
+ sorter = suptest.events_from_cmdline([tfile])
+ # get failure base info
+ failevents = sorter.get(repevent.ItemFinish)
+ assert len(failevents) == 1
+ item = failevents[0].item
+ excinfo = failevents[0].excinfo
+ return item, excinfo
+
+ def gentest(self, check, **options):
+ print "using config options", options
+ p = self.getpresenter()
+ for name, value in options.items():
+ setattr(p.config.option, name, value)
+ check(p)
def test_repr_source(self):
source = py.code.Source("""
@@ -90,25 +102,57 @@
for key in loc.keys():
assert result.find(key) != -1
- def test_repr_traceback(self):
- tfile = suptest.makeuniquepyfile("""
+ def test_repr_failure_simple(self):
+ item, excinfo = self.getfailing("""
def test_one():
+ # failingsourcemarker
assert 42 == 43
- def f():
- assert 0
- def test_nested():
- f()
""")
- sorter = suptest.events_from_cmdline([tfile])
p = self.getpresenter()
-
- failevents = sorter.get(repevent.ItemFinish)
- assert len(failevents) == 2
- item = failevents[0].item
- py.test.skip("refactor Presenter.repr_failure_*")
- # errr... here we should
- # a) prepare an item
- # b) prepare excinfo
- # c) prepare some traceback info, with few different ideas,
- # like recursion detected etc.
- # test it...
+ p.repr_failure(item, excinfo)
+ s = p.stringio.getvalue()
+ print s
+ assert re.search("entrypoint:.*\.test_one", s)
+ assert s.find("# failingsourcemarker") != -1
+ assert re.search(r"E.*assert 42 == 43", s)
+ assert re.search(r">.*assert 42 == 43", s)
+
+ def test_repr_failure_recursive_funcs(self):
+ item, excinfo = self.getfailing("""
+ def rec2(x):
+ return rec1(x+1)
+ def rec1(x):
+ return rec2(x-1)
+ def test_one():
+ rec1(42)
+ """)
+ def check(p):
+ p.repr_failure(item, excinfo)
+ s = p.stringio.getvalue()
+ print s
+ assert re.search(".*return rec1.*x\+1", s)
+ assert re.search(".*return rec2.*x-1.*", s)
+ assert re.search("Recursion detected", s)
+
+ self.gentest(check, fulltrace=True)
+ self.gentest(check, fulltrace=False)
+ self.gentest(check, tbstyle='short')
+ self.gentest(check, showlocals=True)
+
+ def test_repr_failing_setup(self):
+ item, excinfo = self.getfailing("""
+ def setup_module(mod):
+ xyz
+ def test_one():
+ pass
+ """)
+ def check(p):
+ p.repr_failure(item, excinfo)
+ s = p.stringio.getvalue()
+ print s
+ assert re.search(">.*xyz", s)
+ assert re.search("NameError:.*xyz", s)
+
+ self.gentest(check, tbstyle="short")
+ self.gentest(check, fulltrace=True)
+ self.gentest(check, showlocals=True)
Modified: py/branch/event/py/test2/testing/test_session.py
==============================================================================
--- py/branch/event/py/test2/testing/test_session.py (original)
+++ py/branch/event/py/test2/testing/test_session.py Thu Feb 14 22:00:50 2008
@@ -179,9 +179,9 @@
sorter = suptest.events_run_example("brokenrepr.py")
passed, skipped, failed = sorter.listoutcomes()
assert len(failed) == 2
- out = failed[0].excinfo.exconly()
+ out = failed[0].exconly
assert out.find("""[Exception("Ha Ha fooled you, I'm a broken repr().") raised in repr()]""") != -1 #'
- out = failed[1].excinfo.exconly()
+ out = failed[1].exconly
assert out.find("[unknown exception raised in repr()]") != -1
def test_collect_only_with_various_situations(self):
@@ -249,9 +249,9 @@
assert len(skipped) == 0
assert len(passed) == 1
assert len(failed) == 3
- assert failed[0].item.name == "test_one_one"
- assert failed[1].item.name == "test_other"
- assert failed[2].item.name == "test_two"
+ assert failed[0].dottedpath(sorter.config).endswith("test_one_one")
+ assert failed[1].dottedpath(sorter.config).endswith("test_other")
+ assert failed[2].dottedpath(sorter.config).endswith("test_two")
def test_capture_info_on_event(self):
tfile = suptest.makeuniquepyfile("""
More information about the pytest-commit
mailing list