Skip to content

Commit 6e2a7e7

Browse files
committed
Initial commit
0 parents  commit 6e2a7e7

27 files changed

+384
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.pyc
2+
chromedriver.log
3+
coverage

fabfile.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""Fabfile for the ``myproject`` project."""
2+
from fabric.api import local
3+
4+
5+
def test(integration=1):
6+
command = './manage.py test -v 2 --settings=myproject.test_settings'
7+
if int(integration) == 0:
8+
command += " --exclude='integration_tests'"
9+
local(command)

manage.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env python
2+
import os
3+
import sys
4+
5+
if __name__ == "__main__":
6+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
7+
8+
from django.core.management import execute_from_command_line
9+
10+
execute_from_command_line(sys.argv)

myapp/__init__.py

Whitespace-only changes.

myapp/models.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""Models for the ``myapp`` app."""
2+
from django.db import models
3+
4+
5+
class Entry(models.Model):
6+
"""A comment entry."""
7+
user = models.ForeignKey('auth.User')
8+
message = models.TextField()

myapp/templates/myapp/entry_detail.html

Whitespace-only changes.

myapp/templates/myapp/home.html

Whitespace-only changes.

myapp/tests/__init__.py

Whitespace-only changes.

myapp/tests/factories.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
"""Factories for the ``myapp`` app."""
2+
import factory
3+
4+
from myapp.models import Entry
5+
from myproject.tests.factories import UserFactory
6+
7+
8+
class EntryFactory(factory.Factory):
9+
FACTORY_FOR = Entry
10+
11+
user = factory.SubFactory(UserFactory)
12+
message = 'A message'

