[py-svn] r8784 - in py/branch/py-collect: . execnet test2 test2/testing test2/testing/test/data

hpk at codespeak.net hpk at codespeak.net
Tue Feb 1 14:06:59 CET 2005


Author: hpk
Date: Tue Feb  1 14:06:58 2005
New Revision: 8784

Added:
   py/branch/py-collect/
      - copied from r8742, py/dist/py/
   py/branch/py-collect/test2/
      - copied from r8742, py/dist/py/test/
   py/branch/py-collect/test2/testing/test/data/filetest.py   (contents, props changed)
Modified:
   py/branch/py-collect/__init__.py
   py/branch/py-collect/conftest.py
   py/branch/py-collect/execnet/gateway.py
   py/branch/py-collect/test2/collect.py
   py/branch/py-collect/test2/defaultconfig.py
   py/branch/py-collect/test2/item.py
   py/branch/py-collect/test2/testing/test/data/disabled.py
   py/branch/py-collect/test2/testing/test_collect.py
Log:
open the collect refactoring branch.  The goal of this 
refactoring is to cleanup the collecting process and making
it saner/actually work in session or other distributed modes.  
Also doctests should be integrated at the collection level 
(this will be experimental).  Some of the ideas motivating
this branch have been discussed on the "py.test broken" thread 
on py-dev. 



Modified: py/branch/py-collect/__init__.py
==============================================================================
--- py/dist/py/__init__.py	(original)
+++ py/branch/py-collect/__init__.py	Tue Feb  1 14:06:58 2005
@@ -21,6 +21,25 @@
     'test.GenItem'           : ('./test/item.py', 'GenItem'),
     'test.Driver'            : ('./test/drive.py', 'Driver'),
 
+    'test2.skip'              : ('./test2/item.py', 'skip'),
+    'test2.skip_on_error'     : ('./test2/item.py', 'skip_on_error'),
+    'test2.raises'            : ('./test2/raises.py', 'raises'),
+    'test2.fail'              : ('./test2/item.py', 'fail'),
+    'test2.exit'              : ('./test2/drive.py', 'exit'),
+    'test2.config'            : ('./test2/config.py', 'config'),
+    'test2.compat.TestCase'   : ('./test2/compat.py', 'TestCase'),
+    'test2.collect.Directory' : ('./test2/collect.py', 'Directory'),
+    'test2.collect.Module'    : ('./test2/collect.py', 'Module'),
+    'test2.collect.Class'     : ('./test2/collect.py', 'Class'),
+    'test2.collect.Generator' : ('./test2/collect.py', 'Generator'),
+    'test2.TextReporter'      : ('./test2/report/text/reporter.py',
+                                'TextReporter'),
+    'test2.Option'            : ('./test2/tool/optparse.py', 'Option'),
+    'test2.MemoReporter'      : ('./test2/report/memo.py', 'MemoReporter'),
+    'test2.Item'              : ('./test2/item.py', 'Item'),
+    'test2.GenItem'           : ('./test2/item.py', 'GenItem'),
+    'test2.Driver'            : ('./test2/drive.py', 'Driver'),
+
     'std'                    : ('./misc/std.py', 'std'),
 
     'process.cmdexec'        : ('./process/cmdexec.py', 'cmdexec'),

Modified: py/branch/py-collect/conftest.py
==============================================================================
--- py/dist/py/conftest.py	(original)
+++ py/branch/py-collect/conftest.py	Tue Feb  1 14:06:58 2005
@@ -7,9 +7,6 @@
 #    mod.module = 23
 #    directory = pypath.root.dirpath()
 
-import py
-rootdir = py.magic.autopath().dirpath().dirpath()
-
 # default values for options (modified from cmdline)
 verbose = 0
 nocapture = False

Modified: py/branch/py-collect/execnet/gateway.py
==============================================================================
--- py/dist/py/execnet/gateway.py	(original)
+++ py/branch/py-collect/execnet/gateway.py	Tue Feb  1 14:06:58 2005
@@ -190,7 +190,7 @@
                     loc = { 'channel' : channel }
                     self.trace("execution starts:", repr(source)[:50])
                     try:
-                        co = compile(source+'\n', '', 'exec')
+                        co = compile(source+'\n', '', 'exec', 4096)
                         exec co in loc
                     finally:
                         self.trace("execution finished:", repr(source)[:50])

Modified: py/branch/py-collect/test2/collect.py
==============================================================================
--- py/dist/py/test/collect.py	(original)
+++ py/branch/py-collect/test2/collect.py	Tue Feb  1 14:06:58 2005
@@ -1,206 +1,242 @@
-from __future__ import generators
-
-import sys, inspect, types
-from py import path, test
 import py
