changeset 0:ff263bdd455e

initial checkin
author Victor Ng <victor@monkeybean.ca>
date Thu, 28 Aug 2008 09:44:43 -0400
parents
children 1a416359a617
files .hgignore AUTHORS Makefile README.txt examples/project/manage.py examples/project/settings.py examples/project/tests/__init__.py examples/project/tests/test_views.py examples/project/urls.py examples/project/zoo/models.py examples/project/zoo/views.py nosedjango/nosedjango.py setup.cfg setup.py
diffstat 14 files changed, 331 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,6 @@
+syntax: glob
+
+*.pyc
+*.egg-info
+build
+dist
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AUTHORS	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,3 @@
+Jason Pellerin
+Bjorn Stabell
+Victor Ng
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,7 @@
+pypi:
+	python setup.py sdist bdist_egg upload -s 
+
+clean:
+	rm -rf dist build *egg-info
+	find . -name "*.pyc" | xargs rm
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.txt	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,18 @@
+Nose django helper plugin
+=========================
+
+nosetests -v --with-django --with-doctest --doctest-tests 
+
+This is a rewrite of Jason Pellerin's original nose-django plugin.
+
+This plugin will work with Django trunk (0.97-pre SVN revision 6669)
+
+Features:
+
+    * automatic settings.py detection in current or parent directory
+    * fixture support
+    * database setup/teardown
+
+Contact: 
+    Victor Ng <crankycoder@gmail.com>
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/project/manage.py	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+from django.core.management import execute_manager
+try:
+    import settings # Assumed to be in the same directory.
+except ImportError:
+    import sys
+    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+    sys.exit(1)
+
+if __name__ == "__main__":
+    execute_manager(settings)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/project/settings.py	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,74 @@
+# Django settings for dtt project.
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3'           # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
+DATABASE_NAME = ':memory:'             # Or path to database file if using sqlite3.
+#DATABASE_USER = ''             # Not used with sqlite3.
+#DATABASE_PASSWORD = ''         # Not used with sqlite3.
+#DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
+#DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
+
+
+# Local time zone for this installation. All choices can be found here:
+# http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
+TIME_ZONE = 'America/Chicago'
+
+# Language code for this installation. All choices can be found here:
+# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
+# http://blogs.law.harvard.edu/tech/stories/storyReader$15
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT.
+# Example: "http://media.lawrence.com"
+MEDIA_URL = ''
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = 'gl6%_ew1u)@)4#^blbji7(25urbdmr82jtov=%i$crckk^t%y@'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.load_template_source',
+    'django.template.loaders.app_directories.load_template_source',
+#     'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.middleware.doc.XViewMiddleware',
+)
+
+ROOT_URLCONF = 'dtt.urls'
+
+TEMPLATE_DIRS = (
+    # Put strings here, like "/home/html/django_templates".
+    # Always use forward slashes, even on Windows.
+)
+
+INSTALLED_APPS = (
+    'django.contrib.contenttypes',
+    'django.contrib.auth',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'project.zoo'
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/project/tests/__init__.py	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,1 @@
+pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/project/tests/test_views.py	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,6 @@
+from django.http import HttpRequest
+from project.zoo import views
+
+def test_view_index():
+    r = views.index(HttpRequest())
+    assert r
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/project/urls.py	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,9 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+    # Example:
+    # (r'^dtt/', include('dtt.apps.foo.urls.foo')),
+
+    # Uncomment this for admin:
+#     (r'^admin/', include('django.contrib.admin.urls')),
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/project/zoo/models.py	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,45 @@
+"""
+Module-level doctest.
+
+    >>> Zoo
+    <class 'project.zoo.models.Zoo'>
+    >>> 1 + 1
+    2
+"""
+from django.db import models
+
+# Create your models here.
+class Zoo(models.Model):
+    """
+    Class-level doctest
+
+    >>> Zoo
+    <class 'project.zoo.models.Zoo'>
+    >>> 1 + 1
+    2
+    >>> Zoo.objects.all()
+    []
+    >>> z = Zoo(name='Bronx')
+    >>> z.save()
+    >>> z
+    <Zoo: Bronx>
+    >>> Zoo.objects.all()
+    [<Zoo: Bronx>]
+    """
+    name = models.CharField(max_length=100)
+
+    def __str__(self):
+        """
+        Function in class test
+        >>> 1 + 2
+        3
+        """
+        return self.name
+
+def func():
+    """
+    Function-level test
+        >>> 1+3
+        4
+    """
+    pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/project/zoo/views.py	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,4 @@
+# Create your views here.
+
+def index(request):
+    return 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nosedjango/nosedjango.py	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,118 @@
+"""
+nose plugin for easy testing of django projects and apps. Sets up a test
+database (or schema) and installs apps from test settings file before tests
+are run, and tears the test database (or schema) down after all tests are run.
+"""
+__author = 'Jason Pellerin'
+__version__ = '0.1'
+
+import atexit
+import logging
+import os, sys
+import re
+
+from nose.plugins import Plugin
+import nose.case
+
+# Force settings.py pointer
+# search the current working directory and all parent directories to find
+# the settings file
+from nose.importer import add_path
+os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
+def get_SETTINGS_PATH():
+    cwd = os.getcwd()
+    while cwd:
+        if 'settings.py' in os.listdir(cwd):
+            break
+        cwd = os.path.split(cwd)[0]
+        if cwd == '/':
+            return None
+    return cwd
+SETTINGS_PATH = get_SETTINGS_PATH()
+
+log = logging.getLogger('nose.plugins.nosedjango')
+
+class NoseDjango(Plugin):
+    """
+    Enable to set up django test environment before running all tests, and
+    tear it down after all tests. If the django database engine in use is not
+    sqlite3, one or both of --django-test-db or django-test-schema must be
+    specified.
+
+    Note that your django project must be on PYTHONPATH for the settings file
+    to be loaded. The plugin will help out by placing the nose working dir
+    into sys.path if it isn't already there, unless the -P
+    (--no-path-adjustment) argument is set.
+    """
+    name = 'django'
+
+    def configure(self, options, conf):
+        Plugin.configure(self, options, conf)
+        self.verbosity = conf.verbosity
+
+    def begin(self):
+        """Create the test database and schema, if needed, and switch the
+        connection over to that database. Then call install() to install
+        all apps listed in the loaded settings module.
+        """
+        # Add the working directory (and any package parents) to sys.path
+        # before trying to import django modules; otherwise, they won't be
+        # able to find project.settings if the working dir is project/ or
+        # project/..
+
+        if not SETTINGS_PATH:
+            sys.stderr.write("Can't find Django settings file!\n")
+            # short circuit if no settings file can be found
+            return
+
+        if self.conf.addPaths:
+            map(add_path, self.conf.where)
+
+        add_path(SETTINGS_PATH)
+        sys.path.append(SETTINGS_PATH)
+        import settings
+        settings.DEBUG = False # I have no idea why Django does this, but it does
+        from django.core import mail
+        self.mail = mail
+        from django.conf import settings
+        from django.core import management
+        from django.test.utils import setup_test_environment
+        from django.db import connection
+
+        self.old_db = settings.DATABASE_NAME
+
+        # setup the test env for each test case
+        setup_test_environment()
+        connection.creation.create_test_db(verbosity=self.verbosity)
+
+        # exit the setup phase and let nose do it's thing
+            
+    def beforeTest(self, test):
+
+        if not SETTINGS_PATH:
+            # short circuit if no settings file can be found
+            return
+
+        from django.core.management import call_command
+        call_command('flush', verbosity=0, interactive=False)
+
+        if isinstance(test, nose.case.Test) and \
+            isinstance(test.test, nose.case.MethodTestCase) and \
+            hasattr(test.context, 'fixtures'):
+                # We have to use this slightly awkward syntax due to the fact
+                # that we're using *args and **kwargs together.
+                call_command('loaddata', *test.context.fixtures, **{'verbosity': 0}) 
+        self.mail.outbox = []
+
+    def finalize(self, result=None):
+        """
+        Clean up any created database and schema.
+        """
+        if not SETTINGS_PATH:
+            # short circuit if no settings file can be found
+            return
+
+        from django.test.utils import teardown_test_environment
+        from django.db import connection
+        connection.creation.destroy_test_db(self.old_db, verbosity=self.verbosity)   
+        teardown_test_environment()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/setup.cfg	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/setup.py	Thu Aug 28 09:44:43 2008 -0400
@@ -0,0 +1,24 @@
+from setuptools import setup, find_packages
+
+setup(
+    name='NoseDjango',
+    version='0.5',
+    author='Victor Ng',
+    author_email = 'victor.ng@monkeybeanonline.com',
+    description = 'nose plugin for easy testing of django projects ' \
+        'and apps. Sets up a test database (or schema) and installs apps ' \
+        'from test settings file before tests are run, and tears the test ' \
+        'database (or schema) down after all tests are run.',
+    install_requires='nose>=0.10',
+    url = "http://poli-cms.googlecode.com/svn/nose-django/",
+    license = 'GNU LGPL',
+    packages = find_packages(exclude=['tests']),
+    zip_safe = False,
+    include_package_data = True,
+    entry_points = {
+        'nose.plugins': [
+            'django = nosedjango.nosedjango:NoseDjango',
+            ]
+        }
+    )
+