Template tags classes work through concatenation and have passing tests for most for everything implemented so far.
This commit is contained in:
		| @@ -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
									
								
							
							
						
						
									
										71
									
								
								tests/core/tests.py
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										1
									
								
								tests/media/css/one.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | body { background:#990; } | ||||||
							
								
								
									
										1
									
								
								tests/media/css/two.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/media/css/two.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | body { color:#fff; } | ||||||
							
								
								
									
										1
									
								
								tests/media/js/one.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/media/js/one.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | obj = {}; | ||||||
| @@ -1,20 +1,26 @@ | |||||||
| import sys | import sys | ||||||
| from os.path import dirname, abspath, join | from os.path import dirname, abspath, join | ||||||
| TEST_DIR = [dirname(abspath(__file__))] | TEST_DIR = dirname(abspath(__file__)) | ||||||
|  |  | ||||||
|  | DEBUG = True | ||||||
|  | XDADD = "" | ||||||
|  |  | ||||||
| ROOT_URLCONF = 'urls' | ROOT_URLCONF = 'urls' | ||||||
|  |  | ||||||
|  | MEDIA_URL = '/media/' | ||||||
|  | MEDIA_ROOT = join(TEST_DIR, 'media') | ||||||
|  |  | ||||||
| DATABASE_ENGINE = 'sqlite3' | DATABASE_ENGINE = 'sqlite3' | ||||||
| DATABASE_NAME = 'django_inlines_tests.db' | DATABASE_NAME = 'django_inlines_tests.db' | ||||||
|   |   | ||||||
| INSTALLED_APPS = [ | INSTALLED_APPS = [ | ||||||
|     'core', |     'core', | ||||||
|     'django-compress', |     'compressor', | ||||||
| ] | ] | ||||||
| TEMPLATE_LOADERS = ( | TEMPLATE_LOADERS = ( | ||||||
|     'django.template.loaders.app_directories.load_template_source', |     'django.template.loaders.app_directories.load_template_source', | ||||||
| ) | ) | ||||||
|  |  | ||||||
| TEMPLATE_DIRS = ( | TEMPLATE_DIRS = ( | ||||||
|     join (TEST_DIR, 'templates'), |     join(TEST_DIR, 'templates'), | ||||||
| ) | ) | ||||||
		Reference in New Issue
	
	Block a user
	 xian
					xian