Changeset 119
- Timestamp:
- Wed Nov 15 13:24:21 2006
- Files:
-
- branches/new_loader/nose/selector.py (modified) (diff)
- branches/new_loader/work.py (modified) (diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
branches/new_loader/nose/selector.py
r116 r119 59 59 self.match = conf.testMatch 60 60 self.tests = conf.tests 61 62 def fileInTests(self, tests): 63 if tests is None: 64 def in_tests(file): 65 return True 66 else: 67 def in_tests(file): 68 return filter(None, 69 [ t.matches_file(file) for t in tests ]) 70 return in_tests 61 71 62 def fileInTests(self, file): 72 def _fileInTests(self, file): 62 72 orig = file 63 73 if not os.path.isabs(file): … … 144 154 [exc.search(name) for exc in self.exclude]) 145 155 )) 156 157 def methodInTests(self, tests): 158 if tests is None: 159 def in_tests(method): 160 return True 161 else: 162 def in_tests(method): 163 return filter(None, 164 [ t.matches_method(method) for t in tests ]) 165 return in_tests 146 166 147 def methodInTests(self, method): 167 def _methodInTests(self, method): 147 167 """Determine if a method is listed in the requested tests. To 148 168 be consideed a match, the method's class must be in the class … … 163 183 return self.anytest(match) 164 184 165 def moduleInTests(self, module, either=False): 185 def moduleInTests(self, tests, either=False): 186 """Return a function that can tell whether a module is in this 187 batch of tests. 188 189 FIXME: it would be good to memoize this 190 """ 191 if tests is None: 192 def in_tests(module): 193 return True 194 else: 195 def in_tests(module): 196 return filter(None, 197 [ t.matches_module(module, either) 198 for t in tests ]) 199 return in_tests 200 201 def _moduleInTests(self, module, either=False): 166 202 def match(filename, modname, funcname, module=module, either=either): 167 203 log.debug("Checking module %s in test %s:%s (either: %s)", … … 187 223 return res 188 224 189 def wantClass(self, cls): 225 def wantClass(self, cls, tests=None): 189 225 """Is the class a wanted test class? 190 226 … … 206 242 log.debug("Plugin setting selection of %s to %s", cls, plug_wants) 207 243 wanted = plug_wants 208 return wanted and self.classInTests(cls) 244 return wanted and self.classInTests(tests)(cls) 208 244 209 def wantDirectory(self, dirname): 245 def wantDirectory(self, dirname, tests=None): 209 245 """Is the directory a wanted test directory? 210 246 … … 214 250 All other directories must match test requirements. 215 251 """ 252 log.debug("Want directory %s (%s)?", dirname, tests) 253 216 254 init = os.path.join(dirname, '__init__.py') 217 tail = os.path.basename(dirname) 255 tail = os.path.basename(dirname) 217 255 if os.path.exists(init): 218 256 wanted = (not self.exclude … … 229 267 if plug_wants is not None: 230 268 wanted = plug_wants 231 # FIXME in tests? 232 return wanted 269 in_tests = self.fileInTests(tests)(dirname) 270 log.debug("wantDirectory wanted %s, in_tests %s", wanted, in_tests) 271 return wanted and in_tests 233 272 234 def wantFile(self, file, package=None): 273 def wantFile(self, file, package=None, tests=None): 234 273 """Is the file a wanted test file? 235 274 … … 255 294 log.info('%s is executable; skipped', file) 256 295 return False 257 in_tests = self.fileInTests(file) 296 in_tests = self.fileInTests(tests)(file) 257 296 if not in_tests: 258 297 return False … … 268 307 return wanted or (pysrc and self.tests and in_tests) 269 308 270 def wantFunction(self, function): 309 def wantFunction(self, function, tests=None): 270 309 """Is the function a test function? 271 310 … … 280 319 # not a function 281 320 return False 282 in_tests = self.funcInTests(function) 321 in_tests = self.funcInTests(tests)(function) 282 321 if not in_tests: 283 322 return False … … 289 328 return wanted 290 329 291 def wantMethod(self, method): 330 def wantMethod(self, method, tests=None): 291 330 """Is the method a test method? 292 331 … … 304 343 # never collect 'private' methods 305 344 return False 306 in_tests = self.methodInTests(method) 345 in_tests = self.methodInTests(tests)(method) 306 345 if not in_tests: 307 346 return False … … 313 352 return wanted 314 353 315 def wantModule(self, module): 354 def wantModule(self, module, tests=None): 315 354 """Is the module a test module? 316 355 … … 323 362 modules where wantModuleTests() is true. 324 363 """ 325 in_tests = self.moduleInTests( module, either=True)364 in_tests = self.moduleInTests(tests, either=True)(module) 325 364 if not in_tests: 326 365 return False … … 332 371 return wanted or (self.tests and in_tests) 333 372 334 def wantModuleTests(self, module): 373 def wantModuleTests(self, module, tests=None): 334 373 """Collect tests from this module? 335 374 … … 343 382 tests, but instead cause the standard collector to collect tests. 344 383 """ 345 in_tests = self.moduleInTests(module) 384 in_tests = self.moduleInTests(tests)(module) 345 384 if not in_tests: 346 385 return False … … 358 397 defaultSelector = Selector 359 398 399 400 class TestAddress(object): 401 """A test address represents a user's request to run a particular 402 test. The user may specify a filename or module (or neither), 403 and/or a callable (a class, function, or method). The naming 404 format for test addresses is: 405 406 filename_or_module:callable 407 408 Filenames that are not absolute will be made absolute relative to 409 the working dir. 410 411 The filename or module part will be considered a module name if it 412 doesn't look like a file, that is, if it doesn't exist on the file 413 system and it doesn't contain any directory separators and it 414 doesn't end in .py. 415 416 Callables may be a class name, function name, method name, or 417 class.method specification. 418 """ 419 def __init__(self, name, working_dir): 420 self.name = name 421 self.working_dir = working_dir 422 self.filename, self.module, self.call = split_test_name(name) 423 if not self.filename is None and not os.path.isabs(self.filename): 424 self.filename = os.path.abspath(os.path.join(working_dir, 425 self.filename)) 426 427 def __str__(self): 428 return self.name 429 430 def __repr__(self): 431 return "%s: (%s, %s, %s)" % (self.name, self.filename, 432 self.module, self.call) 433 434 def matches_class(self, cls): 435 """Does the class match my call part? 436 """ 437 if self.call is None: 438 return True 439 440 def matches_file(self, filename): 441 fn = self.filename 442 if fn is None: 443 return self.matches_file_as_module(filename) 444 if fn.endswith('__init__.py'): 445 dn = os.path.dn(fn) 446 elif os.path.isdir(fn): 447 dn = fn 448 else: 449 dn = None 450 if os.path.isdir(filename): 451 dirname = filename 452 else: 453 dirname = None 454 # filename might be a directory and fn a file in that directory 455 # if so the directory has to match for us to continue on? 456 return (fn == filename 457 or (dn is not None 458 and (filename.startswith(dn) 459 and len(filename) > len(dn) 460 and filename[len(dn)] == os.path.sep) 461 or (filename == dn)) 462 or (dirname is not None 463 and (dirname == fn 464 or (fn.startswith(dirname) 465 and len(fn) > len(dirname) 466 and fn[len(dirname)] == os.path.sep)))) 467 468 def matches_file_as_module(self, filename): 469 """Match filename vs our module part. Convert our module into 470 a path fragment, and return True if the filename contains that 471 path fragment. This method should only be called when self.filename 472 is None. 473 """ 474 mn = self.module 475 if mn is None: 476 # No filename or modname part; so we match any module, because 477 # the only part we have defined is the call, which could be 478 # in any module 479 return True 480 mpath = os.path.sep.join(mn.split('.')) 481 return mpath in os.path.splitext(filename)[0] 482 483 def matches_function(self, function): 484 """Does the function match my call part? 485 """ 486 if self.call is None: 487 return True 488 489 def matches_method(self, method): 490 """Does the method match my call part? 491 """ 492 if self.call is None: 493 return True 494 495 def matches_module(self, module, either=False): 496 """Either = either my module can be a child of module or 497 module can be a child of my module. Without either, the 498 match is valid only if module is a child of my module. 499 """ 500 pass 501 360 502 # Helpers 361 503 -
branches/new_loader/work.py
r118 r119 2 2 import re 3 3 from imp import load_source 4 from nose.selector import Selector 4 from nose.selector import Selector, TestAddress 4 4 from nose.config import Config 5 5 from nose.importer import _import … … 8 8 9 9 import logging 10 logging.basicConfig() 11 logging.getLogger('').setLevel(0) 10 # logging.basicConfig() 11 # logging.getLogger('').setLevel(0) 12 12 13 13 conf = Config() 14 14 selector = Selector(conf) 15 15 16 16 17 def ispackage(dirname): 17 18 return os.path.exists(os.path.join(dirname, '__init__.py')) … … 31 32 32 33 33 class TestAddress:34 def __init__(self, name, working_dir):35 self.name = name36 self.working_dir = working_dir37 self.filename, self.module, self.call = split_test_name(name)38 if not self.filename is None and not os.path.isabs(self.filename):39 self.filename = os.path.abspath(os.path.join(working_dir,40 self.filename))41 42 def __str__(self):43 return self.name44 45 def __repr__(self):46 return "%s: (%s, %s, %s)" % (self.name, self.filename,47 self.module, self.call)48 49 def matches_file(self, filename):50 fn = self.filename51 if fn is None:52 return self.matches_file_as_module(filename)53 if fn.endswith('__init__.py'):54 dn = os.path.dn(fn)55 elif os.path.isdir(fn):56 dn = fn57 else:58 dn = None59 if os.path.isdir(filename):60 dirname = filename61 else:62 dirname = None63 # filename might be a directory and fn a file in that directory64 # if so the directory has to match for us to continue on?65 return (fn == filename66 or (dn is not None67 and (filename.startswith(dn)68 and len(filename) > len(dn)69 and filename[len(dn)] == os.path.sep)70 or (filename == dn))71 or (dirname is not None72 and (dirname == fn73 or (fn.startswith(dirname)74 and len(fn) > len(dirname)75 and fn[len(dirname)] == os.path.sep))))76 77 def matches_file_as_module(self, filename):78 """Match filename vs our module. Convert our module into79 a path fragment, and return True if the filename contains that80 path fragment.81 """82 mn = self.module83 if mn is None:84 return False85 mpath = os.path.sep.join(mn.split('.'))86 return mpath in os.path.splitext(filename)[0]87 88 89 34 class ModuleSuite: 90 def __init__(self, name, path, loader, working_dir, wanted):35 def __init__(self, name, path, loader, working_dir, tests): 90 35 self.name = name 91 36 self.path = path … … 94 39 self.loader = loader 95 40 self.working_dir = working_dir 96 self.wanted = wanted 41 self.tests = tests 42 self._collected = False 97 43 self._tests = [] 98 44 … … 118 64 119 65 def collectTests(self): 120 if self._tests: 66 # print "Collect Tests %s" % self 67 if self._collected or self._tests: 121 68 return 69 self._collected = True 122 70 self._tests = [] 123 71 if self.module is None: … … 126 74 # if it's a package) to sys.path first, though 127 75 self.module = load_source(self.name, self.path) 128 for test in self.loader.loadTestsFromModule(self.module, self. wanted):76 for test in self.loader.loadTestsFromModule(self.module, self.tests): 128 76 self.addTest(test) 129 77 130 78 def run(self, result): 131 79 self.collectTests() 132 if not self ._tests:80 if not self: 132 80 return 133 81 # FIXME this needs to be a real run() with exc handling … … 144 92 def tearDown(self): 145 93 print "TEARDOWN %s" % self 146 147 94 148 95 … … 155 102 if names: 156 103 tests = [ TestAddress(n, working_dir) for n in names ] 157 if tests is not None: 158 def intests(filename): 159 return filter(None, 160 [ t.matches_file(filename) for t in tests ]) 161 else: 162 def intests(filename): 163 return True 164 return self.findTests(working_dir, wanted=intests) 104 return self.findTests(working_dir, tests=tests) 165 105 166 def findTests(self, working_dir, wanted=None, package=None):106 def findTests(self, working_dir, tests=None, package=None): 166 106 for dirpath, dirnames, filenames in os.walk(working_dir): 167 107 … … 178 118 remove = True 179 119 ldir = os.path.join(dirpath, dirname) 180 pack = ispackage(ldir) 181 if ((pack or conf.testMatch.search(dirname)) 182 and wanted(ldir)): 183 if pack: 120 if selector.wantDirectory(ldir, tests=tests): 121 if ispackage(ldir): 184 122 remove = True 185 # print "**",ldir 186 # FIXME track this, we'll yield a ModuleSuite later 123 # we'll yield a ModuleSuite later 187 124 packages.append((dirname, 188 125 os.path.join(ldir, '__init__.py'))) 189 126 else: 190 127 remove = False 128 # print "Continue into %s" % ldir 191 129 if remove: 192 130 to_remove.add(dirname) … … 194 132 dirnames.remove(dirname) 195 133 196 # FIXME store dirs that we're going to yield as ModuleSuites197 # FIXME we want to yield the files in this dir first198 199 134 # Process files after dirs so that any lib dirs will 200 135 # already be in sys.path before we start importing files … … 202 137 for filename in filenames: 203 138 lname = os.path.join(dirpath, filename) 204 if (filename.endswith('.py') 205 and conf.testMatch.search(filename) 206 and wanted(lname)): 139 if selector.wantFile(lname, package=package, tests=tests): 207 140 # print "**", lname 208 141 yield ModuleSuite( … … 210 143 path=lname, loader=self, 211 144 working_dir=working_dir, 212 wanted=wanted)145 tests=tests) 212 145 # FIXME yield a ModuleSuite if it's a python module 213 146 # FIXME yield a FileSuite if it's not 214 # FIXME yield ModuleSuites for all module dirs147 # yield ModuleSuites for all packages 214 147 for name, path in packages: 215 148 yield ModuleSuite( … … 219 152 path=path, loader=self, 220 153 working_dir=working_dir, 221 wanted=wanted)154 tests=tests) 221 154 # At this point we're diving into directories that aren't packages 222 155 # so if we think we are in a package, we have to forget the … … 226 159 package = None 227 160 228 def loadTestsFromModule(self, module, wanted=None):161 def loadTestsFromModule(self, module, tests=None): 228 161 """Construct a TestSuite containing all of the tests in 229 162 the module, including tests in the package if it is a package 230 163 """ 164 # print "loadTestsFromModule %s" % module 231 165 if ispackageinit(module): 232 166 path = os.path.dirname(module.__file__) 233 for test in self.findTests(path, wanted, package=module.__name__):167 for test in self.findTests(path, tests, package=module.__name__): 233 167 # FIXME 234 168 print " ", test … … 254 188 #'test-dir' => 'support/test-dir/test.py' 255 189 #'test-dir/' => 'support/test-dir/test.py' 256 190 # 'test' => 'support/test.py', 'support/test-dir/test.py' -- not foo 256 190 257 191
