Skip to content

Commit

Permalink
Merge remote branch 'akai/django-1.2-compatibility'
Browse files Browse the repository at this point in the history
  • Loading branch information
jbalogh committed Jan 26, 2010
2 parents 6b3ab3c + 391c92d commit b7e0ec0
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 67 deletions.
2 changes: 1 addition & 1 deletion django_nose/__init__.py
@@ -1,4 +1,4 @@
VERSION = (0, 0, 3)
__version__ = '.'.join(map(str, VERSION))

from runner import run_tests, run_gis_tests
from django_nose.runner import NoseTestSuiteRunner
31 changes: 21 additions & 10 deletions django_nose/management/commands/test.py
Expand Up @@ -7,10 +7,10 @@
from django.test.utils import get_runner


test_runner = get_runner(settings)
TestRunner = get_runner(settings)

if hasattr(test_runner, 'options'):
extra_options = test_runner.options
if hasattr(TestRunner, 'options'):
extra_options = TestRunner.options
else:
extra_options = []

Expand All @@ -19,6 +19,8 @@ class Command(BaseCommand):
option_list = BaseCommand.option_list + (
make_option('--noinput', action='store_false', dest='interactive', default=True,
help='Tells Django to NOT prompt the user for input of any kind.'),
make_option('--failfast', action='store_true', dest='failfast', default=False,
help='Tells Django to stop running the test suite after first failed test.'),
) + tuple(extra_options)
help = 'Runs the test suite for the specified applications, or the entire site if no apps are specified.'
args = '[appname ...]'
Expand All @@ -29,16 +31,25 @@ def handle(self, *test_labels, **options):

verbosity = int(options.get('verbosity', 1))
interactive = options.get('interactive', True)
failfast = options.get('failfast', False)

try:
import south
except ImportError:
pass
else:
if management._commands['syncdb'] == 'south':
# South has its own test command that turns off migrations
# during testings. If we detected south, we need to fix syncdb.
management._commands['syncdb'] = 'django.core'

failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive)
if hasattr(TestRunner, 'func_name'):
# Pre 1.2 test runners were just functions,
# and did not support the 'failfast' option.
import warnings
warnings.warn(
'Function-based test runners are deprecated. Test runners should be classes with a run_tests() method.',
PendingDeprecationWarning
)
failures = TestRunner(test_labels, verbosity=verbosity, interactive=interactive)
else:
test_runner = TestRunner(verbosity=verbosity, interactive=interactive, failfast=failfast)
failures = test_runner.run_tests(test_labels)

if failures:
sys.exit(failures)
sys.exit(bool(failures))
116 changes: 60 additions & 56 deletions django_nose/runner.py
Expand Up @@ -13,7 +13,8 @@
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import connection
from django.test import utils
from django.db.models import get_apps
from django.test.simple import DjangoTestSuiteRunner, get_tests

import nose.core

Expand All @@ -28,57 +29,63 @@ def any(iterable):
return True
return False


def run_tests(test_labels, verbosity=1, interactive=True, spatial_db=False):
"""Test runner that invokes nose."""
# Prepare django for testing.
utils.setup_test_environment()
old_db_name = settings.DATABASE_NAME

if spatial_db:
from django.contrib.gis.db.backend import create_test_spatial_db
create_test_spatial_db(verbosity, autoclobber=not interactive)
else:
connection.creation.create_test_db(verbosity,
autoclobber=not interactive)

# Pretend it's a production environment.
settings.DEBUG = False

# We pass nose a list of arguments that looks like sys.argv, but customize
# to avoid unknown django arguments.
nose_argv = ['nosetests']
if hasattr(settings, 'NOSE_ARGS'):
nose_argv.extend(settings.NOSE_ARGS)

# Skip over 'manage.py test' and any arguments handled by django.
django_opts = ['--noinput']
for opt in BaseCommand.option_list:
django_opts.extend(opt._long_opts)
django_opts.extend(opt._short_opts)

nose_argv.extend(opt for opt in sys.argv[2:] if
not any(opt.startswith(d) for d in django_opts))

if verbosity >= 1:
print ' '.join(nose_argv)

try:
class NoseTestSuiteRunner(DjangoTestSuiteRunner):
def run_suite(self, nose_argv):
result_plugin = ResultPlugin()
test_program = nose.core.TestProgram(argv=nose_argv, exit=False,
addplugins=[result_plugin])
result = result_plugin.result
return len(result.failures) + len(result.errors)
finally:
# Clean up django.
connection.creation.destroy_test_db(old_db_name, verbosity)
utils.teardown_test_environment()


def run_gis_tests(test_labels, verbosity=1, interactive=True):
"""Test runner that invokes nose with a spatial database for GeoDjango."""
run_tests(test_labels, verbosity, interactive, spatial_db=True)

nose.core.TestProgram(argv=nose_argv, exit=False,
addplugins=[result_plugin])
return result_plugin.result

def build_suite(self):
"""Unused method
The build_suite() method of django.test.simple.DjangoTestSuiteRunner is
not used in django_nose.
"""
pass

def run_tests(self, test_labels, extra_tests=None):
"""
Run the unit tests for all the test names in the provided list.
Test names specified may be file or module names, and may optionally
indicate the test case to run by separating the module or file name from
the test case name with a colon. Filenames may be relative or
absolute. Examples:
runner.run_tests('test.module')
runner.run_tests('another.test:TestCase.test_method')
runner.run_tests('a.test:TestCase')
runner.run_tests('/path/to/test/file.py:test_function')
Returns the number of tests that failed.
"""
self.setup_test_environment()
for app in get_apps():
# register models from .tests modules in apps
get_tests(app)
old_names = self.setup_databases()

nose_argv = ['nosetests']
if hasattr(settings, 'NOSE_ARGS'):
nose_argv.extend(settings.NOSE_ARGS)

# Skip over 'manage.py test' and any arguments handled by django.
django_opts = ['--noinput', '--failfast']
for opt in BaseCommand.option_list:
django_opts.extend(opt._long_opts)
django_opts.extend(opt._short_opts)

nose_argv.extend(opt for opt in sys.argv[2:] if
not any(opt.startswith(d) for d in django_opts))

if self.verbosity >= 1:
print ' '.join(nose_argv)

result = self.run_suite(nose_argv)
self.teardown_databases(old_names)
self.teardown_test_environment()
return self.suite_result(result)

def _get_options():
"""Return all nose options that don't conflict with django options."""
Expand All @@ -92,8 +99,5 @@ def _get_options():


# Replace the builtin command options with the merged django/nose options.
run_tests.options = _get_options()
run_tests.__test__ = False

run_gis_tests.options = _get_options()
run_gis_tests.__test__ = False
NoseTestSuiteRunner.options = _get_options()
NoseTestSuiteRunner.__test__ = False

0 comments on commit b7e0ec0

Please sign in to comment.