[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