myapp/tests/integration_tests/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Tests for the views of the ``myapp`` app."""
2+
from django.test import TestCase
3+
from django.core.urlresolvers import reverse
4+
5+
from myapp.tests.factories import EntryFactory
6+
7+
8+
class HomeViewTestCase(TestCase):
9+
"""Tests for the ``HomeView`` generic view class."""
10+
def get_view_name(self):
11+
return 'home'
12+
13+
def test_view(self):
14+
resp = self.client.get(reverse(self.get_view_name()))
15+
self.assertEqual(resp.status_code, 200)
16+
17+
18+
class EntryDetailViewTestCase(TestCase):
19+
"""Tests for the ``EntryDetailView`` generic view class."""
20+
def setUp(self):
21+
self.entry = EntryFactory()
22+
23+
def get_view_name(self):
24+
return 'entry_detail'
25+
26+
def get_view_kwargs(self):
27+
return {'pk': self.entry.pk}
28+
29+
def test_view(self):
30+
resp = self.client.get(reverse(self.get_view_name(),
31+
kwargs=self.get_view_kwargs()))
32+
self.assertEqual(resp.status_code, 200)

myapp/tests/models_tests.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"""Tests for the models of the ``myapp`` app."""
2+
from django.test import TestCase
3+
4+
from myapp.tests.factories import EntryFactory
5+
6+
7+
class EntryTestCase(TestCase):
8+
"""Tests for the ``Entry`` model class."""
9+
def test_model(self):
10+
entry = EntryFactory()
11+
self.assertTrue(entry.pk)

myapp/urls.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from django.conf.urls import patterns, url
2+
3+
from myapp.views import HomeView, EntryDetailView
4+
5+
6+
urlpatterns = patterns('',
7+
url(r'^$', HomeView.as_view(), name='home'),
8+
9+
url(r'^/entries/(?P<pk>\d+)/$', EntryDetailView.as_view(),
10+
name='entry_detail'),
11+
)

myapp/views.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
"""Views for the ``myapp`` app."""
2+
from django.views.generic import TemplateView, DetailView
3+
4+
from myapp.models import Entry
5+
6+
7+
class HomeView(TemplateView):
8+
template_name = 'myapp/home.html'
9+
10+
11+
class EntryDetailView(DetailView):
12+
model = Entry

myproject/__init__.py

Whitespace-only changes.

myproject/settings.py

+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Django settings for myproject project.
2+
import os
3+
4+
DEBUG = False
5+
TEMPLATE_DEBUG = DEBUG
6+
7+
ADMINS = (
8+
# ('Your Name', '[email protected]'),
9+
)
10+
11+
MANAGERS = ADMINS
12+
13+
DATABASES = {
14+
'default': {
15+
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
16+
'NAME': 'db.sqlite', # Or path to database file if using sqlite3.
17+
'USER': '', # Not used with sqlite3.
18+
'PASSWORD': '', # Not used with sqlite3.
19+
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
20+
'PORT': '', # Set to empty string for default. Not used with sqlite3.
21+
}
22+
}
23+
24+
# Local time zone for this installation. Choices can be found here:
25+
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
26+
# although not all choices may be available on all operating systems.
27+
# On Unix systems, a value of None will cause Django to use the same
28+
# timezone as the operating system.
29+
# If running in a Windows environment this must be set to the same as your
30+
# system time zone.
31+
TIME_ZONE = 'America/Chicago'
32+
33+
# Language code for this installation. All choices can be found here:
34+
# http://www.i18nguy.com/unicode/language-identifiers.html
35+
LANGUAGE_CODE = 'en-us'
36+
37+
SITE_ID = 1
38+
39+
# If you set this to False, Django will make some optimizations so as not
40+
# to load the internationalization machinery.
41+
USE_I18N = True
42+
43+
# If you set this to False, Django will not format dates, numbers and
44+
# calendars according to the current locale.
45+
USE_L10N = True
46+
47+
# If you set this to False, Django will not use timezone-aware datetimes.
48+
USE_TZ = True
49+
50+
# Absolute filesystem path to the directory that will hold user-uploaded files.
51+
# Example: "/home/media/media.lawrence.com/media/"
52+
MEDIA_ROOT = ''
53+
54+
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
55+
# trailing slash.
56+
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
57+
MEDIA_URL = ''
58+
59+
# Absolute path to the directory static files should be collected to.
60+
# Don't put anything in this directory yourself; store your static files
61+
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
62+
# Example: "/home/media/media.lawrence.com/static/"
63+
STATIC_ROOT = ''
64+
65+
# URL prefix for static files.
66+
# Example: "http://media.lawrence.com/static/"
67+
STATIC_URL = '/static/'
68+
69+
# Additional locations of static files
70+
STATICFILES_DIRS = (
71+
# Put strings here, like "/home/html/static" or "C:/www/django/static".
72+
# Always use forward slashes, even on Windows.
73+
# Don't forget to use absolute paths, not relative paths.
74+
)
75+
76+
# List of finder classes that know how to find static files in
77+
# various locations.
78+
STATICFILES_FINDERS = (
79+
'django.contrib.staticfiles.finders.FileSystemFinder',
80+
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
81+
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
82+
)
83+
84+
# Make this unique, and don't share it with anybody.
85+
SECRET_KEY = '4m9m-r0b+ehvjk=((dmh!9-$_v#n71xheol%%1-d&amp;p3o!4llj7'
86+
87+
# List of callables that know how to import templates from various sources.
88+
TEMPLATE_LOADERS = (
89+
'django.template.loaders.filesystem.Loader',
90+
'django.template.loaders.app_directories.Loader',
91+
'django.template.loaders.eggs.Loader',
92+
)
93+
94+
MIDDLEWARE_CLASSES = (
95+
'django.middleware.common.CommonMiddleware',
96+
'django.contrib.sessions.middleware.SessionMiddleware',
97+
'django.middleware.csrf.CsrfViewMiddleware',
98+
'django.contrib.auth.middleware.AuthenticationMiddleware',
99+
'django.contrib.messages.middleware.MessageMiddleware',
100+
# Uncomment the next line for simple clickjacking protection:
101+
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
102+
)
103+
104+
ROOT_URLCONF = 'myproject.urls'
105+
106+
# Python dotted path to the WSGI application used by Django's runserver.
107+
WSGI_APPLICATION = 'myproject.wsgi.application'
108+
109+
TEMPLATE_DIRS = (
110+
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
111+
# Always use forward slashes, even on Windows.
112+
# Don't forget to use absolute paths, not relative paths.
113+
os.path.join(os.path.dirname(__file__), 'templates'),
114+
)
115+
116+
EXTERNAL_APPS = [
117+
'django.contrib.auth',
118+
'django.contrib.contenttypes',
119+
'django.contrib.sessions',
120+
'django.contrib.sites',
121+
'django.contrib.messages',
122+
'django.contrib.staticfiles',
123+
# Uncomment the next line to enable the admin:
124+
# 'django.contrib.admin',
125+
# Uncomment the next line to enable admin documentation:
126+
# 'django.contrib.admindocs',
127+
]
128+
129+
INTERNAL_APPS = [
130+
'myapp',
131+
]
132+
133+
INSTALLED_APPS = EXTERNAL_APPS + INTERNAL_APPS
134+
135+
# A sample logging configuration. The only tangible logging
136+
# performed by this configuration is to send an email to
137+
# the site admins on every HTTP 500 error when DEBUG=False.
138+
# See http://docs.djangoproject.com/en/dev/topics/logging for
139+
# more details on how to customize your logging configuration.
140+
LOGGING = {
141+
'version': 1,
142+
'disable_existing_loggers': False,
143+
'filters': {
144+
'require_debug_false': {
145+
'()': 'django.utils.log.RequireDebugFalse'
146+
}
147+
},
148+
'handlers': {
149+
'mail_admins': {
150+
'level': 'ERROR',
151+
'filters': ['require_debug_false'],
152+
'class': 'django.utils.log.AdminEmailHandler'
153+
}
154+
},
155+
'loggers': {
156+
'django.request': {
157+
'handlers': ['mail_admins'],
158+
'level': 'ERROR',
159+
'propagate': True,
160+
},
161+
}
162+
}

myproject/static/robots.txt

Whitespace-only changes.

myproject/templates/404.html

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
404

myproject/templates/500.html

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
500

myproject/templates/base.html

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{% block main %}{% endblock %}

myproject/test_settings.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# flake8: noqa
2+
"""Settings to be used for running tests."""
3+
import os
4+
5+
from myproject.settings import *
6+
7+
8+
INSTALLED_APPS.append('django_nose')
9+
10+
DATABASES = {
11+
"default": {
12+
"ENGINE": "django.db.backends.sqlite3",
13+
"NAME": ":memory:",
14+
}
15+
}
16+
17+
PASSWORD_HASHERS = (
18+
'django.contrib.auth.hashers.MD5PasswordHasher',
19+
)
20+
21+
22+
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
23+
SOUTH_TESTS_MIGRATE = False
24+
25+
TEST_RUNNER = 'myproject.testrunner.NoseCoverageTestRunner'
26+
COVERAGE_MODULE_EXCLUDES = [
27+
'tests$', 'settings$', 'urls$', 'locale$',
28+
'migrations', 'fixtures', 'admin$', 'django_extensions',
29+
]
30+
COVERAGE_MODULE_EXCLUDES += EXTERNAL_APPS
31+
COVERAGE_REPORT_HTML_OUTPUT_DIR = os.path.join(__file__, '../../coverage')

myproject/testrunner.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""Custom test runner for the project."""
2+
from django_coverage.coverage_runner import CoverageRunner
3+
from django_nose import NoseTestSuiteRunner
4+
5+
6+
class NoseCoverageTestRunner(CoverageRunner, NoseTestSuiteRunner):
7+
"""Custom test runner that uses nose and coverage"""
8+
pass

