Template tags classes work through concatenation and have passing tests for most for everything implemented so far.

This commit is contained in:
xian
2009-04-24 19:08:00 -05:00
parent 53e3d58d02
commit 951430ae10
6 changed files with 172 additions and 3 deletions

View File

@@ -0,0 +1,89 @@
import os
from BeautifulSoup import BeautifulSoup
from django import template
from compressor.conf import settings
register = template.Library()
class CompressedNode(template.Node):
def __init__(self, content, ouput_prefix="compressed"):
self.content = content
self.ouput_prefix = ouput_prefix
self.hunks = []
self.split_content = []
self.soup = BeautifulSoup(self.content)
def content_hash(self):
"""docstring for content_hash"""
pass
def split_contents(self):
raise NotImplementedError('split_contents must be defined in a subclass')
def get_filename(self, url):
if not url.startswith(settings.MEDIA_URL):
# TODO: Put a proper exception here. Maybe one that only shows up
# if debug is on.
raise Exception('FIX THIS EXCPETIONS@!@')
basename = url[len(settings.MEDIA_URL):]
filename = os.path.join(settings.MEDIA_ROOT, basename)
return filename
def get_hunks(self):
if self.hunks:
return self.hunks
for k, v in self.split_contents():
if k == 'hunk':
self.hunks.append(v)
if k == 'file':
fd = open(v, 'rb')
self.hunks.append(fd.read())
fd.close()
return self.hunks
def concat(self):
return "\n".join(self.get_hunks())
def render(self):
if not settings.COMPRESS:
return self.content
return "fail"
class CompressedCssNode(CompressedNode):
def __init__(self, content, ouput_prefix="css", media="all"):
self.media = media
super(CompressedCssNode, self).__init__(content, ouput_prefix)
def split_contents(self):
if self.split_content:
return self.split_content
split = self.soup.findAll({'link' : True, 'style' : True})
for elem in split:
if elem.name == 'link' and elem['rel'] == 'stylesheet':
self.split_content.append(('file', self.get_filename(elem['href'])))
if elem.name == 'style':
self.split_content.append(('hunk', elem.string))
return self.split_content
class CompressedJsNode(CompressedNode):
def __init__(self, content, ouput_prefix="js"):
super(CompressedJsNode, self).__init__(content, ouput_prefix)
def split_contents(self):
if self.split_content:
return self.split_content
split = self.soup.findAll('script')
for elem in split:
if elem.has_key('src'):
self.split_content.append(('file', self.get_filename(elem['src'])))
else:
self.split_content.append(('hunk', elem.string))
return self.split_content

71
tests/core/tests.py Normal file
View File

@@ -0,0 +1,71 @@
import os
from django.test import TestCase
from compressor.templatetags.compress import CompressedCssNode, CompressedJsNode
from compressor.conf import settings
class CompressedNodeTestCase(TestCase):
def setUp(self):
settings.COMPRESS = True
self.css = """
<link rel="stylesheet" href="/media/css/one.css" type="text/css" media="screen" charset="utf-8">
<style type="text/css" media="screen">p { border:5px solid green;}</style>
<link rel="stylesheet" href="/media/css/two.css" type="text/css" media="screen" charset="utf-8">
"""
self.css_output = '<link rel="stylesheet" href="/media/compressed/cssHASH.css" type="text/css" media="all" charset="utf-8">'
self.cssNode = CompressedCssNode(self.css)
self.js = """
<script src="/media/js/one.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">obj.value = "value";</script>
"""
self.js_output = '<script src="/media/compressed/jsHASH.js" charset="utf-8"></script>'
self.jsNode = CompressedJsNode(self.js)
def test_css_split(self):
out = [
('file', os.path.join(settings.MEDIA_ROOT, u'css/one.css')),
('hunk', u'p { border:5px solid green;}'),
('file', os.path.join(settings.MEDIA_ROOT, u'css/two.css')),
]
self.assertEqual(out, self.cssNode.split_contents())
def test_css_hunks(self):
out = ['body { background:#990; }', u'p { border:5px solid green;}', 'body { color:#fff; }']
self.assertEqual(out, self.cssNode.get_hunks())
def test_css_concat(self):
out = u'body { background:#990; }\np { border:5px solid green;}\nbody { color:#fff; }'
self.assertEqual(out, self.cssNode.concat())
def test_css_return_if_off(self):
settings.COMPRESS = False
self.assertEqual(self.css, self.cssNode.render())
def test_css_return_if_on(self):
self.assertEqual(self.css_output, self.cssNode.render())
def test_js_split(self):
out = [
('file', os.path.join(settings.MEDIA_ROOT, u'js/one.js')),
('hunk', u'obj.value = "value";'),
]
self.assertEqual(out, self.jsNode.split_contents())
def test_js_hunks(self):
out = ['obj = {};', u'obj.value = "value";']
self.assertEqual(out, self.jsNode.get_hunks())
def test_js_concat(self):
out = u'obj = {};\nobj.value = "value";'
self.assertEqual(out, self.jsNode.concat())
def test_js_return_if_off(self):
settings.COMPRESS = False
self.assertEqual(self.js, self.jsNode.render())
def test_js_return_if_on(self):
self.assertEqual(self.js_output, self.jsNode.render())

1
tests/media/css/one.css Normal file
View File

@@ -0,0 +1 @@
body { background:#990; }

1
tests/media/css/two.css Normal file
View File

@@ -0,0 +1 @@
body { color:#fff; }

1
tests/media/js/one.js Normal file
View File

@@ -0,0 +1 @@
obj = {};

View File

@@ -1,20 +1,26 @@
import sys
from os.path import dirname, abspath, join
TEST_DIR = [dirname(abspath(__file__))]
TEST_DIR = dirname(abspath(__file__))
DEBUG = True
XDADD = ""
ROOT_URLCONF = 'urls'
MEDIA_URL = '/media/'
MEDIA_ROOT = join(TEST_DIR, 'media')
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'django_inlines_tests.db'
INSTALLED_APPS = [
'core',
'django-compress',
'compressor',
]
TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.load_template_source',
)
TEMPLATE_DIRS = (
join (TEST_DIR, 'templates'),
join(TEST_DIR, 'templates'),
)