Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added tests.builddocs, which builds HTML documentation by introspecti…

…ng the model unit tests

git-svn-id: http://code.djangoproject.com/svn/django/trunk@348 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 5002b44f2872f87785d34eee6f2cc9e7d410a797 1 parent 47ce615
Adrian Holovaty adrianholovaty authored
65 tests/builddocs.py
View
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+"""
+This module builds HTML documentation for models by introspecting the model
+unit tests.
+"""
+
+from django.core import meta, template
+import runtests
+import inspect, os, re, sys
+
+MODEL_DOC_TEMPLATE = """
+<div class="document" id="model-{{ model_name }}">
+
+<h1 class="title">{{ title }}</h1>
+{{ blurb }}
+
+<h2>Model source code</h2>
+<pre>{{ model_source }}</pre>
+
+<h2>Sample API usage</h2>
+<pre>{{ api_usage }}</pre>
+</div>
+"""
+
+def make_docs_from_model_tests(output_dir):
+ from django.conf import settings
+
+ # Manually set INSTALLED_APPS to point to the test app.
+ settings.INSTALLED_APPS = (runtests.APP_NAME,)
+
+ for model_name in runtests.get_test_models():
+ mod = meta.get_app(model_name)
+
+ # Clean up the title and blurb.
+ title, blurb = mod.__doc__.strip().split('\n', 1)
+ blurb = '<p>%s</p>' % blurb.strip().replace('\n\n', '</p><p>')
+ api_usage = mod.API_TESTS
+
+ # Get the source code of the model, without the docstring or the
+ # API_TESTS variable.
+ model_source = inspect.getsource(mod)
+ model_source = model_source.replace(mod.__doc__, '')
+ model_source = model_source.replace(mod.API_TESTS, '')
+ model_source = model_source.replace('""""""\n', '\n')
+ model_source = model_source.replace('API_TESTS = ', '')
+ model_source = model_source.strip()
+
+ # Run this through the template system.
+ t = template.Template(MODEL_DOC_TEMPLATE)
+ c = template.Context(locals())
+ html = t.render(c)
+
+ file_name = os.path.join(output_dir, 'model_' + model_name + '.html')
+ try:
+ fp = open(file_name, 'w')
+ except IOError:
+ sys.stderr.write("Couldn't write to %s.\n" % file_name)
+ continue
+ else:
+ fp.write(html)
+ fp.close()
+
+if __name__ == "__main__":
+ import sys
+ make_docs_from_model_tests(sys.argv[1])
27 tests/runtests.py
View
@@ -17,6 +17,11 @@ def log_error(model_name, title, description):
'description': description,
})
+MODEL_DIR = os.path.join(os.path.dirname(__file__), APP_NAME, 'models')
+
+def get_test_models():
+ return [f[:-3] for f in os.listdir(MODEL_DIR) if f.endswith('.py') and not f.startswith('__init__')]
+
class DjangoDoctestRunner(doctest.DocTestRunner):
def __init__(self, verbosity_level, *args, **kwargs):
self.verbosity_level = verbosity_level
@@ -51,13 +56,15 @@ def run_tests(self):
# Manually set INSTALLED_APPS to point to the test app.
settings.INSTALLED_APPS = (APP_NAME,)
- # If we're using SQLite, it's more convient to test against an in-memory database
+ # If we're using SQLite, it's more convenient to test against an
+ # in-memory database.
if settings.DATABASE_ENGINE == "sqlite3":
global TEST_DATABASE_NAME
TEST_DATABASE_NAME = ":memory:"
- else:
- # Create the test database and connect to it. We need autocommit() because
- # PostgreSQL doesn't allow CREATE DATABASE statements within transactions.
+ else:
+ # Create the test database and connect to it. We need autocommit()
+ # because PostgreSQL doesn't allow CREATE DATABASE statements
+ # within transactions.
cursor = db.cursor()
try:
db.connection.autocommit()
@@ -83,10 +90,8 @@ def run_tests(self):
self.output(1, "Initializing test database")
management.init()
- # Run the tests for each model within APP_NAME/models.
- model_dir = os.path.join(os.path.dirname(__file__), APP_NAME, 'models')
- test_models = [f[:-3] for f in os.listdir(model_dir) if f.endswith('.py') and not f.startswith('__init__')]
- for model_name in test_models:
+ # Run the tests for each test model.
+ for model_name in get_test_models():
self.output(1, "%s model: Importing" % model_name)
try:
mod = meta.get_app(model_name)
@@ -106,9 +111,9 @@ def run_tests(self):
self.output(1, "%s model: Running tests" % model_name)
runner.run(dtest, clear_globs=True, out=sys.stdout.write)
- # Unless we're using SQLite, remove the test database, to clean up after
- # ourselves. Connect to the previous database (not the test database)
- # to do so, because it's not allowed to delete a database while being
+ # Unless we're using SQLite, remove the test database to clean up after
+ # ourselves. Connect to the previous database (not the test database)
+ # to do so, because it's not allowed to delete a database while being
# connected to it.
if settings.DATABASE_ENGINE != "sqlite3":
db.close()
1  tests/testapp/models/lookup.py
View
@@ -1,6 +1,7 @@
"""
7. The lookup API
+This demonstrates features of the database API.
"""
from django.core import meta
Please sign in to comment.
Something went wrong with that request. Please try again.