myproject/tests/__init__.py

Whitespace-only changes.

myproject/tests/factories.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Factories for models that are global to the project."""
2+
from django.contrib.auth.models import User
3+
4+
import factory
5+
6+
7+
class UserFactory(factory.Factory):
8+
"""
9+
Creates a new ``User`` object.
10+
11+
Username will be a random 30 character md5 value.
12+
Email will be ``[email protected]`` with ``N`` being a counter.
13+
Password will be ``test123`` by default.
14+
15+
"""
16+
FACTORY_FOR = User
17+
18+
username = factory.Sequence(lambda n: 'username{0}'.format(n))
19+
email = factory.Sequence(lambda n: 'user{0}@example.com'.format(n))
20+
21+
@classmethod
22+
def _prepare(cls, create, **kwargs):
23+
password = 'test123'
24+
if 'password' in kwargs:
25+
password = kwargs.pop('password')
26+
user = super(UserFactory, cls)._prepare(create, **kwargs)
27+
user.set_password(password)
28+
if create:
29+
user.save()
30+
return user

myproject/urls.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.conf.urls import patterns, include, url
2+
3+
4+
urlpatterns = patterns('',
5+
url(r'^myapp/', include('myapp.urls')),
6+
)

myproject/wsgi.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
WSGI config for myproject project.
3+
4+
This module contains the WSGI application used by Django's development server
5+
and any production WSGI deployments. It should expose a module-level variable
6+
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
7+
this application via the ``WSGI_APPLICATION`` setting.
8+
9+
Usually you will have the standard Django WSGI application here, but it also
10+
might make sense to replace the whole Django WSGI application with a custom one
11+
that later delegates to the Django one. For example, you could introduce WSGI
12+
middleware here, or combine a Django application with an application of another
13+
framework.
14+
15+
"""
16+
import os
17+
18+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
19+
20+
# This application object is used by any WSGI server configured to use this
21+
# file. This includes Django's development server, if the WSGI_APPLICATION
22+
# setting points here.
23+
from django.core.wsgi import get_wsgi_application
24+
application = get_wsgi_application()
25+
26+
# Apply WSGI middleware here.
27+
# from helloworld.wsgi import HelloWorldApplication
28+
# application = HelloWorldApplication(application)

0 commit comments

Comments
 (0)