2005-07-29 23:15:40 +08:00
#!/usr/bin/env python
2006-08-27 21:59:47 +08:00
import os , sys , traceback
import unittest
2005-07-29 23:15:40 +08:00
2006-05-02 09:31:56 +08:00
MODEL_TESTS_DIR_NAME = ' modeltests '
2006-06-20 13:29:19 +08:00
REGRESSION_TESTS_DIR_NAME = ' regressiontests '
2005-07-29 23:15:40 +08:00
2006-05-02 09:31:56 +08:00
MODEL_TEST_DIR = os . path . join ( os . path . dirname ( __file__ ) , MODEL_TESTS_DIR_NAME )
2006-06-20 13:29:19 +08:00
REGRESSION_TEST_DIR = os . path . join ( os . path . dirname ( __file__ ) , REGRESSION_TESTS_DIR_NAME )
2005-07-30 06:35:54 +08:00
2006-05-27 05:28:12 +08:00
ALWAYS_INSTALLED_APPS = [
' django.contrib.contenttypes ' ,
2006-06-20 22:27:44 +08:00
' django.contrib.auth ' ,
2006-06-17 02:58:45 +08:00
' django.contrib.sites ' ,
2006-05-27 05:28:12 +08:00
' django.contrib.flatpages ' ,
' django.contrib.redirects ' ,
' django.contrib.sessions ' ,
2006-06-17 02:58:45 +08:00
' django.contrib.comments ' ,
' django.contrib.admin ' ,
2006-05-27 05:28:12 +08:00
]
2005-07-30 06:35:54 +08:00
def get_test_models ( ) :
2006-06-20 15:12:45 +08:00
models = [ ]
2006-06-20 22:27:44 +08:00
for loc , dirpath in ( MODEL_TESTS_DIR_NAME , MODEL_TEST_DIR ) , ( REGRESSION_TESTS_DIR_NAME , REGRESSION_TEST_DIR ) :
for f in os . listdir ( dirpath ) :
2006-08-27 21:59:47 +08:00
if f . startswith ( ' __init__ ' ) or f . startswith ( ' . ' ) or f . startswith ( ' sql ' ) or f . startswith ( ' invalid ' ) :
2006-06-20 15:12:45 +08:00
continue
models . append ( ( loc , f ) )
return models
2005-07-30 06:35:54 +08:00
2006-08-27 21:59:47 +08:00
def get_invalid_models ( ) :
models = [ ]
for loc , dirpath in ( MODEL_TESTS_DIR_NAME , MODEL_TEST_DIR ) , ( REGRESSION_TESTS_DIR_NAME , REGRESSION_TEST_DIR ) :
for f in os . listdir ( dirpath ) :
if f . startswith ( ' __init__ ' ) or f . startswith ( ' . ' ) or f . startswith ( ' sql ' ) :
continue
if f . startswith ( ' invalid ' ) :
models . append ( ( loc , f ) )
return models
class InvalidModelTestCase ( unittest . TestCase ) :
def __init__ ( self , model_label ) :
unittest . TestCase . __init__ ( self )
self . model_label = model_label
def runTest ( self ) :
2006-05-02 09:31:56 +08:00
from django . core import management
2006-06-23 12:37:00 +08:00
from django . db . models . loading import load_app
2006-08-27 21:59:47 +08:00
from cStringIO import StringIO
try :
module = load_app ( self . model_label )
except Exception , e :
self . fail ( ' Unable to load invalid model module ' )
s = StringIO ( )
count = management . get_validation_errors ( s , module )
s . seek ( 0 )
error_log = s . read ( )
actual = error_log . split ( ' \n ' )
expected = module . model_errors . split ( ' \n ' )
unexpected = [ err for err in actual if err not in expected ]
missing = [ err for err in expected if err not in actual ]
self . assert_ ( not unexpected , " Unexpected Errors: " + ' \n ' . join ( unexpected ) )
self . assert_ ( not missing , " Missing Errors: " + ' \n ' . join ( missing ) )
def django_tests ( verbosity , tests_to_run ) :
from django . conf import settings
from django . db . models . loading import get_apps , load_app
old_installed_apps = settings . INSTALLED_APPS
# load all the ALWAYS_INSTALLED_APPS
settings . INSTALLED_APPS = ALWAYS_INSTALLED_APPS
get_apps ( )
test_models = [ ]
# Load all the test model apps
for model_dir , model_name in get_test_models ( ) :
model_label = ' . ' . join ( [ model_dir , model_name ] )
try :
# if the model was named on the command line, or
# no models were named (i.e., run all), import
# this model and add it to the list to test.
if not tests_to_run or model_name in tests_to_run :
if verbosity > = 1 :
print " Importing model %s " % model_name
mod = load_app ( model_label )
settings . INSTALLED_APPS . append ( model_label )
test_models . append ( mod )
except Exception , e :
sys . stderr . write ( " Error while importing %s : " % model_name + ' ' . join ( traceback . format_exception ( * sys . exc_info ( ) ) [ 1 : ] ) )
continue
# Add tests for invalid models
extra_tests = [ ]
for model_dir , model_name in get_invalid_models ( ) :
model_label = ' . ' . join ( [ model_dir , model_name ] )
if not tests_to_run or model_name in tests_to_run :
extra_tests . append ( InvalidModelTestCase ( model_label ) )
# Run the test suite, including the extra validation tests.
from django . test . simple import run_tests
run_tests ( test_models , verbosity , extra_tests = extra_tests )
# Restore the old INSTALLED_APPS setting
settings . INSTALLED_APPS = old_installed_apps
2005-07-29 23:15:40 +08:00
if __name__ == " __main__ " :
from optparse import OptionParser
2005-09-19 09:18:04 +08:00
usage = " % prog [options] [model model model ...] "
2006-02-19 04:08:20 +08:00
parser = OptionParser ( usage = usage )
2006-08-27 21:59:47 +08:00
parser . add_option ( ' -v ' , ' --verbosity ' , action = ' store ' , dest = ' verbosity ' , default = ' 0 ' ,
type = ' choice ' , choices = [ ' 0 ' , ' 1 ' , ' 2 ' ] ,
help = ' Verbosity level; 0=minimal output, 1=normal output, 2=all output ' )
2005-08-10 23:36:16 +08:00
parser . add_option ( ' --settings ' ,
2006-01-02 02:37:33 +08:00
help = ' Python path to settings module, e.g. " myproject.settings " . If this isn \' t provided, the DJANGO_SETTINGS_MODULE environment variable will be used. ' )
2005-07-29 23:15:40 +08:00
options , args = parser . parse_args ( )
2005-08-10 23:36:16 +08:00
if options . settings :
os . environ [ ' DJANGO_SETTINGS_MODULE ' ] = options . settings
2006-08-27 21:59:47 +08:00
django_tests ( int ( options . verbosity ) , args )