Changeset 121

Show
Ignore:
Timestamp:
Wed Nov 15 22:34:10 2006
Author:
jpellerin
Message:

Reverted [113] in trunk. That work belongs in the new_loader work branch only.

Files:

Legend:

Unmodified
Added
Removed
Modified
  • trunk/unit_tests/test_loader.py

    r113 r121  
    248 248          
    249 249 if __name__ == '__main__':  
    250       import logging  
    251       logging.basicConfig()  
    252       logging.getLogger('').setLevel(0)  
    253       #logging.getLogger('nose.importer').setLevel(0)  
    254       unittest.main() #testLoader=loader.TestLoader())  
      250     #import logging  
      251     #logging.basicConfig()  
      252     #logging.getLogger('').setLevel(0)  
      253     unittest.main(testLoader=loader.TestLoader())  
  • trunk/nose/core.py

    r113 r121  
    15 15 from nose.proxy import ResultProxySuite  
    16 16 from nose.result import Result  
    17   from nose.suite import LazySuite  
      17 from nose.suite import LazySuite, TestModule  
    17 17 from nose.util import absdir, tolist  
    18 18 from nose.importer import add_path  
     
    469 469     testLoader = defaultTestLoader(conf)  
    470 470     def collector(conf, loader):  
    471           return loader.loadTestsFromModule(name=name)  
      471         return TestModule(loader.loadTestsFromModule, conf, name)  
    471 471     main(defaultTest=collector, testLoader=testLoader)     
    472 472  
  • trunk/nose/suite.py

    r113 r121  
    4 4 """  
    5 5 import logging  
    6   import os  
    7 6 import sys  
    8 7 import unittest  
     
    14 13 log = logging.getLogger('nose.suite')  
    15 14  
    16   class TestSuite(unittest.TestSuite):  
    17       """A test suite with setup and teardown methods.  
      15  
      16 class LazySuite(unittest.TestSuite):  
      17     """Generator-based test suite. Pass a callable that returns an iterable of  
      18     tests, and a nose.config.Config. Also provides hooks (setUp and tearDown)  
      19     for suite-level fixtures.  
    18 20     """  
      21     # _exc_info_to_string needs this property  
      22     failureException = unittest.TestCase.failureException  
      23      
      24     def __init__(self, loadtests, conf=None):  
      25         self._loadtests = loadtests  
      26         if conf is None:  
      27             conf = Config()  
      28         self.conf = conf  
      29  
      30     def loadtests(self):  
      31         for test in self._loadtests():  
      32             yield test  
      33  
      34     # lazy property so subclasses can override loadtests()  
      35     _tests = property(lambda self: self.loadtests(),  
      36                       None, None,  
      37                       'Tests in this suite (iter)')  
      38  
    19 39     def __call__(self, *arg, **kw):  
    20 40         self.run(*arg, **kw)  
    21    
    22       def id(self):  
    23           return self.__str__()  
    24 41          
    25 42     def run(self, result):  
     
    47 64         finally:  
    48 65             result.stopTest(self)  
    49    
      66              
    49 66     def setUp(self):  
    50 67         pass  
     
    58 75  
    59 76  
    60   class ModuleSuite(TestSuite):  
    61       """Suite of tests in a module.  
    62       """  
    63       def __init__(self, tests, module=None, error=None, **kw):  
    64           super(ModuleSuite, self).__init__(tests=tests, **kw)  
    65           self.module = module  
    66           self.error = error  
    67    
    68       def __repr__(self):  
    69           try:  
    70               name = self.module.__name__  
    71               if hasattr(self.module, '__path__') and self.module.__path__:  
    72                   path = self.module.__path__[0]  
    73               else:                 
    74                   path = self.module.__file__  
    75               for i in xrange(0, len(name.split('.'))):  
    76                   path = os.path.dirname(path)  
    77               return "test module %s in %s" % (name, path)  
    78           except AttributeError:  
    79               from traceback import format_exception  
    80               if self.error:  
    81                   ef = ''.join(format_exception(*self.error))  
    82               else:  
    83                   ef = ''  
    84               return "test module (%s, %s)" % (self.module, ef)  
    85       __str__ = __repr__  
    86    
    87       def run(self, result):  
    88           if self.error:  
    89               result.addError(self.error)  
    90               return  
    91           # Don't bother running setup and teardown if we don't  
    92           # have any tests to run.  
    93           if not self._tests:  
    94               return  
    95           super(ModuleSuite, self).run(result)  
    96    
    97       def setUp(self):  
    98           """Run any package or module setup function found. For packages, setup  
    99           functions may be named 'setupPackage', 'setup_package', 'setUp',  
    100           or 'setup'. For modules, setup functions may be named  
    101           'setupModule', 'setup_module', 'setUp', or 'setup'. The setup  
    102           function may optionally accept a single argument; in that case,  
    103           the test package or module will be passed to the setup function.  
    104           """  
    105           log.debug('TestModule.setUp')  
    106           if hasattr(self.module, '__path__'):  
    107               names = ['setupPackage', 'setUpPackage', 'setup_package']  
    108           else:  
    109               names = ['setupModule', 'setUpModule', 'setup_module']  
    110           names += ['setUp', 'setup']  
    111           try_run(self.module, names)  
    112                
    113       def tearDown(self):  
    114           """Run any package or module teardown function found. For packages,  
    115           teardown functions may be named 'teardownPackage',  
    116           'teardown_package' or 'teardown'. For modules, teardown functions  
    117           may be named 'teardownModule', 'teardown_module' or  
    118           'teardown'. The teardown function may optionally accept a single  
    119           argument; in that case, the test package or module will be passed  
    120           to the teardown function.  
    121    
    122           The teardown function will be run only if any package or module  
    123           setup function completed successfully.  
    124           """  
    125           if hasattr(self.module, '__path__'):  
    126               names = ['teardownPackage', 'teardown_package']  
    127           else:  
    128               names = ['teardownModule', 'teardown_module']  
    129           names += ['tearDown', 'teardown']         
    130           try_run(self.module, names)  
    131    
    132   # backwards compatibility  
    133   TestModule = ModuleSuite  
    134    
    135    
    136   class LazySuite(TestSuite):  
    137       """Generator-based test suite. Pass a callable that returns an iterable of  
    138       tests, and a nose.config.Config. Also provides hooks (setUp and tearDown)  
    139       for suite-level fixtures.  
    140       """  
    141       # _exc_info_to_string needs this property  
    142       failureException = unittest.TestCase.failureException  
    143        
    144       def __init__(self, loadtests, conf=None, **kw):  
    145           self._loadtests = loadtests  
    146           if conf is None:  
    147               conf = Config()  
    148           self.conf = conf  
    149    
    150       def loadtests(self):  
    151           for test in self._loadtests():  
    152               yield test  
    153    
    154       # lazy property so subclasses can override loadtests()  
    155       _tests = property(lambda self: self.loadtests(),  
    156                         None, None,  
    157                         'Tests in this suite (iter)')  
    158    
    159    
    160 77 class GeneratorMethodTestSuite(LazySuite):  
    161 78     """Test suite for test methods that are generators.  
     
    217 134                                     self.importPath):  
    218 135             yield test  
      136  
      137              
      138 class TestModule(LazySuite):  
      139     """Lazy suite that collects tests from modules and packages.  
      140  
      141     This suite collects module members that match the testMatch  
      142     regular expression. For packages, it also collects any modules or  
      143     packages found in the package __path__ that match testMatch. For  
      144     modules that themselves do not match testMatch, the collector collects  
      145     doctests instead of test functions.  
      146  
      147     Before returning the first collected test, any defined setup method  
      148     will be run. Packages may define setup, setUp, setup_package or  
      149     setUpPackage, modules setup, setUp, setup_module, setupModule or  
      150     setUpModule. Likewise, teardown will be run if defined and if setup  
      151     ran successfully; teardown methods follow the same naming rules as  
      152     setup methods.  
      153     """  
      154     fromDirectory = None  
      155      
      156     def __init__(self, loadtests, conf, moduleName=None, path=None,  
      157                  module=None):  
      158         self.moduleName = moduleName  
      159         self.path = path  
      160         self.module = module  
      161         if module and moduleName is None:  
      162             self.moduleName = module.__name__         
      163         LazySuite.__init__(self, loadtests, conf)  
      164          
      165     def __repr__(self):  
      166         return "test module %s in %s" % (self.moduleName, self.path)  
      167     __str__ = __repr__  
      168  
      169     def loadtests(self):  
      170         tests = self._loadtests(self.module, self.path)  
      171         try:  
      172             for test in tests:  
      173                 yield test  
      174         except TypeError:  
      175             # python 2.3: TestSuite not iterable  
      176             for test in tests._tests:  
      177                 yield test  
      178  
      179     def id(self):  
      180         return self.__str__()  
      181          
      182     def setUp(self):  
      183         """Run any package or module setup function found. For packages, setup  
      184         functions may be named 'setupPackage', 'setup_package', 'setUp',  
      185         or 'setup'. For modules, setup functions may be named  
      186         'setupModule', 'setup_module', 'setUp', or 'setup'. The setup  
      187         function may optionally accept a single argument; in that case,  
      188         the test package or module will be passed to the setup function.  
      189         """  
      190         log.debug('TestModule.setUp')  
      191         if self.module is None:  
      192             self.module = _import(self.moduleName, [self.path], self.conf)  
      193             log.debug('Imported %s from %s on %s', self.module,  
      194                       self.moduleName, self.path)  
      195         if hasattr(self.module, '__path__'):  
      196             names = ['setupPackage', 'setUpPackage', 'setup_package']  
      197         else:  
      198             names = ['setupModule', 'setUpModule', 'setup_module']  
      199         names += ['setUp', 'setup']  
      200         try_run(self.module, names)  
      201              
      202     def tearDown(self):  
      203         """Run any package or module teardown function found. For packages,  
      204         teardown functions may be named 'teardownPackage',  
      205         'teardown_package' or 'teardown'. For modules, teardown functions  
      206         may be named 'teardownModule', 'teardown_module' or  
      207         'teardown'. The teardown function may optionally accept a single  
      208         argument; in that case, the test package or module will be passed  
      209         to the teardown function.  
      210  
      211         The teardown function will be run only if any package or module  
      212         setup function completed successfully.  
      213         """  
      214         if hasattr(self.module, '__path__'):  
      215             names = ['teardownPackage', 'teardown_package']  
      216         else:  
      217             names = ['teardownModule', 'teardown_module']  
      218         names += ['tearDown', 'teardown']         
      219         try_run(self.module, names)  
  • trunk/nose/importer.py

    r113 r121  
    43 43     if conf.addPaths:  
    44 44         for p in path:  
    45               if p is not None:  
    46                   add_path(p)  
      45             add_path(p)  
    47 46  
    48 47     path = [ p for p in path if p is not None ]  
  • trunk/nose/loader.py

    r113 r121  
    10 10 from nose.case import *  
    11 11 from nose.config import Config  
    12   from nose.importer import add_path, _import  
      12 from nose.importer import add_path  
    12 12 from nose.plugins import call_plugins  
    13 13 from nose.selector import defaultSelector  
    14   from nose.suite import ModuleSuite, TestClass, TestDir, \  
      14 from nose.suite import LazySuite, TestClass, TestDir, TestModule, \  
    14 14     GeneratorMethodTestSuite  
    15 15 from nose.util import is_generator, split_test_name, try_run  
     
    19 19 log = logging.getLogger(__name__)  
    20 20  
    21   class LoaderException(Exception):  
    22       pass  
    23 21      
    24 22 class TestLoader(unittest.TestLoader):  
     
    32 30     long as possible.  
    33 31     """  
    34       suiteClass = ModuleSuite  
    35        
    36 32     def __init__(self, conf=None, selector=None):  
    37 33         if conf is None:  
     
    56 52                              "absolute paths (%s)" % dirname)  
    57 53         self.conf.working_dir = dirname  
    58           if importPath is None:  
    59               importPath = dirname  
    60            
      54  
    61 55         # Ensure that any directory we examine is on sys.path  
    62 56         if self.conf.addPaths:  
     
    84 78                 yield test  
    85 79          
    86       def loadTestsFromModule(self, module=None, name=None,  
    87                               package=None, importPath=None):  
    88           """Load tests from module at (optional) import path. One of module or  
    89           name must be supplied. If name is supplied, the module name (prepended  
    90           with package if that is not empty) will be imported.  
      80     def loadTestsFromModule(self, module, importPath=None):  
      81         """Load tests from module at (optional) import path.  
    91 82         """  
    92           if module is None:  
    93               if name is None:  
    94                   raise LoaderException("loadTestsFromModule: one of module or "  
    95                                         "name must be supplied")  
    96               if package is not None:  
    97                   modname = "%s.%s" % (package, name)  
    98               else:  
    99                   modname = name  
    100               try:  
    101                   log.debug("Importing %s from %s", modname, importPath)  
    102                   module = _import(modname, [importPath], self.conf)  
    103               except KeyboardInterrupt:  
    104                   raise  
    105               except:  
    106                   error = sys.exc_info()  
    107                   return self.suiteClass(tests=[], error=error)  
    108            
    109 83         log.debug("load from module %s (%s)", module, importPath)  
    110 84         tests = []  
     
    131 105                                  module.__name__, importPath))  
    132 106         # compat w/unittest  
    133           return self.suiteClass(tests, module=module)  
      107         return self.suiteClass(tests)  
      108  
      109     def loadTestsFromModuleName(self, module_name, package=None,  
      110                                 importPath=None):  
      111         """Load tests from module_name. Specifiy module (name) to load module  
      112         from that module. Specify import path  
      113         to import from that path.  
      114         """  
      115         if package is not None:  
      116             module_name = "%s.%s" % (package, module_name)  
      117         if importPath is None:  
      118             importPath = self.conf.working_dir  
      119         yield TestModule(self.loadTestsFromModule,  
      120                          self.conf, module_name, importPath)  
    134 121  
    135 122     def loadTestsFromName(self, name, module=None, importPath=None):  
     
    144 131         except AttributeError:  
    145 132             pass  
    146    
    147           if importPath is None:  
    148               importPath = self.conf.working_dir  
    149 133          
    150 134         tests = None  
     
    177 161         elif mod_name:  
    178 162             # handle module-like names  
    179               log.debug("%s is a module name", name)  
    180               yield self.loadTestsFromModule(name=name,  
    181                                              package=module,  
    182                                              importPath=importPath)  
      163             tests = self.loadTestsFromModuleName(name,  
      164                                                  package=module,  
      165                                                  importPath=importPath)  
    183 166         elif module:  
    184 167             # handle func-like names in a module             
     
    186 169         if tests:  
    187 170             for test in tests:  
    188                   yield test  
      171                 yield test                 
    188 171         # give plugins a chance  
    189 172         for plug in self.plugins:  
     
    211 194                 self.conf.tests.extend([ rel(n, module.__name__)  
    212 195                                          for n in names ])  
      196  
    213 197             try:  
    214 198                 mpath = os.path.dirname(module.__path__[0])  
     
    216 200                 mpath = os.path.dirname(module.__file__)  
    217 201                  
    218               return self.loadTestsFromModule(module, importPath=mpath)  
      202             #return self.loadTestsFromModule(module)  
      203             return TestModule(self.loadTestsFromModule,  
      204                               self.conf,  
      205                               module=module,  
      206                               path=mpath)  
    219 207         else:  
    220 208             tests = []  
    221 209             for name in names:  
    222 210                 for test in self.loadTestsFromName(name):  
    223                       tests.append(test)  
      211                     tests.append(test)         
    223 211         return self.suiteClass(tests)  
    224 212  
     
    242 230             ispymod = False  
    243 231         if ispymod:  
    244               yield self.loadTestsFromModule(name=test, package=module,  
    245                                              importPath=importPath)  
      232             if module is not None:  
      233                 test = "%s.%s" % (module, test)  
      234             yield TestModule(self.loadTestsFromModule,  
      235                              self.conf, test, importPath)  
    246 236         # give plugins a chance  
    247 237         for plug in self.plugins:  
  • trunk/nose/selector.py

    r113 r121  
    210 210         """Is the directory a wanted test directory?  
    211 211  
    212           All package directories match, so long as they do not match exclude.  
    213           All other directories must match test requirements.  
      212         All package directories match, so long as they do not match exclude. All  
      213         other directories must match test requirements.  
    214 214         """  
    215 215         init = os.path.join(dirname, '__init__.py')  
  • trunk/nose/proxy.py

    r113 r121  
    10 10 import unittest  
    11 11 from nose.result import Result, ln  
    12   from nose.suite import TestSuite  
    13 12  
    14 13 log = logging.getLogger(__name__)  
     
    70 69  
    71 70      
    72   class ResultProxySuite(TestSuite):  
      71 class ResultProxySuite(unittest.TestSuite):  
    72 71     """Test suite that supports output capture, etc, by wrapping each test in  
    73 72     a TestProxy.