+isclass = py.std.inspect.isclass 
 
-def getfscollector(fspath):
-    if fspath.check(file=1):
-        col = py.test.config.getconfigvalue(fspath, 'Module')
-    elif fspath.check(dir=1):
-        col = py.test.config.getconfigvalue(fspath, 'Directory')
-    else:
-        raise py.error.ENOENT(fspath)
-    return col(fspath)
+"""
+The is the tree of collectors.  Items are the leaves 
+that really get executed as tests. 
+
+    Directory
+        Module 
+            Class 
+                Instance  # empty setup/teardown 
+                    Function  
+                        Item 
+                    Generator 
+                        GenItem 
+            Function 
+                Item 
+            Generator 
+                GenItem 
+""" 
 
 def configproperty(name):
     def fget(self):
-        return py.test.config.getconfigvalue(self.fspath, name)
+        print "retrieving %r property from %s" %(name, self.fspath)
+        return py.test2.config.getconfigvalue(self.fspath, name)
     return property(fget)
 
-class Error(object):
-    """ represents a non-fatal exception while collecting. """
-    def __init__(self, excinfo):
-        self.excinfo = py.code.ExceptionInfo(excinfo)
-
-    def __repr__(self):
-        tb = list(self.excinfo)[-1]
-        return '<collect.Error in %r, line %d>' % (tb.frame.code.path,
-                                                   tb.lineno+1)
-
-class Collector(object):
-    """ instances are *restartable iterators*. They will yield Units or
-        Collector instances during iteration.
-    """
-    Item = test.Item
-    GenItem = test.GenItem
-    Error = Error
+def getfscollector(fspath):
+    return Directory(fspath.dirpath()).join(fspath.basename) 
+ 
+class Collector(object): 
+    def __init__(self, name, parent=None): 
+        self.name = name 
+        self.parent = parent 
+
+    Item = py.test2.Item
+    GenItem = py.test2.GenItem
     Module = configproperty('Module')
     Directory = configproperty('Directory')
     Class = configproperty('Class')
+    Generator = configproperty('Generator')
+
+    def setup(self, item): 
+        pass 
+
+    def teardown(self, item): 
+        pass 
 
-    def iterunits(self):
-        """ yield all units of the Collector instance. """
-        for x in self:
+    def iteritems(self):
+        """ yield all Items of a flattened Collector instance. """
+        for x in self.listdir(): 
             if isinstance(x, Collector):
-                for y in x.iterunits():
+                for y in x.iteritems():
                     yield y
             else:
                 yield x
 
