def test_css_output_with_bom_input(self): out = 'body { background:#990; }\n.compress-test {color: red;}' css = ("""<link rel="stylesheet" href="/static/css/one.css" type="text/css" /> <link rel="stylesheet" href="/static/css/utf-8_with-BOM.css" type="text/css" />""") css_node_with_bom = CssCompressor(css) hunks = '\n'.join([h for h in css_node_with_bom.hunks()]) self.assertEqual(out, hunks)
def test_css_hunks(self): hash_python_png = self.hashing_func(os.path.join(settings.COMPRESS_ROOT, 'img/python.png')) hash_add_png = self.hashing_func(os.path.join(settings.COMPRESS_ROOT, 'img/add.png')) css1 = """\ p { background: url('%(compress_url)simg/python.png?%(hash)s'); } p { background: url(%(compress_url)simg/python.png?%(hash)s); } p { background: url(%(compress_url)simg/python.png?%(hash)s); } p { background: url('%(compress_url)simg/python.png?%(hash)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%(compress_url)simg/python.png?%(hash)s'); } """ % dict(compress_url=self.expected_url_prefix, hash=hash_python_png) css2 = """\ p { background: url('%(compress_url)simg/add.png?%(hash)s'); } p { background: url(%(compress_url)simg/add.png?%(hash)s); } p { background: url(%(compress_url)simg/add.png?%(hash)s); } p { background: url('%(compress_url)simg/add.png?%(hash)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%(compress_url)simg/add.png?%(hash)s'); } """ % dict(compress_url=self.expected_url_prefix, hash=hash_add_png) css = """ <link rel="stylesheet" href="/static/css/url/url1.css" type="text/css"> <link rel="stylesheet" href="/static/css/url/2/url2.css" type="text/css"> """ css_node = CssCompressor(css) self.assertEqual([css1, css2], list(css_node.hunks()))
class CssDataUriTestCase(TestCase): def setUp(self): settings.COMPRESS_ENABLED = True settings.COMPRESS_CSS_FILTERS = [ 'compressor.filters.css_default.CssAbsoluteFilter', 'compressor.filters.datauri.CssDataUriFilter', ] settings.COMPRESS_URL = '/static/' settings.COMPRESS_CSS_HASHING_METHOD = 'mtime' self.css = """ <link rel="stylesheet" href="/static/css/datauri.css" type="text/css"> """ self.css_node = CssCompressor(self.css) def test_data_uris(self): datauri_hash = get_hashed_mtime( os.path.join(settings.COMPRESS_ROOT, 'img/python.png')) out = [ u'''.add { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJvSURBVDjLpZPrS5NhGIf9W7YvBYOkhlkoqCklWChv2WyKik7blnNris72bi6dus0DLZ0TDxW1odtopDs4D8MDZuLU0kXq61CijSIIasOvv94VTUfLiB74fXngup7nvrnvJABJ/5PfLnTTdcwOj4RsdYmo5glBWP6iOtzwvIKSWstI0Wgx80SBblpKtE9KQs/We7EaWoT/8wbWP61gMmCH0lMDvokT4j25TiQU/ITFkek9Ow6+7WH2gwsmahCPdwyw75uw9HEO2gUZSkfyI9zBPCJOoJ2SMmg46N61YO/rNoa39Xi41oFuXysMfh36/Fp0b7bAfWAH6RGi0HglWNCbzYgJaFjRv6zGuy+b9It96N3SQvNKiV9HvSaDfFEIxXItnPs23BzJQd6DDEVM0OKsoVwBG/1VMzpXVWhbkUM2K4oJBDYuGmbKIJ0qxsAbHfRLzbjcnUbFBIpx/qH3vQv9b3U03IQ/HfFkERTzfFj8w8jSpR7GBE123uFEYAzaDRIqX/2JAtJbDat/COkd7CNBva2cMvq0MGxp0PRSCPF8BXjWG3FgNHc9XPT71Ojy3sMFdfJRCeKxEsVtKwFHwALZfCUk3tIfNR8XiJwc1LmL4dg141JPKtj3WUdNFJqLGFVPC4OkR4BxajTWsChY64wmCnMxsWPCHcutKBxMVp5mxA1S+aMComToaqTRUQknLTH62kHOVEE+VQnjahscNCy0cMBWsSI0TCQcZc5ALkEYckL5A5noWSBhfm2AecMAjbcRWV0pUTh0HE64TNf0mczcnnQyu/MilaFJCae1nw2fbz1DnVOxyGTlKeZft/Ff8x1BRssfACjTwQAAAABJRU5ErkJggg=="); } .add-with-hash { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJvSURBVDjLpZPrS5NhGIf9W7YvBYOkhlkoqCklWChv2WyKik7blnNris72bi6dus0DLZ0TDxW1odtopDs4D8MDZuLU0kXq61CijSIIasOvv94VTUfLiB74fXngup7nvrnvJABJ/5PfLnTTdcwOj4RsdYmo5glBWP6iOtzwvIKSWstI0Wgx80SBblpKtE9KQs/We7EaWoT/8wbWP61gMmCH0lMDvokT4j25TiQU/ITFkek9Ow6+7WH2gwsmahCPdwyw75uw9HEO2gUZSkfyI9zBPCJOoJ2SMmg46N61YO/rNoa39Xi41oFuXysMfh36/Fp0b7bAfWAH6RGi0HglWNCbzYgJaFjRv6zGuy+b9It96N3SQvNKiV9HvSaDfFEIxXItnPs23BzJQd6DDEVM0OKsoVwBG/1VMzpXVWhbkUM2K4oJBDYuGmbKIJ0qxsAbHfRLzbjcnUbFBIpx/qH3vQv9b3U03IQ/HfFkERTzfFj8w8jSpR7GBE123uFEYAzaDRIqX/2JAtJbDat/COkd7CNBva2cMvq0MGxp0PRSCPF8BXjWG3FgNHc9XPT71Ojy3sMFdfJRCeKxEsVtKwFHwALZfCUk3tIfNR8XiJwc1LmL4dg141JPKtj3WUdNFJqLGFVPC4OkR4BxajTWsChY64wmCnMxsWPCHcutKBxMVp5mxA1S+aMComToaqTRUQknLTH62kHOVEE+VQnjahscNCy0cMBWsSI0TCQcZc5ALkEYckL5A5noWSBhfm2AecMAjbcRWV0pUTh0HE64TNf0mczcnnQyu/MilaFJCae1nw2fbz1DnVOxyGTlKeZft/Ff8x1BRssfACjTwQAAAABJRU5ErkJggg=="); } .python { background-image: url("/static/img/python.png?%s"); } .datauri { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0 vr4MkhoXe0rZigAAAABJRU5ErkJggg=="); } ''' % datauri_hash ] self.assertEqual(out, list(self.css_node.hunks()))
def test_css_hunks(self): hash_python_png = self.hashing_func( os.path.join(settings.COMPRESS_ROOT, 'img/python.png')) hash_add_png = self.hashing_func( os.path.join(settings.COMPRESS_ROOT, 'img/add.png')) css1 = """\ p { background: url('%(compress_url)simg/python.png?%(hash)s'); } p { background: url(%(compress_url)simg/python.png?%(hash)s); } p { background: url(%(compress_url)simg/python.png?%(hash)s); } p { background: url('%(compress_url)simg/python.png?%(hash)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%(compress_url)simg/python.png?%(hash)s'); } """ % dict(compress_url=self.expected_url_prefix, hash=hash_python_png) css2 = """\ p { background: url('%(compress_url)simg/add.png?%(hash)s'); } p { background: url(%(compress_url)simg/add.png?%(hash)s); } p { background: url(%(compress_url)simg/add.png?%(hash)s); } p { background: url('%(compress_url)simg/add.png?%(hash)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%(compress_url)simg/add.png?%(hash)s'); } """ % dict(compress_url=self.expected_url_prefix, hash=hash_add_png) css = """ <link rel="stylesheet" href="/static/css/url/url1.css" type="text/css"> <link rel="stylesheet" href="/static/css/url/2/url2.css" type="text/css"> """ css_node = CssCompressor('css', css) self.assertEqual([css1, css2], list(css_node.hunks()))
def helper(self, enabled, use_precompiler, use_absolute_filter, expected_output): precompiler = (('text/css', 'compressor.tests.test_base.PassthroughPrecompiler'),) if use_precompiler else () filters = ('compressor.filters.css_default.CssAbsoluteFilter',) if use_absolute_filter else () with self.settings(COMPRESS_ENABLED=enabled, COMPRESS_PRECOMPILERS=precompiler, COMPRESS_CSS_FILTERS=filters): css_node = CssCompressor(self.html_orig) output = list(css_node.hunks())[0] self.assertEqual(output, expected_output)
class CssDataUriTestCase(TestCase): def setUp(self): self.css = """ <link rel="stylesheet" href="/static/css/datauri.css" type="text/css"> """ self.css_node = CssCompressor(self.css) def test_data_uris(self): datauri_hash = get_hashed_mtime(os.path.join(settings.COMPRESS_ROOT, 'img/python.png')) out = ['''.add { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJvSURBVDjLpZPrS5NhGIf9W7YvBYOkhlkoqCklWChv2WyKik7blnNris72bi6dus0DLZ0TDxW1odtopDs4D8MDZuLU0kXq61CijSIIasOvv94VTUfLiB74fXngup7nvrnvJABJ/5PfLnTTdcwOj4RsdYmo5glBWP6iOtzwvIKSWstI0Wgx80SBblpKtE9KQs/We7EaWoT/8wbWP61gMmCH0lMDvokT4j25TiQU/ITFkek9Ow6+7WH2gwsmahCPdwyw75uw9HEO2gUZSkfyI9zBPCJOoJ2SMmg46N61YO/rNoa39Xi41oFuXysMfh36/Fp0b7bAfWAH6RGi0HglWNCbzYgJaFjRv6zGuy+b9It96N3SQvNKiV9HvSaDfFEIxXItnPs23BzJQd6DDEVM0OKsoVwBG/1VMzpXVWhbkUM2K4oJBDYuGmbKIJ0qxsAbHfRLzbjcnUbFBIpx/qH3vQv9b3U03IQ/HfFkERTzfFj8w8jSpR7GBE123uFEYAzaDRIqX/2JAtJbDat/COkd7CNBva2cMvq0MGxp0PRSCPF8BXjWG3FgNHc9XPT71Ojy3sMFdfJRCeKxEsVtKwFHwALZfCUk3tIfNR8XiJwc1LmL4dg141JPKtj3WUdNFJqLGFVPC4OkR4BxajTWsChY64wmCnMxsWPCHcutKBxMVp5mxA1S+aMComToaqTRUQknLTH62kHOVEE+VQnjahscNCy0cMBWsSI0TCQcZc5ALkEYckL5A5noWSBhfm2AecMAjbcRWV0pUTh0HE64TNf0mczcnnQyu/MilaFJCae1nw2fbz1DnVOxyGTlKeZft/Ff8x1BRssfACjTwQAAAABJRU5ErkJggg=="); } .add-with-hash { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJvSURBVDjLpZPrS5NhGIf9W7YvBYOkhlkoqCklWChv2WyKik7blnNris72bi6dus0DLZ0TDxW1odtopDs4D8MDZuLU0kXq61CijSIIasOvv94VTUfLiB74fXngup7nvrnvJABJ/5PfLnTTdcwOj4RsdYmo5glBWP6iOtzwvIKSWstI0Wgx80SBblpKtE9KQs/We7EaWoT/8wbWP61gMmCH0lMDvokT4j25TiQU/ITFkek9Ow6+7WH2gwsmahCPdwyw75uw9HEO2gUZSkfyI9zBPCJOoJ2SMmg46N61YO/rNoa39Xi41oFuXysMfh36/Fp0b7bAfWAH6RGi0HglWNCbzYgJaFjRv6zGuy+b9It96N3SQvNKiV9HvSaDfFEIxXItnPs23BzJQd6DDEVM0OKsoVwBG/1VMzpXVWhbkUM2K4oJBDYuGmbKIJ0qxsAbHfRLzbjcnUbFBIpx/qH3vQv9b3U03IQ/HfFkERTzfFj8w8jSpR7GBE123uFEYAzaDRIqX/2JAtJbDat/COkd7CNBva2cMvq0MGxp0PRSCPF8BXjWG3FgNHc9XPT71Ojy3sMFdfJRCeKxEsVtKwFHwALZfCUk3tIfNR8XiJwc1LmL4dg141JPKtj3WUdNFJqLGFVPC4OkR4BxajTWsChY64wmCnMxsWPCHcutKBxMVp5mxA1S+aMComToaqTRUQknLTH62kHOVEE+VQnjahscNCy0cMBWsSI0TCQcZc5ALkEYckL5A5noWSBhfm2AecMAjbcRWV0pUTh0HE64TNf0mczcnnQyu/MilaFJCae1nw2fbz1DnVOxyGTlKeZft/Ff8x1BRssfACjTwQAAAABJRU5ErkJggg=="); } .python { background-image: url("/static/img/python.png?%s"); } .datauri { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0 vr4MkhoXe0rZigAAAABJRU5ErkJggg=="); } ''' % datauri_hash] self.assertEqual(out, list(self.css_node.hunks()))
class CompressorTestCase(SimpleTestCase): def setUp(self): self.css = """\ <link rel="stylesheet" href="/static/css/one.css" type="text/css" /> <style type="text/css">p { border:5px solid green;}</style> <link rel="stylesheet" href="/static/css/two.css" type="text/css" />""" self.css_node = CssCompressor(self.css) self.js = """\ <script src="/static/js/one.js" type="text/javascript"></script> <script type="text/javascript">obj.value = "value";</script>""" self.js_node = JsCompressor(self.js) def assertEqualCollapsed(self, a, b): """ assertEqual with internal newlines collapsed to single, and trailing whitespace removed. """ collapse = lambda x: re.sub(r'\n+', '\n', x).rstrip() self.assertEqual(collapse(a), collapse(b)) def assertEqualSplits(self, a, b): """ assertEqual for splits, particularly ignoring the presence of a trailing newline on the content. """ mangle = lambda split: [(x[0], x[1], x[2], x[3].rstrip()) for x in split] self.assertEqual(mangle(a), mangle(b)) def test_css_split(self): out = [ ( SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, 'css', 'one.css'), 'css/one.css', '<link rel="stylesheet" href="/static/css/one.css" type="text/css" />', ), ( SOURCE_HUNK, 'p { border:5px solid green;}', None, '<style type="text/css">p { border:5px solid green;}</style>', ), ( SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, 'css', 'two.css'), 'css/two.css', '<link rel="stylesheet" href="/static/css/two.css" type="text/css" />', ), ] split = self.css_node.split_contents() split = [(x[0], x[1], x[2], self.css_node.parser.elem_str(x[3])) for x in split] self.assertEqualSplits(split, out) def test_css_hunks(self): out = ['body { background:#990; }', 'p { border:5px solid green;}', 'body { color:#fff; }'] self.assertEqual(out, list(self.css_node.hunks())) def test_css_output(self): out = 'body { background:#990; }\np { border:5px solid green;}\nbody { color:#fff; }' hunks = '\n'.join([h for h in self.css_node.hunks()]) self.assertEqual(out, hunks) def test_css_output_with_bom_input(self): out = 'body { background:#990; }\n.compress-test {color: red;}' css = ("""<link rel="stylesheet" href="/static/css/one.css" type="text/css" /> <link rel="stylesheet" href="/static/css/utf-8_with-BOM.css" type="text/css" />""") css_node_with_bom = CssCompressor(css) hunks = '\n'.join([h for h in css_node_with_bom.hunks()]) self.assertEqual(out, hunks) def test_css_mtimes(self): is_date = re.compile(r'^\d{10}[\.\d]+$') for date in self.css_node.mtimes: self.assertTrue(is_date.match(str(float(date))), "mtimes is returning something that doesn't look like a date: %s" % date) @override_settings(COMPRESS_ENABLED=False) def test_css_return_if_off(self): self.assertEqualCollapsed(self.css, self.css_node.output()) def test_cachekey(self): is_cachekey = re.compile(r'\w{12}') self.assertTrue(is_cachekey.match(self.css_node.cachekey), r"cachekey is returning something that doesn't look like r'\w{12}'") def test_css_return_if_on(self): output = css_tag('/static/CACHE/css/58a8c0714e59.css') self.assertEqual(output, self.css_node.output().strip()) def test_js_split(self): out = [ ( SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, 'js', 'one.js'), 'js/one.js', '<script src="/static/js/one.js" type="text/javascript"></script>', ), ( SOURCE_HUNK, 'obj.value = "value";', None, '<script type="text/javascript">obj.value = "value";</script>', ), ] split = self.js_node.split_contents() split = [(x[0], x[1], x[2], self.js_node.parser.elem_str(x[3])) for x in split] self.assertEqualSplits(split, out) def test_js_hunks(self): out = ['obj = {};', 'obj.value = "value";'] self.assertEqual(out, list(self.js_node.hunks())) def test_js_output(self): out = '<script type="text/javascript" src="/static/CACHE/js/74e158ccb432.js"></script>' self.assertEqual(out, self.js_node.output()) def test_js_override_url(self): self.js_node.context.update({'url': 'This is not a url, just a text'}) out = '<script type="text/javascript" src="/static/CACHE/js/74e158ccb432.js"></script>' self.assertEqual(out, self.js_node.output()) def test_css_override_url(self): self.css_node.context.update({'url': 'This is not a url, just a text'}) output = css_tag('/static/CACHE/css/58a8c0714e59.css') self.assertEqual(output, self.css_node.output().strip()) @override_settings(COMPRESS_PRECOMPILERS=(), COMPRESS_ENABLED=False) def test_js_return_if_off(self): self.assertEqualCollapsed(self.js, self.js_node.output()) def test_js_return_if_on(self): output = '<script type="text/javascript" src="/static/CACHE/js/74e158ccb432.js"></script>' self.assertEqual(output, self.js_node.output()) @override_settings(COMPRESS_OUTPUT_DIR='custom') def test_custom_output_dir1(self): output = '<script type="text/javascript" src="/static/custom/js/74e158ccb432.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) @override_settings(COMPRESS_OUTPUT_DIR='') def test_custom_output_dir2(self): output = '<script type="text/javascript" src="/static/js/74e158ccb432.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) @override_settings(COMPRESS_OUTPUT_DIR='/custom/nested/') def test_custom_output_dir3(self): output = '<script type="text/javascript" src="/static/custom/nested/js/74e158ccb432.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) @override_settings(COMPRESS_PRECOMPILERS=( ('text/foobar', 'compressor.tests.test_base.TestPrecompiler'), ), COMPRESS_ENABLED=True) def test_precompiler_class_used(self): css = '<style type="text/foobar">p { border:10px solid red;}</style>' css_node = CssCompressor(css) output = make_soup(css_node.output('inline')) self.assertEqual(output.text, 'OUTPUT') @override_settings(COMPRESS_PRECOMPILERS=( ('text/foobar', 'compressor.tests.test_base.NonexistentFilter'), ), COMPRESS_ENABLED=True) def test_nonexistent_precompiler_class_error(self): css = '<style type="text/foobar">p { border:10px solid red;}</style>' css_node = CssCompressor(css) self.assertRaises(FilterDoesNotExist, css_node.output, 'inline') @override_settings(COMPRESS_PRECOMPILERS=( ('text/foobar', './foo -I ./bar/baz'), ), COMPRESS_ENABLED=True) def test_command_with_dot_precompiler(self): css = '<style type="text/foobar">p { border:10px solid red;}</style>' css_node = CssCompressor(css) self.assertRaises(FilterError, css_node.output, 'inline') @override_settings(COMPRESS_PRECOMPILERS=( ('text/django', 'compressor.filters.template.TemplateFilter'), ), COMPRESS_ENABLED=True) def test_template_precompiler(self): css = '<style type="text/django">p { border:10px solid {% if 1 %}green{% else %}red{% endif %};}</style>' css_node = CssCompressor(css) output = make_soup(css_node.output('inline')) self.assertEqual(output.text, 'p { border:10px solid green;}')
class CssAbsolutizingTestCase(TestCase): hashing_method = 'mtime' hashing_func = staticmethod(get_hashed_mtime) template = ( "p { background: url('%(url)simg/python.png%(query)s%(hash)s%(frag)s') }" "p { filter: Alpha(src='%(url)simg/python.png%(query)s%(hash)s%(frag)s') }" ) def setUp(self): self.override_settings = self.settings( COMPRESS_CSS_HASHING_METHOD=self.hashing_method) self.override_settings.__enter__() self.css = """ <link rel="stylesheet" href="/static/css/url/url1.css" type="text/css"> <link rel="stylesheet" href="/static/css/url/2/url2.css" type="text/css"> """ self.css_node = CssCompressor(self.css) def tearDown(self): self.override_settings.__exit__(None, None, None) @override_settings(COMPRESS_CSS_HASHING_METHOD=None) def test_css_no_hash(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') content = self.template % blankdict(url='../../') params = blankdict({ 'url': settings.COMPRESS_URL, }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://static.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../') params = blankdict({ 'url': settings.COMPRESS_URL, 'hash': '?' + self.hashing_func(imagefilename), }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://static.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_url_fragment(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../', frag='#foo') params = blankdict({ 'url': settings.COMPRESS_URL, 'hash': '?' + self.hashing_func(imagefilename), 'frag': '#foo', }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://media.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_only_url_fragment(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') content = "p { background: url('#foo') }" filter = CssAbsoluteFilter(content) self.assertEqual( content, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://media.example.com/'): filter = CssAbsoluteFilter(content) self.assertEqual( content, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_only_url_fragment_wrap_double_quotes(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') content = 'p { background: url("#foo") }' filter = CssAbsoluteFilter(content) self.assertEqual( content, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://media.example.com/'): filter = CssAbsoluteFilter(content) self.assertEqual( content, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_querystring(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../', query='?foo') params = blankdict({ 'url': settings.COMPRESS_URL, 'query': '?foo', 'hash': '&' + self.hashing_func(imagefilename), }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://media.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_https(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../') params = blankdict({ 'url': settings.COMPRESS_URL, 'hash': '?' + self.hashing_func(imagefilename), }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='https://static.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_relative_path(self): filename = os.path.join(settings.TEST_DIR, 'whatever', '..', 'static', 'whatever/../css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../') params = blankdict({ 'url': settings.COMPRESS_URL, 'hash': '?' + self.hashing_func(imagefilename), }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='https://static.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_filename_outside_compress_root(self): filename = '/foo/bar/baz/test.css' content = self.template % blankdict(url='../qux/') params = blankdict({ 'url': settings.COMPRESS_URL + 'bar/qux/', }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='bar/baz/test.css')) with self.settings(COMPRESS_URL='https://static.example.com/'): params['url'] = settings.COMPRESS_URL + 'bar/qux/' output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='bar/baz/test.css')) def test_css_hunks(self): hash_dict = { 'hash1': self.hashing_func( os.path.join(settings.COMPRESS_ROOT, 'img/python.png')), 'hash2': self.hashing_func( os.path.join(settings.COMPRESS_ROOT, 'img/add.png')), } self.assertEqual([ """\ p { background: url('/static/img/python.png?%(hash1)s'); } p { background: url('/static/img/python.png?%(hash1)s'); } p { background: url('/static/img/python.png?%(hash1)s'); } p { background: url('/static/img/python.png?%(hash1)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/static/img/python.png?%(hash1)s'); } """ % hash_dict, """\ p { background: url('/static/img/add.png?%(hash2)s'); } p { background: url('/static/img/add.png?%(hash2)s'); } p { background: url('/static/img/add.png?%(hash2)s'); } p { background: url('/static/img/add.png?%(hash2)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/static/img/add.png?%(hash2)s'); } """ % hash_dict ], list(self.css_node.hunks())) def test_guess_filename(self): for base_url in ('/static/', 'http://static.example.com/'): with self.settings(COMPRESS_URL=base_url): url = '%s/img/python.png' % settings.COMPRESS_URL.rstrip('/') path = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('%s') }" % url filter = CssAbsoluteFilter(content) self.assertEqual(path, filter.guess_filename(url))
class CssAbsolutizingTestCase(TestCase): hashing_method = 'mtime' hashing_func = staticmethod(get_hashed_mtime) content = ("p { background: url('../../img/python.png') }" "p { filter: Alpha(src='../../img/python.png') }") def setUp(self): self.old_enabled = settings.COMPRESS_ENABLED self.old_url = settings.COMPRESS_URL self.old_hashing_method = settings.COMPRESS_CSS_HASHING_METHOD settings.COMPRESS_ENABLED = True settings.COMPRESS_URL = '/static/' settings.COMPRESS_CSS_HASHING_METHOD = self.hashing_method self.css = """ <link rel="stylesheet" href="/static/css/url/url1.css" type="text/css"> <link rel="stylesheet" href="/static/css/url/2/url2.css" type="text/css"> """ self.css_node = CssCompressor(self.css) def tearDown(self): settings.COMPRESS_ENABLED = self.old_enabled settings.COMPRESS_URL = self.old_url settings.COMPRESS_CSS_HASHING_METHOD = self.old_hashing_method def test_css_absolute_filter(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') params = { 'url': settings.COMPRESS_URL, 'hash': self.hashing_func(imagefilename), } output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }" ) % params filter = CssAbsoluteFilter(self.content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = params['url'] = 'http://static.example.com/' filter = CssAbsoluteFilter(self.content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }" ) % params self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_url_fragment(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') params = { 'url': settings.COMPRESS_URL, 'hash': self.hashing_func(imagefilename), } content = "p { background: url('../../img/python.png#foo') }" output = "p { background: url('%(url)simg/python.png?%(hash)s#foo') }" % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = params['url'] = 'http://media.example.com/' filter = CssAbsoluteFilter(content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = "p { background: url('%(url)simg/python.png?%(hash)s#foo') }" % params self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_only_url_fragment(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') content = "p { background: url('#foo') }" filter = CssAbsoluteFilter(content) self.assertEqual( content, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = 'http://media.example.com/' filter = CssAbsoluteFilter(content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') self.assertEqual( content, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_querystring(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') params = { 'url': settings.COMPRESS_URL, 'hash': self.hashing_func(imagefilename), } content = "p { background: url('../../img/python.png?foo') }" output = "p { background: url('%(url)simg/python.png?foo&%(hash)s') }" % params filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = params['url'] = 'http://media.example.com/' filter = CssAbsoluteFilter(content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = "p { background: url('%(url)simg/python.png?foo&%(hash)s') }" % params self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_https(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') params = { 'url': settings.COMPRESS_URL, 'hash': self.hashing_func(imagefilename), } output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }" ) % params filter = CssAbsoluteFilter(self.content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = params['url'] = 'https://static.example.com/' filter = CssAbsoluteFilter(self.content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }" ) % params self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_relative_path(self): filename = os.path.join(settings.TEST_DIR, 'whatever', '..', 'static', 'whatever/../css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') params = { 'url': settings.COMPRESS_URL, 'hash': self.hashing_func(imagefilename), } output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }" ) % params filter = CssAbsoluteFilter(self.content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = params['url'] = 'https://static.example.com/' filter = CssAbsoluteFilter(self.content) output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }" ) % params self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_hunks(self): hash_dict = { 'hash1': self.hashing_func( os.path.join(settings.COMPRESS_ROOT, 'img/python.png')), 'hash2': self.hashing_func( os.path.join(settings.COMPRESS_ROOT, 'img/add.png')), } self.assertEqual([ u"""\ p { background: url('/static/img/python.png?%(hash1)s'); } p { background: url('/static/img/python.png?%(hash1)s'); } p { background: url('/static/img/python.png?%(hash1)s'); } p { background: url('/static/img/python.png?%(hash1)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/static/img/python.png?%(hash1)s'); } """ % hash_dict, u"""\ p { background: url('/static/img/add.png?%(hash2)s'); } p { background: url('/static/img/add.png?%(hash2)s'); } p { background: url('/static/img/add.png?%(hash2)s'); } p { background: url('/static/img/add.png?%(hash2)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/static/img/add.png?%(hash2)s'); } """ % hash_dict ], list(self.css_node.hunks())) def test_guess_filename(self): for base_url in ('/static/', 'http://static.example.com/'): settings.COMPRESS_URL = base_url url = '%s/img/python.png' % settings.COMPRESS_URL.rstrip('/') path = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('%s') }" % url filter = CssAbsoluteFilter(content) self.assertEqual(path, filter.guess_filename(url))
class CssAbsolutizingTestCase(TestCase): def setUp(self): settings.COMPRESS_ENABLED = True settings.COMPRESS_URL = '/media/' settings.COMPRESS_CSS_HASHING_METHOD = 'mtime' self.css = """ <link rel="stylesheet" href="/media/css/url/url1.css" type="text/css"> <link rel="stylesheet" href="/media/css/url/2/url2.css" type="text/css"> """ self.css_node = CssCompressor(self.css) def suffix_method(self, filename): return get_hashed_mtime(filename) def test_css_absolute_filter(self): from compressor.filters.css_default import CssAbsoluteFilter filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('../../img/python.png') }" output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename)) filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = 'http://media.example.com/' filter = CssAbsoluteFilter(content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename)) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_https(self): from compressor.filters.css_default import CssAbsoluteFilter filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('../../img/python.png') }" output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename)) filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = 'https://media.example.com/' filter = CssAbsoluteFilter(content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename)) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_relative_path(self): from compressor.filters.css_default import CssAbsoluteFilter filename = os.path.join(settings.TEST_DIR, 'whatever', '..', 'media', 'whatever/../css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('../../img/python.png') }" output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename)) filter = CssAbsoluteFilter(content) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = 'https://media.example.com/' filter = CssAbsoluteFilter(content) output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename)) self.assertEqual( output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_hunks(self): hash_dict = { 'hash1': self.suffix_method( os.path.join(settings.COMPRESS_ROOT, 'img/python.png')), 'hash2': self.suffix_method( os.path.join(settings.COMPRESS_ROOT, 'img/add.png')), } out = [ u"p { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\n" % hash_dict, u"p { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\n" % hash_dict ] hunks = [h for m, h in self.css_node.hunks()] self.assertEqual(out, hunks) def test_guess_filename(self): import urllib from compressor.filters.css_default import CssAbsoluteFilter for base_url in ('/media/', 'http://media.example.com/'): settings.COMPRESS_URL = base_url url = '%s/img/python.png' % settings.COMPRESS_URL.rstrip('/') path = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('%s') }" % url filter = CssAbsoluteFilter(content) self.assertEqual(path, filter.guess_filename(url))
class CssAbsolutizingTestCase(TestCase): hashing_method = 'mtime' hashing_func = staticmethod(get_hashed_mtime) template = ("p { background: url('%(url)simg/python.png%(query)s%(hash)s%(frag)s') }" "p { filter: Alpha(src='%(url)simg/python.png%(query)s%(hash)s%(frag)s') }") def setUp(self): self.override_settings = self.settings(COMPRESS_CSS_HASHING_METHOD=self.hashing_method) self.override_settings.__enter__() self.css = """ <link rel="stylesheet" href="/static/css/url/url1.css" type="text/css"> <link rel="stylesheet" href="/static/css/url/2/url2.css" type="text/css"> """ self.css_node = CssCompressor(self.css) def tearDown(self): self.override_settings.__exit__(None, None, None) @override_settings(COMPRESS_CSS_HASHING_METHOD=None) def test_css_no_hash(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') content = self.template % blankdict(url='../../') params = blankdict({ 'url': settings.COMPRESS_URL, }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://static.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../') params = blankdict({ 'url': settings.COMPRESS_URL, 'hash': '?' + self.hashing_func(imagefilename), }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://static.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_url_fragment(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../', frag='#foo') params = blankdict({ 'url': settings.COMPRESS_URL, 'hash': '?' + self.hashing_func(imagefilename), 'frag': '#foo', }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://media.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_only_url_fragment(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') content = "p { background: url('#foo') }" filter = CssAbsoluteFilter(content) self.assertEqual(content, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://media.example.com/'): filter = CssAbsoluteFilter(content) self.assertEqual(content, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_querystring(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../', query='?foo') params = blankdict({ 'url': settings.COMPRESS_URL, 'query': '?foo', 'hash': '&' + self.hashing_func(imagefilename), }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='http://media.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_https(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../') params = blankdict({ 'url': settings.COMPRESS_URL, 'hash': '?' + self.hashing_func(imagefilename), }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='https://static.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_relative_path(self): filename = os.path.join(settings.TEST_DIR, 'whatever', '..', 'static', 'whatever/../css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = self.template % blankdict(url='../../') params = blankdict({ 'url': settings.COMPRESS_URL, 'hash': '?' + self.hashing_func(imagefilename), }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) with self.settings(COMPRESS_URL='https://static.example.com/'): params['url'] = settings.COMPRESS_URL output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_filename_outside_compress_root(self): filename = '/foo/bar/baz/test.css' content = self.template % blankdict(url='../qux/') params = blankdict({ 'url': settings.COMPRESS_URL + 'bar/qux/', }) output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='bar/baz/test.css')) with self.settings(COMPRESS_URL='https://static.example.com/'): params['url'] = settings.COMPRESS_URL + 'bar/qux/' output = self.template % params filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='bar/baz/test.css')) def test_css_hunks(self): hash_dict = { 'hash1': self.hashing_func(os.path.join(settings.COMPRESS_ROOT, 'img/python.png')), 'hash2': self.hashing_func(os.path.join(settings.COMPRESS_ROOT, 'img/add.png')), } self.assertEqual(["""\ p { background: url('/static/img/python.png?%(hash1)s'); } p { background: url('/static/img/python.png?%(hash1)s'); } p { background: url('/static/img/python.png?%(hash1)s'); } p { background: url('/static/img/python.png?%(hash1)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/static/img/python.png?%(hash1)s'); } """ % hash_dict, """\ p { background: url('/static/img/add.png?%(hash2)s'); } p { background: url('/static/img/add.png?%(hash2)s'); } p { background: url('/static/img/add.png?%(hash2)s'); } p { background: url('/static/img/add.png?%(hash2)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/static/img/add.png?%(hash2)s'); } """ % hash_dict], list(self.css_node.hunks())) def test_guess_filename(self): for base_url in ('/static/', 'http://static.example.com/'): with self.settings(COMPRESS_URL=base_url): url = '%s/img/python.png' % settings.COMPRESS_URL.rstrip('/') path = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('%s') }" % url filter = CssAbsoluteFilter(content) self.assertEqual(path, filter.guess_filename(url))
class CompressorTestCase(TestCase): def setUp(self): settings.COMPRESS_ENABLED = True settings.COMPRESS_PRECOMPILERS = {} settings.COMPRESS_DEBUG_TOGGLE = 'nocompress' self.css = """\ <link rel="stylesheet" href="/media/css/one.css" type="text/css" /> <style type="text/css">p { border:5px solid green;}</style> <link rel="stylesheet" href="/media/css/two.css" type="text/css" />""" self.css_node = CssCompressor(self.css) self.js = """\ <script src="/media/js/one.js" type="text/javascript"></script> <script type="text/javascript">obj.value = "value";</script>""" self.js_node = JsCompressor(self.js) def test_css_split(self): out = [ (SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u'css', u'one.css'), u'css/one.css', u'<link rel="stylesheet" href="/media/css/one.css" type="text/css" />'), (SOURCE_HUNK, u'p { border:5px solid green;}', None, u'<style type="text/css">p { border:5px solid green;}</style>'), (SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u'css', u'two.css'), u'css/two.css', u'<link rel="stylesheet" href="/media/css/two.css" type="text/css" />'), ] split = self.css_node.split_contents() split = [(x[0], x[1], x[2], self.css_node.parser.elem_str(x[3])) for x in split] self.assertEqual(out, split) def test_css_hunks(self): out = ['body { background:#990; }', u'p { border:5px solid green;}', 'body { color:#fff; }'] self.assertEqual(out, list(self.css_node.hunks())) def test_css_output(self): out = u'body { background:#990; }\np { border:5px solid green;}\nbody { color:#fff; }' hunks = '\n'.join([h for h in self.css_node.hunks()]) self.assertEqual(out, hunks) def test_css_mtimes(self): is_date = re.compile(r'^\d{10}[\.\d]+$') for date in self.css_node.mtimes: self.assertTrue(is_date.match(str(float(date))), "mtimes is returning something that doesn't look like a date: %s" % date) def test_css_return_if_off(self): settings.COMPRESS_ENABLED = False self.assertEqual(self.css, self.css_node.output()) def test_cachekey(self): is_cachekey = re.compile(r'\w{12}') self.assertTrue(is_cachekey.match(self.css_node.cachekey), "cachekey is returning something that doesn't look like r'\w{12}'") def test_css_return_if_on(self): output = css_tag('/media/CACHE/css/e41ba2cc6982.css') self.assertEqual(output, self.css_node.output().strip()) def test_js_split(self): out = [ (SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u'js', u'one.js'), u'js/one.js', '<script src="/media/js/one.js" type="text/javascript"></script>'), (SOURCE_HUNK, u'obj.value = "value";', None, '<script type="text/javascript">obj.value = "value";</script>'), ] split = self.js_node.split_contents() split = [(x[0], x[1], x[2], self.js_node.parser.elem_str(x[3])) for x in split] self.assertEqual(out, split) def test_js_hunks(self): out = ['obj = {};', u'obj.value = "value";'] self.assertEqual(out, list(self.js_node.hunks())) def test_js_output(self): out = u'<script type="text/javascript" src="/media/CACHE/js/066cd253eada.js"></script>' self.assertEqual(out, self.js_node.output()) def test_js_override_url(self): self.js_node.context.update({'url': u'This is not a url, just a text'}) out = u'<script type="text/javascript" src="/media/CACHE/js/066cd253eada.js"></script>' self.assertEqual(out, self.js_node.output()) def test_css_override_url(self): self.css_node.context.update({'url': u'This is not a url, just a text'}) output = css_tag('/media/CACHE/css/e41ba2cc6982.css') self.assertEqual(output, self.css_node.output().strip()) def test_js_return_if_off(self): try: enabled = settings.COMPRESS_ENABLED precompilers = settings.COMPRESS_PRECOMPILERS settings.COMPRESS_ENABLED = False settings.COMPRESS_PRECOMPILERS = {} self.assertEqual(self.js, self.js_node.output()) finally: settings.COMPRESS_ENABLED = enabled settings.COMPRESS_PRECOMPILERS = precompilers def test_js_return_if_on(self): output = u'<script type="text/javascript" src="/media/CACHE/js/066cd253eada.js"></script>' self.assertEqual(output, self.js_node.output()) def test_custom_output_dir(self): try: old_output_dir = settings.COMPRESS_OUTPUT_DIR settings.COMPRESS_OUTPUT_DIR = 'custom' output = u'<script type="text/javascript" src="/media/custom/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) settings.COMPRESS_OUTPUT_DIR = '' output = u'<script type="text/javascript" src="/media/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) settings.COMPRESS_OUTPUT_DIR = '/custom/nested/' output = u'<script type="text/javascript" src="/media/custom/nested/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) finally: settings.COMPRESS_OUTPUT_DIR = old_output_dir
class CompressorTestCase(TestCase): def setUp(self): settings.COMPRESS_ENABLED = True settings.COMPRESS_PRECOMPILERS = {} settings.COMPRESS_DEBUG_TOGGLE = 'nocompress' self.css = """\ <link rel="stylesheet" href="/media/css/one.css" type="text/css" /> <style type="text/css">p { border:5px solid green;}</style> <link rel="stylesheet" href="/media/css/two.css" type="text/css" />""" self.css_node = CssCompressor(self.css) self.js = """\ <script src="/media/js/one.js" type="text/javascript"></script> <script type="text/javascript">obj.value = "value";</script>""" self.js_node = JsCompressor(self.js) def test_css_split(self): out = [ (SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u'css', u'one.css'), u'css/one.css', u'<link rel="stylesheet" href="/media/css/one.css" type="text/css" />' ), (SOURCE_HUNK, u'p { border:5px solid green;}', None, u'<style type="text/css">p { border:5px solid green;}</style>'), (SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u'css', u'two.css'), u'css/two.css', u'<link rel="stylesheet" href="/media/css/two.css" type="text/css" />' ), ] split = self.css_node.split_contents() split = [(x[0], x[1], x[2], self.css_node.parser.elem_str(x[3][0])) for x in split] self.assertEqual(out, split) def test_css_hunks(self): out = [ 'body { background:#990; }', u'p { border:5px solid green;}', 'body { color:#fff; }' ] self.assertEqual(out, list(self.css_node.hunks())) def test_css_output(self): out = u'body { background:#990; }\np { border:5px solid green;}\nbody { color:#fff; }' hunks = '\n'.join([h for h in self.css_node.hunks()]) self.assertEqual(out, hunks) def test_css_mtimes(self): is_date = re.compile(r'^\d{10}[\.\d]+$') for date in self.css_node.mtimes: self.assertTrue( is_date.match(str(float(date))), "mtimes is returning something that doesn't look like a date: %s" % date) def test_css_return_if_off(self): settings.COMPRESS_ENABLED = False self.assertEqual(self.css, self.css_node.output()) def test_cachekey(self): is_cachekey = re.compile(r'\w{12}') self.assertTrue( is_cachekey.match(self.css_node.cachekey), "cachekey is returning something that doesn't look like r'\w{12}'") def test_css_return_if_on(self): output = css_tag('/media/CACHE/css/e41ba2cc6982.css') self.assertEqual(output, self.css_node.output().strip()) def test_js_split(self): out = [ (SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u'js', u'one.js'), u'js/one.js', '<script src="/media/js/one.js" type="text/javascript"></script>' ), (SOURCE_HUNK, u'obj.value = "value";', None, '<script type="text/javascript">obj.value = "value";</script>'), ] split = self.js_node.split_contents() split = [(x[0], x[1], x[2], self.js_node.parser.elem_str(x[3][0])) for x in split] self.assertEqual(out, split) def test_js_hunks(self): out = ['obj = {};', u'obj.value = "value";'] self.assertEqual(out, list(self.js_node.hunks())) def test_js_output(self): out = u'<script type="text/javascript" src="/media/CACHE/js/066cd253eada.js"></script>' self.assertEqual(out, self.js_node.output()) def test_js_override_url(self): self.js_node.context.update({'url': u'This is not a url, just a text'}) out = u'<script type="text/javascript" src="/media/CACHE/js/066cd253eada.js"></script>' self.assertEqual(out, self.js_node.output()) def test_css_override_url(self): self.css_node.context.update( {'url': u'This is not a url, just a text'}) output = css_tag('/media/CACHE/css/e41ba2cc6982.css') self.assertEqual(output, self.css_node.output().strip()) def test_js_return_if_off(self): try: enabled = settings.COMPRESS_ENABLED precompilers = settings.COMPRESS_PRECOMPILERS settings.COMPRESS_ENABLED = False settings.COMPRESS_PRECOMPILERS = {} self.assertEqual(self.js, self.js_node.output()) finally: settings.COMPRESS_ENABLED = enabled settings.COMPRESS_PRECOMPILERS = precompilers def test_js_return_if_on(self): output = u'<script type="text/javascript" src="/media/CACHE/js/066cd253eada.js"></script>' self.assertEqual(output, self.js_node.output()) def test_custom_output_dir(self): try: old_output_dir = settings.COMPRESS_OUTPUT_DIR settings.COMPRESS_OUTPUT_DIR = 'custom' output = u'<script type="text/javascript" src="/media/custom/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) settings.COMPRESS_OUTPUT_DIR = '' output = u'<script type="text/javascript" src="/media/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) settings.COMPRESS_OUTPUT_DIR = '/custom/nested/' output = u'<script type="text/javascript" src="/media/custom/nested/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) finally: settings.COMPRESS_OUTPUT_DIR = old_output_dir
class CompressorTestCase(SimpleTestCase): def setUp(self): settings.COMPRESS_ENABLED = True settings.COMPRESS_PRECOMPILERS = () settings.COMPRESS_DEBUG_TOGGLE = 'nocompress' self.css = """\ <link rel="stylesheet" href="/static/css/one.css" type="text/css" /> <style type="text/css">p { border:5px solid green;}</style> <link rel="stylesheet" href="/static/css/two.css" type="text/css" />""" self.css_node = CssCompressor(self.css) self.js = """\ <script src="/static/js/one.js" type="text/javascript"></script> <script type="text/javascript">obj.value = "value";</script>""" self.js_node = JsCompressor(self.js) def test_css_split(self): out = [ ( SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, 'css', 'one.css'), 'css/one.css', '<link rel="stylesheet" href="/static/css/one.css" type="text/css" />', ), ( SOURCE_HUNK, 'p { border:5px solid green;}', None, '<style type="text/css">p { border:5px solid green;}</style>', ), ( SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, 'css', 'two.css'), 'css/two.css', '<link rel="stylesheet" href="/static/css/two.css" type="text/css" />', ), ] split = self.css_node.split_contents() split = [(x[0], x[1], x[2], self.css_node.parser.elem_str(x[3])) for x in split] self.assertEqual(out, split) def test_css_hunks(self): out = ['body { background:#990; }', 'p { border:5px solid green;}', 'body { color:#fff; }'] self.assertEqual(out, list(self.css_node.hunks())) def test_css_output(self): out = 'body { background:#990; }\np { border:5px solid green;}\nbody { color:#fff; }' hunks = '\n'.join([h for h in self.css_node.hunks()]) self.assertEqual(out, hunks) def test_css_mtimes(self): is_date = re.compile(r'^\d{10}[\.\d]+$') for date in self.css_node.mtimes: self.assertTrue(is_date.match(str(float(date))), "mtimes is returning something that doesn't look like a date: %s" % date) def test_css_return_if_off(self): settings.COMPRESS_ENABLED = False self.assertEqual(self.css, self.css_node.output()) def test_cachekey(self): is_cachekey = re.compile(r'\w{12}') self.assertTrue(is_cachekey.match(self.css_node.cachekey), "cachekey is returning something that doesn't look like r'\w{12}'") def test_css_return_if_on(self): output = css_tag('/static/CACHE/css/e41ba2cc6982.css') self.assertEqual(output, self.css_node.output().strip()) def test_js_split(self): out = [ ( SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, 'js', 'one.js'), 'js/one.js', '<script src="/static/js/one.js" type="text/javascript"></script>', ), ( SOURCE_HUNK, 'obj.value = "value";', None, '<script type="text/javascript">obj.value = "value";</script>', ), ] split = self.js_node.split_contents() split = [(x[0], x[1], x[2], self.js_node.parser.elem_str(x[3])) for x in split] self.assertEqual(out, split) def test_js_hunks(self): out = ['obj = {};', 'obj.value = "value";'] self.assertEqual(out, list(self.js_node.hunks())) def test_js_output(self): out = '<script type="text/javascript" src="/static/CACHE/js/066cd253eada.js"></script>' self.assertEqual(out, self.js_node.output()) def test_js_override_url(self): self.js_node.context.update({'url': 'This is not a url, just a text'}) out = '<script type="text/javascript" src="/static/CACHE/js/066cd253eada.js"></script>' self.assertEqual(out, self.js_node.output()) def test_css_override_url(self): self.css_node.context.update({'url': 'This is not a url, just a text'}) output = css_tag('/static/CACHE/css/e41ba2cc6982.css') self.assertEqual(output, self.css_node.output().strip()) @override_settings(COMPRESS_PRECOMPILERS=(), COMPRESS_ENABLED=False) def test_js_return_if_off(self): self.assertEqual(self.js, self.js_node.output()) def test_js_return_if_on(self): output = '<script type="text/javascript" src="/static/CACHE/js/066cd253eada.js"></script>' self.assertEqual(output, self.js_node.output()) @override_settings(COMPRESS_OUTPUT_DIR='custom') def test_custom_output_dir1(self): output = '<script type="text/javascript" src="/static/custom/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) @override_settings(COMPRESS_OUTPUT_DIR='') def test_custom_output_dir2(self): output = '<script type="text/javascript" src="/static/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) @override_settings(COMPRESS_OUTPUT_DIR='/custom/nested/') def test_custom_output_dir3(self): output = '<script type="text/javascript" src="/static/custom/nested/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) @override_settings(COMPRESS_PRECOMPILERS=( ('text/foobar', 'compressor.tests.test_base.TestPrecompiler'), ), COMPRESS_ENABLED=True) def test_precompiler_class_used(self): css = '<style type="text/foobar">p { border:10px solid red;}</style>' css_node = CssCompressor(css) output = make_soup(css_node.output('inline')) self.assertEqual(output.text, 'OUTPUT') @override_settings(COMPRESS_PRECOMPILERS=( ('text/foobar', 'compressor.tests.test_base.NonexistentFilter'), ), COMPRESS_ENABLED=True) def test_nonexistent_precompiler_class_error(self): css = '<style type="text/foobar">p { border:10px solid red;}</style>' css_node = CssCompressor(css) self.assertRaises(FilterDoesNotExist, css_node.output, 'inline')
class CssAbsolutizingTestCase(TestCase): def setUp(self): settings.COMPRESS_ENABLED = True settings.COMPRESS_URL = "/media/" settings.COMPRESS_CSS_HASHING_METHOD = "mtime" self.css = """ <link rel="stylesheet" href="/media/css/url/url1.css" type="text/css"> <link rel="stylesheet" href="/media/css/url/2/url2.css" type="text/css"> """ self.css_node = CssCompressor(self.css) def suffix_method(self, filename): return get_hashed_mtime(filename) def test_css_absolute_filter(self): from compressor.filters.css_default import CssAbsoluteFilter filename = os.path.join(settings.COMPRESS_ROOT, "css/url/test.css") imagefilename = os.path.join(settings.COMPRESS_ROOT, "img/python.png") content = "p { background: url('../../img/python.png') }" output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename), ) filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename="css/url/test.css")) settings.COMPRESS_URL = "http://media.example.com/" filter = CssAbsoluteFilter(content) filename = os.path.join(settings.COMPRESS_ROOT, "css/url/test.css") output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename), ) self.assertEqual(output, filter.input(filename=filename, basename="css/url/test.css")) def test_css_absolute_filter_https(self): from compressor.filters.css_default import CssAbsoluteFilter filename = os.path.join(settings.COMPRESS_ROOT, "css/url/test.css") imagefilename = os.path.join(settings.COMPRESS_ROOT, "img/python.png") content = "p { background: url('../../img/python.png') }" output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename), ) filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename="css/url/test.css")) settings.COMPRESS_URL = "https://media.example.com/" filter = CssAbsoluteFilter(content) filename = os.path.join(settings.COMPRESS_ROOT, "css/url/test.css") output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename), ) self.assertEqual(output, filter.input(filename=filename, basename="css/url/test.css")) def test_css_absolute_filter_relative_path(self): from compressor.filters.css_default import CssAbsoluteFilter filename = os.path.join(settings.TEST_DIR, "whatever", "..", "media", "whatever/../css/url/test.css") imagefilename = os.path.join(settings.COMPRESS_ROOT, "img/python.png") content = "p { background: url('../../img/python.png') }" output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename), ) filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename="css/url/test.css")) settings.COMPRESS_URL = "https://media.example.com/" filter = CssAbsoluteFilter(content) output = "p { background: url('%simg/python.png?%s') }" % ( settings.COMPRESS_URL, self.suffix_method(imagefilename), ) self.assertEqual(output, filter.input(filename=filename, basename="css/url/test.css")) def test_css_hunks(self): hash_dict = { "hash1": self.suffix_method(os.path.join(settings.COMPRESS_ROOT, "img/python.png")), "hash2": self.suffix_method(os.path.join(settings.COMPRESS_ROOT, "img/add.png")), } out = [ u"p { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\n" % hash_dict, u"p { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\n" % hash_dict, ] hunks = [h for m, h in self.css_node.hunks()] self.assertEqual(out, hunks) def test_guess_filename(self): import urllib from compressor.filters.css_default import CssAbsoluteFilter for base_url in ("/media/", "http://media.example.com/"): settings.COMPRESS_URL = base_url url = "%s/img/python.png" % settings.COMPRESS_URL.rstrip("/") path = os.path.join(settings.COMPRESS_ROOT, "img/python.png") content = "p { background: url('%s') }" % url filter = CssAbsoluteFilter(content) self.assertEqual(path, filter.guess_filename(url))
class CssAbsolutizingTestCase(TestCase): def setUp(self): settings.COMPRESS_ENABLED = True settings.COMPRESS_URL = '/media/' settings.COMPRESS_CSS_HASHING_METHOD = 'mtime' self.css = """ <link rel="stylesheet" href="/media/css/url/url1.css" type="text/css"> <link rel="stylesheet" href="/media/css/url/2/url2.css" type="text/css"> """ self.css_node = CssCompressor(self.css) def suffix_method(self, filename): return get_hashed_mtime(filename) def test_css_absolute_filter(self): from compressor.filters.css_default import CssAbsoluteFilter filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('../../img/python.png') }" output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename)) filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = 'http://media.example.com/' filter = CssAbsoluteFilter(content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename)) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_https(self): from compressor.filters.css_default import CssAbsoluteFilter filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('../../img/python.png') }" output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename)) filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = 'https://media.example.com/' filter = CssAbsoluteFilter(content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename)) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_relative_path(self): from compressor.filters.css_default import CssAbsoluteFilter filename = os.path.join(settings.TEST_DIR, 'whatever', '..', 'media', 'whatever/../css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('../../img/python.png') }" output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename)) filter = CssAbsoluteFilter(content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = 'https://media.example.com/' filter = CssAbsoluteFilter(content) output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename)) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_hunks(self): hash_dict = { 'hash1': self.suffix_method(os.path.join(settings.COMPRESS_ROOT, 'img/python.png')), 'hash2': self.suffix_method(os.path.join(settings.COMPRESS_ROOT, 'img/add.png')), } out = [u"p { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\n" % hash_dict, u"p { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\n" % hash_dict] hunks = [h for m, h in self.css_node.hunks()] self.assertEqual(out, hunks)
class CssAbsolutizingTestCase(TestCase): hashing_method = 'mtime' hashing_func = staticmethod(get_hashed_mtime) content = ("p { background: url('../../img/python.png') }" "p { filter: Alpha(src='../../img/python.png') }") def setUp(self): self.old_enabled = settings.COMPRESS_ENABLED self.old_url = settings.COMPRESS_URL self.old_hashing_method = settings.COMPRESS_CSS_HASHING_METHOD settings.COMPRESS_ENABLED = True settings.COMPRESS_URL = '/media/' settings.COMPRESS_CSS_HASHING_METHOD = self.hashing_method self.css = """ <link rel="stylesheet" href="/media/css/url/url1.css" type="text/css"> <link rel="stylesheet" href="/media/css/url/2/url2.css" type="text/css"> """ self.css_node = CssCompressor(self.css) def tearDown(self): settings.COMPRESS_ENABLED = self.old_enabled settings.COMPRESS_URL = self.old_url settings.COMPRESS_CSS_HASHING_METHOD = self.old_hashing_method def test_css_absolute_filter(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') params = { 'url': settings.COMPRESS_URL, 'hash': self.hashing_func(imagefilename), } output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params filter = CssAbsoluteFilter(self.content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = params['url'] = 'http://media.example.com/' filter = CssAbsoluteFilter(self.content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_https(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') params = { 'url': settings.COMPRESS_URL, 'hash': self.hashing_func(imagefilename), } output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params filter = CssAbsoluteFilter(self.content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = params['url'] = 'https://media.example.com/' filter = CssAbsoluteFilter(self.content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_relative_path(self): filename = os.path.join(settings.TEST_DIR, 'whatever', '..', 'media', 'whatever/../css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') params = { 'url': settings.COMPRESS_URL, 'hash': self.hashing_func(imagefilename), } output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params filter = CssAbsoluteFilter(self.content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) settings.COMPRESS_URL = params['url'] = 'https://media.example.com/' filter = CssAbsoluteFilter(self.content) output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_hunks(self): hash_dict = { 'hash1': self.hashing_func(os.path.join(settings.COMPRESS_ROOT, 'img/python.png')), 'hash2': self.hashing_func(os.path.join(settings.COMPRESS_ROOT, 'img/add.png')), } self.assertEqual([u"""\ p { background: url('/media/img/python.png?%(hash1)s'); } p { background: url('/media/img/python.png?%(hash1)s'); } p { background: url('/media/img/python.png?%(hash1)s'); } p { background: url('/media/img/python.png?%(hash1)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/media/img/python.png?%(hash1)s'); } """ % hash_dict, u"""\ p { background: url('/media/img/add.png?%(hash2)s'); } p { background: url('/media/img/add.png?%(hash2)s'); } p { background: url('/media/img/add.png?%(hash2)s'); } p { background: url('/media/img/add.png?%(hash2)s'); } p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/media/img/add.png?%(hash2)s'); } """ % hash_dict], list(self.css_node.hunks())) def test_guess_filename(self): for base_url in ('/media/', 'http://media.example.com/'): settings.COMPRESS_URL = base_url url = '%s/img/python.png' % settings.COMPRESS_URL.rstrip('/') path = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') content = "p { background: url('%s') }" % url filter = CssAbsoluteFilter(content) self.assertEqual(path, filter.guess_filename(url))
class CompressorTestCase(TestCase): def setUp(self): settings.COMPRESS_ENABLED = True settings.COMPRESS_PRECOMPILERS = {} settings.COMPRESS_DEBUG_TOGGLE = "nocompress" self.css = """\ <link rel="stylesheet" href="/static/css/one.css" type="text/css" /> <style type="text/css">p { border:5px solid green;}</style> <link rel="stylesheet" href="/static/css/two.css" type="text/css" />""" self.css_node = CssCompressor(self.css) self.js = """\ <script src="/static/js/one.js" type="text/javascript"></script> <script type="text/javascript">obj.value = "value";</script>""" self.js_node = JsCompressor(self.js) def test_css_split(self): out = [ ( SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u"css", u"one.css"), u"css/one.css", u'<link rel="stylesheet" href="/static/css/one.css" type="text/css" />', ), ( SOURCE_HUNK, u"p { border:5px solid green;}", None, u'<style type="text/css">p { border:5px solid green;}</style>', ), ( SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u"css", u"two.css"), u"css/two.css", u'<link rel="stylesheet" href="/static/css/two.css" type="text/css" />', ), ] split = self.css_node.split_contents() split = [(x[0], x[1], x[2], self.css_node.parser.elem_str(x[3])) for x in split] self.assertEqual(out, split) def test_css_hunks(self): out = ["body { background:#990; }", u"p { border:5px solid green;}", "body { color:#fff; }"] self.assertEqual(out, list(self.css_node.hunks())) def test_css_output(self): out = u"body { background:#990; }\np { border:5px solid green;}\nbody { color:#fff; }" hunks = "\n".join([h for h in self.css_node.hunks()]) self.assertEqual(out, hunks) def test_css_mtimes(self): is_date = re.compile(r"^\d{10}[\.\d]+$") for date in self.css_node.mtimes: self.assertTrue( is_date.match(str(float(date))), "mtimes is returning something that doesn't look like a date: %s" % date, ) def test_css_return_if_off(self): settings.COMPRESS_ENABLED = False self.assertEqual(self.css, self.css_node.output()) def test_cachekey(self): is_cachekey = re.compile(r"\w{12}") self.assertTrue( is_cachekey.match(self.css_node.cachekey), "cachekey is returning something that doesn't look like r'\w{12}'", ) def test_css_return_if_on(self): output = css_tag("/static/CACHE/css/e41ba2cc6982.css") self.assertEqual(output, self.css_node.output().strip()) def test_js_split(self): out = [ ( SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u"js", u"one.js"), u"js/one.js", '<script src="/static/js/one.js" type="text/javascript"></script>', ), ( SOURCE_HUNK, u'obj.value = "value";', None, '<script type="text/javascript">obj.value = "value";</script>', ), ] split = self.js_node.split_contents() split = [(x[0], x[1], x[2], self.js_node.parser.elem_str(x[3])) for x in split] self.assertEqual(out, split) def test_js_hunks(self): out = ["obj = {};", u'obj.value = "value";'] self.assertEqual(out, list(self.js_node.hunks())) def test_js_output(self): out = u'<script type="text/javascript" src="/static/CACHE/js/066cd253eada.js"></script>' self.assertEqual(out, self.js_node.output()) def test_js_override_url(self): self.js_node.context.update({"url": u"This is not a url, just a text"}) out = u'<script type="text/javascript" src="/static/CACHE/js/066cd253eada.js"></script>' self.assertEqual(out, self.js_node.output()) def test_css_override_url(self): self.css_node.context.update({"url": u"This is not a url, just a text"}) output = css_tag("/static/CACHE/css/e41ba2cc6982.css") self.assertEqual(output, self.css_node.output().strip()) def test_js_return_if_off(self): try: enabled = settings.COMPRESS_ENABLED precompilers = settings.COMPRESS_PRECOMPILERS settings.COMPRESS_ENABLED = False settings.COMPRESS_PRECOMPILERS = {} self.assertEqual(self.js, self.js_node.output()) finally: settings.COMPRESS_ENABLED = enabled settings.COMPRESS_PRECOMPILERS = precompilers def test_js_return_if_on(self): output = u'<script type="text/javascript" src="/static/CACHE/js/066cd253eada.js"></script>' self.assertEqual(output, self.js_node.output()) def test_custom_output_dir(self): try: old_output_dir = settings.COMPRESS_OUTPUT_DIR settings.COMPRESS_OUTPUT_DIR = "custom" output = u'<script type="text/javascript" src="/static/custom/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) settings.COMPRESS_OUTPUT_DIR = "" output = u'<script type="text/javascript" src="/static/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) settings.COMPRESS_OUTPUT_DIR = "/custom/nested/" output = u'<script type="text/javascript" src="/static/custom/nested/js/066cd253eada.js"></script>' self.assertEqual(output, JsCompressor(self.js).output()) finally: settings.COMPRESS_OUTPUT_DIR = old_output_dir def test_precompiler_class_used(self): try: original_precompilers = settings.COMPRESS_PRECOMPILERS settings.COMPRESS_ENABLED = True settings.COMPRESS_PRECOMPILERS = (("text/foobar", "compressor.tests.test_base.TestPrecompiler"),) css = '<style type="text/foobar">p { border:10px solid red;}</style>' css_node = CssCompressor(css) output = BeautifulSoup(css_node.output("inline")) self.assertEqual(output.text, "OUTPUT") finally: settings.COMPRESS_PRECOMPILERS = original_precompilers def test_nonexistent_precompiler_class_error(self): try: original_precompilers = settings.COMPRESS_PRECOMPILERS settings.COMPRESS_ENABLED = True settings.COMPRESS_PRECOMPILERS = (("text/foobar", "compressor.tests.test_base.NonexistentFilter"),) css = '<style type="text/foobar">p { border:10px solid red;}</style>' css_node = CssCompressor(css) self.assertRaises(FilterDoesNotExist, css_node.output, "inline") finally: settings.COMPRESS_PRECOMPILERS = original_precompilers