deb-python-django-overextends/overextends/tests.py

112 lines
4.0 KiB
Python

from __future__ import with_statement
import os
from shutil import rmtree
import sys
from uuid import uuid4
from django.conf import settings
from django.template import Context
from django.template.loader import get_template
from django.test import TestCase
TEST_TEMPLATE = """
{# avast ye mateys #}
%(extends_string)s
{%% block main %%}
%(super_string)s
%(test_string)s
{%% endblock %%}
"""
class Tests(TestCase):
"""
Test that ``overextends`` triggers across multiple project and
app templates with the same relative path. To achieve this, we
need the same template name to exist in multiple apps, as well as
at the project level, so we create some fake apps and a project
template. These all used a unique ID to ensure they don't
collide with anything in the project. When we're done, we clean
up our mess.
"""
def setUp(self):
"""
Put the test template into a couple of test apps and the project.
"""
self.root = os.path.dirname(__import__(settings.ROOT_URLCONF).__file__)
sys.path.append(self.root)
# Add the test apps to INSTALLED_APPS.
self.unique_id = str(uuid4()).replace("-", "")
self.test_apps = ["app%s%s" % (i, self.unique_id) for i in range(10)]
# Create the app directories with the test template.
for test_app in self.test_apps:
app_dir = os.path.join(self.root, test_app)
os.mkdir(app_dir)
app_templates = os.path.join(app_dir, "templates")
os.mkdir(app_templates)
with open(os.path.join(app_dir, "__init__.py"), "w") as f:
f.write("")
extends = test_app != self.test_apps[-1]
self._create_template(app_templates, test_app, extends)
# Add the test template to the project, and store a flag
# indicating whether or not the project templates directory
# existed, so if it does, we can leave it in place when we
# clean everything up.
project_templates = os.path.join(self.root, "templates")
self.project_templates_exist = os.path.exists(project_templates)
if not self.project_templates_exist:
os.mkdir(project_templates)
self._create_template(project_templates, "project", True)
def _create_template(self, template_dir, test_string, extends):
"""
Creates the test template in the given template directory, with
the test string injected that we'll use for the real test.
"""
with open(os.path.join(template_dir, self.unique_id), "w") as f:
template_vars = {
"test_string": test_string,
"extends_string": "",
"super_string": "",
}
if extends:
extends_string = "{%% overextends \"%s\" %%}" % self.unique_id
template_vars["extends_string"] = extends_string
template_vars["super_string"] = "{{ block.super }}"
f.write((TEST_TEMPLATE % template_vars).strip())
def test_overextends(self):
"""
Ensure the test string appear in the rendered template.
"""
with self.modify_settings(INSTALLED_APPS={
'prepend': self.test_apps
}):
html = get_template(self.unique_id).render(Context())
previous = ""
for test_string in ["project"] + self.test_apps:
self.assertTrue(test_string in html)
if previous:
self.assertTrue(html.index(test_string) < html.index(previous))
previous = test_string
def tearDown(self):
"""
Delete all the temp files and directories we created in ``setUp``.
"""
for test_app in self.test_apps:
rmtree(os.path.join(self.root, test_app))
if self.project_templates_exist:
os.remove(os.path.join(self.root, "templates", self.unique_id))
else:
rmtree(os.path.join(self.root, "templates"))