-    def _except(self):
-        excinfo = sys.exc_info()
-        if isinstance(excinfo[1], (KeyboardInterrupt, SystemExit)):
-            raise excinfo # KeyboardInterrupt
-        return Error(excinfo)
-
-# ----------------------------------------------
-# Collectors starting from a file system path
-# ----------------------------------------------
-
-class FSCollector(Collector):
-    def __init__(self, fspath):
-        self.fspath = py.path.local(fspath)
-    def __repr__(self):
-        return '%s(%r)' %(self.__class__.__name__,
-                          self.fspath.relto(py.path.local()))
-
-class Directory(FSCollector):
-    def fil(self, fspath):
-        return (fspath.check(file=1, fnmatch='test_*.py') or
-                fspath.check(file=1, fnmatch='*_test.py'))
-    rec = py.path.checker(dir=1, dotfile=0, link=0)
-
-    def __iter__(self):
-        try:
-            for fspath in self.fspath.listdir(sort=True):
-                if self.rec(fspath):
-                    # hack to get the correct Directory collector class
-                    yield self.Directory(fspath).Directory(fspath)
-                elif self.fil(fspath):
-                    yield self.Module(fspath)
-        except:
-            yield self._except()
-
-# ----------------------------------------------
-# Collectors starting from Python Paths/Objects
-# ----------------------------------------------
-
-class PyCollector(Collector):
-    def __init__(self, extpy):
-        if not hasattr(extpy, 'resolve'):
-            extpy = py.path.extpy(extpy)
-        self.extpy = extpy
-        self.yielders = [getattr(self, x)
-                            for x in dir(self.__class__)
-                                if x.startswith('collect_')]
-
-    fspath = property(lambda self: self.extpy.root)
-
-    def __repr__(self):
-        return '%s(%r)' %(self.__class__.__name__, str(self.extpy))
-
-    def __iter__(self):
-        try:
-            # we want to sort according to lineno, so here goes
-            # the generator lazyness
-            l = []
-            for extpy in self.extpy.listdir():
-                for meth in self.yielders:
-                    #print "looking at", extpy
-                    for x in meth(extpy):
-                        #print "found", x
-                        sortvalue = self.getsortvalue(x)
-                        l.append((sortvalue, x))
-            l.sort()
-            for x,y in l:
-                yield y
-        except:
-            yield self._except()
-
-    def getsortvalue(self, obj):
-        """ sorting function to bring test methods in
-            the same order as int he file.
+    def fspath(): 
+        def fget(self): 
+            try: 
+                return self._fspath
+            except AttributeError: 
+                parent = self.parent 
+                while parent: 
+                    try: 
+                        self._fspath = parent.fspath 
+                    except AttributeError: 
+                        parent = parent.parent 
+                    else: 
+                        return self._fspath 
+        def fset(self, value): 
+            self._fspath = value 
+        return property(fget, fset, None, "containing filesystem path") 
+    fspath = fspath()
+
+class FSCollector(Collector): 
+    def __init__(self, fspath, parent=None): 
+        if isinstance(fspath, str): 
+            fspath = py.path.local(fspath)
+        self.fspath = fspath 
+        super(FSCollector, self).__init__(fspath.basename, parent) 
+
+class Directory(FSCollector): 
+    def filefilter(self, path): 
+        pb = path.purebasename 
+        return (path.check(fnmatch="*.py") and 
+               (pb.startswith('test_') or pb.endswith('_test')))
+    
+    def recfilter(self, path): 
+        return path.check(dotfile=0) 
+
+    def listdir(self): 
+        l = []
+        dirlist = self.fspath.listdir() 
+        for x in dirlist: 
+            if x.check(file=1) and self.filefilter(x): 
+                pass 
+            elif x.check(dir=1) and self.recfilter(x): 
+                pass 
+            else: 
+                continue 
+            l.append(self.join(x.basename)) 
+        return filter(None, l)
+
+    def join(self, name): 
+        x = self.fspath.join(name) 
+        if x.check(file=1): 
+            return self.Module(x, parent=self) 
+        elif x.check(dir=1): 
+            return self.Directory(x, parent=self) 
+
+    def __repr__(self): 
+        return "<collect.%s at %s" %(self.__class__.__name__, 
+                                     self.fspath)
+
+    # XXX setup/teardown directories? Use cases? 
+    def setup(self, item): 
+        pass 
+    def teardown(self, item): 
+        pass 
+
+class PyCollectorMixin(object): 
+    def funcnamefilter(self, name): 
+        return name.startswith('test_') 
+    def classnamefilter(self, name): 
+        return name.startswith('Test')
+
+    def __repr__(self): 
+        return "<collect.%s %r>" %(self.__class__.__name__, self.obj.__name__)
+
+    def obj(self): 
+        return getattr(self.parent.obj, self.name) 
+    obj = property(obj)
+
+    def listdir(self): 
+        l = []
+        if getattr(self.obj, 'disabled', 0):
+            return l 
+        for name in dir(self.obj): 
+            if self.funcnamefilter(name) or self.classnamefilter(name): 
+                x = self.join(name) 
+                if x: 
+                    l.append((x.sortvalue(), x))
+        l.sort() 
+        return [x[1] for x in l]
+
+    def join(self, name): 
+        obj = getattr(self.obj, name) 
+        if isclass(obj): 
+            return self.Class(name, parent=self)
+        elif callable(obj): 
+            if obj.func_code.co_flags & 32: # generator function 
+                return self.Generator(name, parent=self) 
+            else: 
+                return self.Function(name, parent=self) 
+
+    def sortvalue(self): 
+        """ sorting function helper to bring test methods in
+            the same order as in their file.
         """
-        if isinstance(obj, self.Item):
-            obj = obj.extpy.resolve()
-        elif isinstance(obj, PyCollector):
-            for x in obj:
-                return self.getsortvalue(x)
-        if hasattr(obj, 'im_func'):
-            obj = obj.im_func
-        if hasattr(obj, 'func_code'):
-            obj = obj.func_code
-        # enough is enough
-        return (getattr(obj, 'co_filename', None),
-                getattr(obj, 'co_firstlineno', sys.maxint))
-
-class Module(PyCollector):
-    def __iter__(self):
-        try:
-            iter = self.extpy.join('Collector')
-            if iter.check(exists=True):
-                iter = iter.resolve()(self.extpy)
-            else:
-                iter = super(Module, self).__iter__()
-            for x in iter:
-                yield x
-        except:
-            yield self._except()
-
-    def collect_function(self, extpy):
-        if extpy.check(func=1, basestarts='test_'):
-            if extpy.check(genfunc=1):
-                yield Generator(extpy)
-            else:
-                #if self.extpy.samefile(extpy): not nfs/different mountpoint safe ?
-                yield self.Item(extpy)
+        for x in self.listdir():
+            return x.sortvalue() 
 
-    def collect_class(self, extpy):
-        #print "checking %r (extpy: %r)" % (extpy.resolve(), extpy)
-        if extpy.check(basestarts='Test') and self.extpy.samefile(extpy):
-            obj = extpy.resolve()
-            if inspect.isclass(obj) and not getattr(obj, 'disabled', 0):
-                yield self.Class(extpy)
-
-class Class(PyCollector):
-    def collect_method(self, extpy):
-        # note that we want to allow inheritance and thus
-        # we don't check for "samemodule"-ness of test
-        # methods like in the Module Collector
-        if extpy.check(basestarts='test_', func=1):
-            if extpy.check(genfunc=1):
-                yield Generator(extpy)
-            else:
-                func = extpy.resolve()
-                try:
-                    yield getattr(func.im_class, 'Item')(extpy)
-                except AttributeError:
-                    yield self.Item(extpy)
+class Module(PyCollectorMixin, FSCollector): 
+    def obj(self): 
+        try: 
+            return self._obj    
+        except AttributeError:
+            self._obj = obj = self.fspath.getpymodule() 
+            return obj 
+    obj = property(obj, None, None, "module object")
+
+    def setup(self, item): 
+        item.setup_module(self.obj) 
+    def teardown(self, item): 
+        item.teardown_module(self.obj) 
+
+class Class(PyCollectorMixin, Collector): 
+
+    def listdir(self): 
+        return self.join("()") 
+
+    def join(self, name): 
+        assert name == '()' 
+        return self.Instance(name, self) 
+
+    def setup(self, item): 
+        item.setup_class(self.obj) 
+
+    def teardown(self, item): 
+        item.teardown_class(self.obj) 
+
+class Instance(PyCollectorMixin, Collector): 
+    def Item(self): 
+        return getattr(self.obj, 'Item', super(Class, self).Item) 
+    Item = property(Item)
+
+def makebound(x): 
+    assert callable(x) 
+    if hasattr(x, 'im_self') and x.im_self is None: 
+        return x.__get__(x.im_class(), x.im_class) 
+    return x 
+
+class Generator(Collector): 
+    def obj(self): 
+        return makebound(getattr(self.parent.obj, self.name))
+    obj = property(obj, None, None, "test generator function") 
+        
+    def listdir(self): 
+        l = []
+        for i, x in py.builtin.enumerate(self.obj()): 
+            name = "%s:%d" % (self.name, i) 
+            l.append(self.join(name)) 
+        return l
+
+    def join(self, name): 
+        myname, num = name.split(':')
+        if myname != self.name: 
+            raise NameError("name %r is foreign to %r" %(name,self))
+        num = int(num)
+        for i, x in py.builtin.enumerate(self.obj()): 
+            if i == num: 
+                if isinstance(x, (Collector, self.Item)): 
+                    return x 
+                call, args = self.getcallargs(x) 
+                return self.GenItem(name, self, call, args)
 
-class Generator(PyCollector):
-    def builditem(self, obj):
+    def getcallargs(self, obj):
         if isinstance(obj, (tuple, list)):
-            call = obj[0]
-            args = obj[1:]
+            call, args = obj[0], obj[1:]
         else:
-            call = obj
-            args = ()
-        #if hasattr(call, 'gi_running'):
-        #    return ... Generator(py.path.obj(call), *args)
-        return self.GenItem(self.extpy, call, *args)
-
-    def __iter__(self):
-        try:
-            # XXX we need to setup/teardown state here
-            #sm = self.GenItem.setupmanager
-            #sm.setup_path(self.extpy)
-            #gen, teardown = sm.setup_method(self.extpy)
-            #assert not teardown, "%r not processoable in Generator-Collector (XXX)"
-            gen = self.extpy.resolve()
-            if hasattr(gen, 'im_self')  and not gen.im_self:
-                gen = gen.__get__(gen.im_class(), gen.im_class)
-            for call in gen():
-                yield self.builditem(call)
-        except:
-            yield self._except()
+            call, args = obj, ()
+        assert callable(call) 
+        return call, args 
+
+    def sortvalue(self): 
+        obj = self.obj 
+        obj = getattr(obj, 'im_func', obj) 
+        obj = obj.func_code 
+        return (getattr(obj, 'co_filename', None), 
+                getattr(obj, 'co_firstlineno', py.std.sys.maxint))
+

Modified: py/branch/py-collect/test2/defaultconfig.py
==============================================================================
--- py/dist/py/test/defaultconfig.py	(original)
+++ py/branch/py-collect/test2/defaultconfig.py	Tue Feb  1 14:06:58 2005
@@ -1,9 +1,10 @@
 import py
-Option = py.test.Option
+Option = py.test2.Option
 
-Module = py.test.collect.Module
-Directory = py.test.collect.Directory
-Class = py.test.collect.Class
+Module = py.test2.collect.Module 
+Directory = py.test2.collect.Directory
+Class = py.test2.collect.Class
+Generator = py.test2.collect.Generator 
 
 def getreporter():
     return py.test.TextReporter()

Modified: py/branch/py-collect/test2/item.py
==============================================================================
--- py/dist/py/test/item.py	(original)
+++ py/branch/py-collect/test2/item.py	Tue Feb  1 14:06:58 2005
@@ -11,44 +11,29 @@
 class SetupItem(object):
     state = SetupState()
 
-    def teardownall(cls):
-        while cls.state._setupstack:
-            item, extpy, obj = cls.state._setupstack.pop()
-            item._dispatch_teardown(obj)
-    teardownall = classmethod(teardownall)
-
-    def _dispatch_teardown(self, obj):
-        if ismodule(obj):
-            self.teardown_module(obj)
-        elif isclass(obj):
-            self.teardown_class(obj)
-
-    def _dispatch_setup(self, obj):
-        if ismodule(obj):
-            self.setup_module(obj)
-        elif isclass(obj):
-            self.setup_class(obj)
-        else:
-            return False
-        return True
+    def teardown_all(cls): 
+        stack = self.state._setuptack
+        while stack: 
+            col, item = stack.pop() 
+            col.teardown(item) 
+    teardown_all = classmethod(teardown_all)
 
-    def setup_path(self, extpy):
+    def prepare(self): 
         """ setup objects along the path to the test-method
