2014-09-30 16:15:32 +00:00
|
|
|
from setuptools import Command
|
2013-10-11 17:28:32 +00:00
|
|
|
from distutils.errors import DistutilsOptionError
|
|
|
|
import sys
|
2014-09-30 16:15:32 +00:00
|
|
|
from pkg_resources import *
|
|
|
|
from pkg_resources import _namespace_packages
|
|
|
|
from unittest import TestLoader, main
|
2013-10-11 17:28:32 +00:00
|
|
|
|
|
|
|
class ScanningLoader(TestLoader):
|
2014-09-30 16:15:32 +00:00
|
|
|
|
2013-10-11 17:28:32 +00:00
|
|
|
def loadTestsFromModule(self, module):
|
|
|
|
"""Return a suite of all tests cases contained in the given module
|
|
|
|
|
|
|
|
If the module is a package, load tests from all the modules in it.
|
|
|
|
If the module has an ``additional_tests`` function, call it and add
|
|
|
|
the return value to the tests.
|
|
|
|
"""
|
|
|
|
tests = []
|
2014-09-30 16:15:32 +00:00
|
|
|
if module.__name__!='setuptools.tests.doctest': # ugh
|
|
|
|
tests.append(TestLoader.loadTestsFromModule(self,module))
|
2013-10-11 17:28:32 +00:00
|
|
|
|
|
|
|
if hasattr(module, "additional_tests"):
|
|
|
|
tests.append(module.additional_tests())
|
|
|
|
|
|
|
|
if hasattr(module, '__path__'):
|
|
|
|
for file in resource_listdir(module.__name__, ''):
|
2014-09-30 16:15:32 +00:00
|
|
|
if file.endswith('.py') and file!='__init__.py':
|
|
|
|
submodule = module.__name__+'.'+file[:-3]
|
2013-10-11 17:28:32 +00:00
|
|
|
else:
|
2014-09-30 16:15:32 +00:00
|
|
|
if resource_exists(
|
|
|
|
module.__name__, file+'/__init__.py'
|
|
|
|
):
|
|
|
|
submodule = module.__name__+'.'+file
|
2013-10-11 17:28:32 +00:00
|
|
|
else:
|
|
|
|
continue
|
|
|
|
tests.append(self.loadTestsFromName(submodule))
|
|
|
|
|
2014-09-30 16:15:32 +00:00
|
|
|
if len(tests)!=1:
|
2013-10-11 17:28:32 +00:00
|
|
|
return self.suiteClass(tests)
|
|
|
|
else:
|
2014-09-30 16:15:32 +00:00
|
|
|
return tests[0] # don't create a nested suite for only one return
|
2013-10-11 17:28:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
class test(Command):
|
2014-09-30 16:15:32 +00:00
|
|
|
|
2013-10-11 17:28:32 +00:00
|
|
|
"""Command to run unit tests after in-place build"""
|
|
|
|
|
|
|
|
description = "run unit tests after in-place build"
|
|
|
|
|
|
|
|
user_options = [
|
2014-09-30 16:15:32 +00:00
|
|
|
('test-module=','m', "Run 'test_suite' in specified module"),
|
|
|
|
('test-suite=','s',
|
|
|
|
"Test suite to run (e.g. 'some_module.test_suite')"),
|
2013-10-11 17:28:32 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
def initialize_options(self):
|
|
|
|
self.test_suite = None
|
|
|
|
self.test_module = None
|
|
|
|
self.test_loader = None
|
2014-09-30 16:15:32 +00:00
|
|
|
|
2013-10-11 17:28:32 +00:00
|
|
|
|
|
|
|
def finalize_options(self):
|
|
|
|
|
|
|
|
if self.test_suite is None:
|
|
|
|
if self.test_module is None:
|
|
|
|
self.test_suite = self.distribution.test_suite
|
|
|
|
else:
|
2014-09-30 16:15:32 +00:00
|
|
|
self.test_suite = self.test_module+".test_suite"
|
2013-10-11 17:28:32 +00:00
|
|
|
elif self.test_module:
|
|
|
|
raise DistutilsOptionError(
|
|
|
|
"You may specify a module or a suite, but not both"
|
|
|
|
)
|
|
|
|
|
|
|
|
self.test_args = [self.test_suite]
|
|
|
|
|
|
|
|
if self.verbose:
|
2014-09-30 16:15:32 +00:00
|
|
|
self.test_args.insert(0,'--verbose')
|
2013-10-11 17:28:32 +00:00
|
|
|
if self.test_loader is None:
|
2014-09-30 16:15:32 +00:00
|
|
|
self.test_loader = getattr(self.distribution,'test_loader',None)
|
2013-10-11 17:28:32 +00:00
|
|
|
if self.test_loader is None:
|
|
|
|
self.test_loader = "setuptools.command.test:ScanningLoader"
|
|
|
|
|
2014-08-12 08:44:01 +00:00
|
|
|
|
2014-09-30 16:15:32 +00:00
|
|
|
|
|
|
|
def with_project_on_sys_path(self, func):
|
|
|
|
if sys.version_info >= (3,) and getattr(self.distribution, 'use_2to3', False):
|
2013-10-11 17:28:32 +00:00
|
|
|
# If we run 2to3 we can not do this inplace:
|
|
|
|
|
|
|
|
# Ensure metadata is up-to-date
|
|
|
|
self.reinitialize_command('build_py', inplace=0)
|
|
|
|
self.run_command('build_py')
|
|
|
|
bpy_cmd = self.get_finalized_command("build_py")
|
|
|
|
build_path = normalize_path(bpy_cmd.build_lib)
|
|
|
|
|
|
|
|
# Build extensions
|
|
|
|
self.reinitialize_command('egg_info', egg_base=build_path)
|
|
|
|
self.run_command('egg_info')
|
|
|
|
|
|
|
|
self.reinitialize_command('build_ext', inplace=0)
|
|
|
|
self.run_command('build_ext')
|
|
|
|
else:
|
|
|
|
# Without 2to3 inplace works fine:
|
|
|
|
self.run_command('egg_info')
|
|
|
|
|
|
|
|
# Build extensions in-place
|
|
|
|
self.reinitialize_command('build_ext', inplace=1)
|
|
|
|
self.run_command('build_ext')
|
|
|
|
|
|
|
|
ei_cmd = self.get_finalized_command("egg_info")
|
|
|
|
|
|
|
|
old_path = sys.path[:]
|
|
|
|
old_modules = sys.modules.copy()
|
|
|
|
|
|
|
|
try:
|
|
|
|
sys.path.insert(0, normalize_path(ei_cmd.egg_base))
|
|
|
|
working_set.__init__()
|
|
|
|
add_activation_listener(lambda dist: dist.activate())
|
|
|
|
require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version))
|
|
|
|
func()
|
|
|
|
finally:
|
|
|
|
sys.path[:] = old_path
|
|
|
|
sys.modules.clear()
|
|
|
|
sys.modules.update(old_modules)
|
|
|
|
working_set.__init__()
|
|
|
|
|
2014-09-30 16:15:32 +00:00
|
|
|
|
2013-10-11 17:28:32 +00:00
|
|
|
def run(self):
|
|
|
|
if self.distribution.install_requires:
|
2014-09-30 16:15:32 +00:00
|
|
|
self.distribution.fetch_build_eggs(self.distribution.install_requires)
|
2013-10-11 17:28:32 +00:00
|
|
|
if self.distribution.tests_require:
|
|
|
|
self.distribution.fetch_build_eggs(self.distribution.tests_require)
|
|
|
|
|
|
|
|
if self.test_suite:
|
|
|
|
cmd = ' '.join(self.test_args)
|
|
|
|
if self.dry_run:
|
|
|
|
self.announce('skipping "unittest %s" (dry run)' % cmd)
|
|
|
|
else:
|
|
|
|
self.announce('running "unittest %s"' % cmd)
|
|
|
|
self.with_project_on_sys_path(self.run_tests)
|
|
|
|
|
2014-09-30 16:15:32 +00:00
|
|
|
|
2013-10-11 17:28:32 +00:00
|
|
|
def run_tests(self):
|
2014-09-30 16:15:32 +00:00
|
|
|
import unittest
|
|
|
|
|
2013-10-11 17:28:32 +00:00
|
|
|
# Purge modules under test from sys.modules. The test loader will
|
|
|
|
# re-import them from the build location. Required when 2to3 is used
|
|
|
|
# with namespace packages.
|
2014-09-30 16:15:32 +00:00
|
|
|
if sys.version_info >= (3,) and getattr(self.distribution, 'use_2to3', False):
|
2013-10-11 17:28:32 +00:00
|
|
|
module = self.test_args[-1].split('.')[0]
|
|
|
|
if module in _namespace_packages:
|
|
|
|
del_modules = []
|
|
|
|
if module in sys.modules:
|
|
|
|
del_modules.append(module)
|
|
|
|
module += '.'
|
|
|
|
for name in sys.modules:
|
|
|
|
if name.startswith(module):
|
|
|
|
del_modules.append(name)
|
|
|
|
list(map(sys.modules.__delitem__, del_modules))
|
|
|
|
|
2014-09-30 16:15:32 +00:00
|
|
|
loader_ep = EntryPoint.parse("x="+self.test_loader)
|
|
|
|
loader_class = loader_ep.load(require=False)
|
|
|
|
cks = loader_class()
|
|
|
|
unittest.main(
|
|
|
|
None, None, [unittest.__file__]+self.test_args,
|
|
|
|
testLoader = cks
|
2013-10-11 17:28:32 +00:00
|
|
|
)
|
|
|
|
|
2014-09-30 16:15:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|