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,15 +1,21 @@ | ||||
| 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', | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 xian
					xian