-            (pointed to by extpy). Tear down any previously
-            setup objects which are not directly needed.
+            Teardown any unneccessary previously setup objects. 
         """
-        # the setupstack contains (item, extpy, obj) tuples of already
-        # setup objects.  Strict ordering is maintained, i.e. each extpy in
-        # the stack is "relto" its previous extpy.
-        stack = self.state._setupstack
-        while stack and not extpy.relto(stack[-1][1]):
-            item, addr, obj = stack.pop()
-            item._dispatch_teardown(obj)
-        rest = extpy.parts()[len(stack):-1]
-        for x in rest:
-            obj = x.resolve()
-            if self._dispatch_setup(obj):
-                stack.append((self, x, obj))
+        needed_collectors = self.listcols() 
+        while stack: 
+            col, item = stack.pop() 
+            col.teardown(item) 
+            try: 
+                i = needed_collectors.index(col) 
+            except ValueError: 
+                continue 
+            else: 
+                for col in needed_collectors[i+1:]: 
+                    col.setup(item) 
+                    stack.append((col, item))
 
     def setup_module(self, mod):
         if hasattr(mod, 'setup_module'):
@@ -65,54 +50,52 @@
     def teardown_class(self, cls):
         if hasattr(cls, 'teardown_class'):
             cls.teardown_class.im_func(cls)
-
-    def setup_method(self, method):
-        if hasattr(getattr(method, 'im_self', None), 'setup_method'):
-            method.im_self.setup_method(method)
-
-    def teardown_method(self, method):
-        if hasattr(getattr(method, 'im_self', None), 'teardown_method'):
-            method.im_self.teardown_method(method)
-
-    def setup_function(self, function):
-        x = function.func_globals.get('setup_function', None)
-        if x is not None:
-            x(function)
-
-    def teardown_function(self, function):
-        x = function.func_globals.get('teardown_function', None)
-        if x is not None:
-            x(function)
-
-    def make_callable(self, method):
-        assert callable(method)
-        if not hasattr(method, 'im_class'):
-            return method
-        if self.state._instance.__class__ != method.im_class:
-            self.state._instance = method.im_class()
-        return method.__get__(self.state._instance, method.im_class)
+   
 
 class Item(SetupItem):
     """ an Item is responsible for locating and executing
         a Python callable test object.
     """
+    class Outcome:
+        def __init__(self, **kwargs):
+            assert 'msg' not in kwargs or isinstance(kwargs['msg'], str), (
+                "given 'msg' argument is not a string" )
+            self.__dict__.update(kwargs)
+        def __repr__(self):
+            return getattr(self, 'msg', object.__repr__(self))
+    class Passed(Outcome): pass
+    class Failed(Outcome): pass
+    class ExceptionFailure(Failed): msg = 'DID NOT RAISE'
+    class Skipped(Outcome): pass
 
-    def __init__(self, extpy, *args):
-        self.extpy = extpy
-        self.name = extpy.basename
+    def __init__(self, name, parent, args=()):
+        self.name = name 
+        self.parent = parent 
         self.args = args
 
-    def run(self, driver):
-        self.setup_path(self.extpy)
-        method = self.make_callable(self.extpy.resolve())
-        if hasattr(method, 'im_self'):
-            self.setup_method(method)
-        else:
-            self.setup_function(method)
-        try:
-            self.execute(method, *self.args)
-        finally:
-            self.teardown_method(method)
+    def __repr__(self): 
+        return "<%s %r>" %(self.__class__.__name__, self.name)
+
+    def obj(self): 
+        try: 
+            return self._obj   
+        except AttributeError: 
+            self._obj = obj = getattr(self.parent.obj, self.name) 
+            return obj 
+    obj = property(obj, None, None, "underlying callable") 
+          
+    def sortvalue(self):  
+        obj = self.obj 
+        if hasattr(obj, 'im_func'):
+            obj = obj.im_func
+        if hasattr(obj, 'func_code'):
+            obj = obj.func_code
+        return (getattr(obj, 'co_filename', None), 
+                getattr(obj, 'co_firstlineno', py.std.sys.maxint))
+
+    def run(self):
+        self.prepare() 
+        self.execute(self.obj, *self.args)
 
     def execute(self, target, *args):
         """ default implementation for calling a test target is to
@@ -126,34 +109,25 @@
         """
         return "%s%r" % (self.extpy.modpath, self.args)
 
-    class Outcome:
-        def __init__(self, **kwargs):
-            assert 'msg' not in kwargs or isinstance(kwargs['msg'], str), (
-                "given 'msg' argument is not a string" )
-            self.__dict__.update(kwargs)
-        def __repr__(self):
-            return getattr(self, 'msg', object.__repr__(self))
-    class Passed(Outcome): pass
-    class Failed(Outcome): pass
-    class ExceptionFailure(Failed): msg = 'DID NOT RAISE'
-    class Skipped(Outcome): pass
+class Function(Item): 
+    def setup(self, item): 
+        item.setup_function(self.obj) 
 
-class GenItem(Item):
-    def __init__(self, extpy, call, *args):
-        assert callable(call), "generated test %r is not callable" % (call,)
-        super(GenItem, self).__init__(extpy, *args)
-        self.call = call
+    def teardown(self, item): 
+        item.teardown_function(self.obj) 
 
-    def execute(self, target, *args):
-        #print "calling %r%r" %(self.call, args)
-        return self.call(*args)
+    def setup_function(self, function):
+        if hasattr(self.obj, 'setup_function'): 
+            self.obj.setup_function(self.obj) 
 
-    def reprcall(self):
-        """ return a string representing a call to the underlying
-            generated test function.
-        """
-        name = getattr(self.call, '__name__', self.call)
-        return "%s -> %s%r" % (self.extpy.modpath, name, self.args)
+    def teardown_function(self, function):
+        if hasattr(self.obj, 'teardown_function'): 
+            self.obj.teardown_function(self.obj) 
+    
+class GenItem(Item):
+    def __init__(self, name, parent, call, args): 
+        super(GenItem, self).__init__(name, parent, args) 
+        self._obj = call  
 
 #
 # triggering specific outcomes while executing Items

Modified: py/branch/py-collect/test2/testing/test/data/disabled.py
==============================================================================
--- py/dist/py/test/testing/test/data/disabled.py	(original)
+++ py/branch/py-collect/test2/testing/test/data/disabled.py	Tue Feb  1 14:06:58 2005
@@ -1,4 +1,4 @@
-class x:
-    class y:
-        disabled = True
-        def test_method(self): pass
+class TestDisabled:
+    disabled = True
+    def test_method(self): 
+        pass

Added: py/branch/py-collect/test2/testing/test/data/filetest.py
==============================================================================
--- (empty file)
+++ py/branch/py-collect/test2/testing/test/data/filetest.py	Tue Feb  1 14:06:58 2005
@@ -0,0 +1,7 @@
+
+def test_one(): 
+    assert 42 == 43
+
+class TestClass: 
+    def test_method_one(self): 
+        assert 42 == 43 

Modified: py/branch/py-collect/test2/testing/test_collect.py
==============================================================================
--- py/dist/py/test/testing/test_collect.py	(original)
+++ py/branch/py-collect/test2/testing/test_collect.py	Tue Feb  1 14:06:58 2005
@@ -1,54 +1,63 @@
 from __future__ import generators
 import py
-from py.__impl__.test import collect
-autopath = py.magic.autopath()
-testdir = autopath.dirpath('test')
-assert testdir.check(dir=1)
-datadir = testdir / 'data'
-
+datadir  = py.magic.autopath().dirpath('test', 'data')
 
 def test_failing_import_execfile():
     fn = datadir / 'failingimport.py'
-    col = collect.Module(py.path.extpy(fn))
+    col = py.test2.collect.Module(fn) 
     def _import(): 
-        l = list(col) 
-        assert l
-        ex, = l
-        assert issubclass(ex.excinfo.type, ImportError)
+        py.test2.raises(ImportError, col.listdir)
     _import()
     _import()
 
+def XXXtest_finds_root(): 
+    fn = datadir / 'filetest.py'
+    col = py.test2.collect.Module(fn) 
+    root, namelist = col.fromroot() 
+    assert isinstance(root, py.test2.collect.Directory) 
+    cur = root
+    for x in namelist: 
+        cur = cur.join(x) 
+    assert cur.name == col.name 
+    assert cur.parent == col.parent  
+    assert cur.fspath == cur.fspath 
+
+def test_finds_tests(): 
+    fn = datadir / 'filetest.py'
+    col = py.test2.collect.Module(fn) 
+    l = col.listdir() 
+    assert len(l) == 2 
+    items = list(col.iteritems())
+    assert len(items) == 2 
+ 
+    assert l[0].name == 'test_one' 
+    assert l[1].name == 'TestClass' 
+    assert l[1].fspath == fn 
+
 def test_failing_import_directory():
-    class MyDirectory(collect.Directory):
-        fil = py.path.checker(basestarts="testspecial_", ext='.py')
-    l = list(MyDirectory(datadir))
+    class MyDirectory(py.test2.collect.Directory):
+        filefilter = py.path.checker(fnmatch='testspecial*.py') 
+    l = MyDirectory(datadir).listdir() 
     assert len(l) == 1
-    assert isinstance(l[0], collect.Module)
-    l2 = list(l[0])
-    assert l2
-    exc = l2[0]
-    assert isinstance(exc, collect.Error)
-    assert issubclass(exc.excinfo.type, ImportError)
+    assert isinstance(l[0], py.test2.collect.Module)
+    py.test.raises(ImportError, l[0].listdir)
 
 def test_module_file_not_found():
-    fn = testdir.join('nada','no')
-    l = list(collect.Module(fn))
-    assert len(l) == 1
-    assert isinstance(l[0], collect.Error)
-    assert isinstance(l[0].excinfo.value, py.error.ENOENT)
+    fn = datadir.join('nada','no')
+    col = py.test2.collect.Module(fn) 
+    py.test2.raises(py.error.ENOENT, col.listdir) 
 
 def test_syntax_error_in_module():
     modpath = py.path.extpy(datadir.join('syntax_error.py'))
-    col = collect.Module(modpath) 
-    l2 = list(col) 
-    assert len(l2) == 1
-    assert isinstance(l2[0], collect.Error)
-    assert issubclass(l2[0].excinfo.type, SyntaxError)
+    col = py.test2.collect.Module(modpath) 
+    py.test.raises(SyntaxError, col.listdir) 
 
 def test_disabled_class():
-    extpy = py.path.extpy(datadir.join('disabled.py'))
-    l = list(collect.Class(extpy))
-    assert len(l) == 0
+    col = py.test2.collect.Module(datadir.join('disabled.py'))
+    l = col.listdir() 
+    assert len(l) == 1
+    assert isinstance(l[0], py.test2.collect.Class)
+    assert l[0].listdir() == []
 
 class Testsomeclass:
     disabled = True
@@ -56,16 +65,57 @@
         raise ValueError
 
 
-class TestWithCustomItem:
-    class Item(py.test.Item):
-        flag = []
-        def execute(self, target, *args):
-            self.flag.append(42)
-            target(*args)
-
-    def test_hello(self):
-        assert self.Item.flag == [42]
+#class TestWithCustomItem:
+#    class Item(py.test2.Item):
+#        flag = []
+#        def execute(self, target, *args):
+#            self.flag.append(42)
+#            target(*args)
+#
+#    def test_hello(self):
+#        assert self.Item.flag == [42]
+#
 
+def test_generative_simple(): 
+    o = py.test2.config.tmpdir.ensure('generativetest', dir=1)
+    tfile = o.join('test_generative.py')
+    tfile.write(py.code.Source("""
+        def func1(arg, arg2): 
+            assert arg == arg2 
+
+        def test_gen(): 
+            yield func1, 17, 3*5
+            yield func1, 42, 6*7
+
+        class TestGenMethods: 
+            def test_gen(self): 
+                yield func1, 17, 3*5
+                yield func1, 42, 6*7
+    """))
+    col = py.test2.collect.Module(tfile) 
+    l = col.listdir() 
+    assert len(l) == 2 
+
+    generator = l[0]
+    assert isinstance(generator, py.test2.collect.Generator)
+    l2 = generator.listdir() 
+    assert len(l2) == 2 
+    assert isinstance(l2[0], py.test2.GenItem)
+    assert isinstance(l2[1], py.test2.GenItem)
+    assert l2[0].name == 'test_gen:0'
+    assert l2[1].name == 'test_gen:1'
+ 
+    classlist = l[1].listdir() 
+    assert len(classlist) == 1
+    generator = classlist[0]
+    assert isinstance(generator, py.test2.collect.Generator)
+    l2 = generator.listdir() 
+    assert len(l2) == 2 
+    assert isinstance(l2[0], py.test2.GenItem)
+    assert isinstance(l2[1], py.test2.GenItem)
+    assert l2[0].name == 'test_gen:0'
+    assert l2[1].name == 'test_gen:1'
+    
 l = []
 def test_1():
     l.append(1)
@@ -84,66 +134,34 @@
     def test_4(self):
         assert self.reslist == [1,2,3]
 
-#
-# some tests related to "generating tests"
-#
-l2=[]
-
-def func1():
-    print "in func1"
-    l2.append(1)
-
-def func2(i):
-    print "in func2 with param %d" % i
-    l2.append(i)
-
-def test_generator():
-    yield func1
-    yield func2, 2
-    yield func2, 3
-
-def test_stateful_previous():
-    x = l2
-    assert x == [1,2,3]
-
-class TestGeneratorMethod:
-    l3 = []
-    def func1(self, i):
-        self.l3.append(i)
-
-    def test_generator(self):
-        yield self.func1, 4
-        yield self.func1, 5
-
-    def test_previous_generator_worked(self):
-        assert self.l3 == [4,5]
-
 def test_custom_collection_from_conftest():
-    o = py.test.config.tmpdir.ensure('customconfigtest', dir=1)
+    o = py.test2.config.tmpdir.ensure('customconfigtest', dir=1)
     o.ensure('conftest.py').write("""if 1:
         import py
-        class MyItem(py.test.Item):
+        class MyItem(py.test2.Item):
             pass
-        class Directory(py.test.collect.Directory):
-            def fil(self, fspath):
+        class Directory(py.test2.collect.Directory):
+            def filefilter(self, fspath):
                 return fspath.check(basestarts='check_')
-        class Module(py.test.collect.Module):
-            def collect_function(self, extpy):
-                if extpy.check(basestarts='check_', func=1):
-                    yield self.Item(extpy)
-        class Class(py.test.collect.Class):
-            def collect_method(self, extpy):
-                if extpy.check(basestarts='check_', func=1):
-                    yield MyItem(extpy)
+        class Module(py.test2.collect.Module):
+            Item = MyItem
+            def funcnamefilter(self, name): 
+                return name.startswith('check_') 
+            def classnamefilter(self, name): 
+                return name.startswith('CustomTestClass') 
+        class Class(py.test2.collect.Class):
+            Item = MyItem 
+            def funcnamefilter(self, name): 
+                return name.startswith('check_') 
         """)
     o.ensure('somedir', 'check_something').write("""if 1:
         def check_func():
             assert 42 == 42
-        class TestClass:
+        class CustomTestClass:
             def check_method(self):
                 assert 23 == 23
         """)
-    from py.__impl__.test.collect import getfscollector
-    units = list(getfscollector(o).iterunits())
-    assert len(units) == 2
-    assert units[1].__class__.__name__ == 'MyItem'
+    from py.__impl__.test2.collect import getfscollector
+    items = list(getfscollector(o).iteritems())
+    assert len(items) == 2
+    assert items[1].__class__.__name__ == 'MyItem'



More information about the pytest-commit mailing list