Moved files again.
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
obj={};obj.value="value";
|
|
@@ -1 +0,0 @@
|
|||||||
obj={};obj.value="value";
|
|
@@ -1 +0,0 @@
|
|||||||
obj={};obj.value="value";
|
|
@@ -11,9 +11,9 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.sites',
|
'django.contrib.sites',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'compressor',
|
|
||||||
'compressor.tests',
|
|
||||||
'django_jenkins',
|
'django_jenkins',
|
||||||
|
'compressor',
|
||||||
|
'tests',
|
||||||
]
|
]
|
||||||
|
|
||||||
MEDIA_URL = '/media/'
|
MEDIA_URL = '/media/'
|
||||||
@@ -21,7 +21,10 @@ MEDIA_URL = '/media/'
|
|||||||
MEDIA_ROOT = os.path.join(TEST_DIR, 'media')
|
MEDIA_ROOT = os.path.join(TEST_DIR, 'media')
|
||||||
|
|
||||||
TEMPLATE_DIRS = (
|
TEMPLATE_DIRS = (
|
||||||
os.path.join(TEST_DIR, 'templates'),
|
# Specifically choose a name that will not be considered
|
||||||
|
# by app_directories loader, to make sure each test uses
|
||||||
|
# a specific template without considering the others.
|
||||||
|
os.path.join(TEST_DIR, 'test_templates'),
|
||||||
)
|
)
|
||||||
|
|
||||||
JENKINS_TASKS = (
|
JENKINS_TASKS = (
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
{% block content %}{% endblock %}
|
|
||||||
|
|
||||||
{% block js%}
|
|
||||||
<script type="text/javascript">
|
|
||||||
alert("test 3");
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block css %}
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
background: {{ color|default:"purple" }};
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@@ -1,10 +0,0 @@
|
|||||||
{% extends "buggy_extends.html" %}
|
|
||||||
{% load compress %}
|
|
||||||
|
|
||||||
{% compress css %}
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
background: orange;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endcompress %}
|
|
@@ -1,49 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% load compress %}
|
|
||||||
|
|
||||||
{% block content %}{% spaceless %}
|
|
||||||
{% compress css%}
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
background: {{ color|default:"red" }};
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endcompress %}
|
|
||||||
|
|
||||||
{% compress js%}
|
|
||||||
<script type="text/javascript">
|
|
||||||
alert("{% firstof "test" %}");
|
|
||||||
</script>
|
|
||||||
{% endcompress %}
|
|
||||||
|
|
||||||
{% compress js%}
|
|
||||||
<script type="text/javascript">
|
|
||||||
alert("test 2");
|
|
||||||
</script>
|
|
||||||
{% endcompress %}
|
|
||||||
|
|
||||||
{% if condition %}
|
|
||||||
{% compress js%}
|
|
||||||
<script type="text/javascript">alert("{{ condition|default:"yellow" }}");</script>
|
|
||||||
{% endcompress %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endspaceless %}{% endblock %}
|
|
||||||
|
|
||||||
{% block js %}{% spaceless %}
|
|
||||||
{% compress js %}
|
|
||||||
{{ block.super }}
|
|
||||||
<script type="text/javascript">
|
|
||||||
alert("test 4");
|
|
||||||
</script>
|
|
||||||
{% endcompress %}
|
|
||||||
{% endspaceless %}{% endblock %}
|
|
||||||
|
|
||||||
{% block css %}{% spaceless %}
|
|
||||||
{% compress css %}
|
|
||||||
{{ block.super }}
|
|
||||||
<style type="text/css">
|
|
||||||
body { color: orange ; }
|
|
||||||
</style>
|
|
||||||
{% endcompress %}
|
|
||||||
{% endspaceless %}{% endblock %}
|
|
@@ -4,7 +4,13 @@ from .filters import (CssTidyTestCase, PrecompilerTestCase, CssMinTestCase,
|
|||||||
CssAbsolutizingTestCase, CssAbsolutizingTestCaseWithHash,
|
CssAbsolutizingTestCase, CssAbsolutizingTestCaseWithHash,
|
||||||
CssDataUriTestCase)
|
CssDataUriTestCase)
|
||||||
from .jinja2ext import TestJinja2CompressorExtension
|
from .jinja2ext import TestJinja2CompressorExtension
|
||||||
from .offline import OfflineGenerationTestCase
|
from .offline import (
|
||||||
|
OfflineGenerationBlockSuperTestCase,
|
||||||
|
OfflineGenerationConditionTestCase,
|
||||||
|
OfflineGenerationTemplateTagTestCase,
|
||||||
|
OfflineGenerationTestCaseWithContext,
|
||||||
|
OfflineGenerationTestCaseErrors,
|
||||||
|
OfflineGenerationTestCase)
|
||||||
from .parsers import (LxmlParserTests, Html5LibParserTests,
|
from .parsers import (LxmlParserTests, Html5LibParserTests,
|
||||||
BeautifulSoupParserTests, HtmlParserTests)
|
BeautifulSoupParserTests, HtmlParserTests)
|
||||||
from .signals import PostCompressSignalTestCase
|
from .signals import PostCompressSignalTestCase
|
||||||
|
@@ -1,6 +1,11 @@
|
|||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
try:
|
||||||
|
from cStringIO import StringIO
|
||||||
|
except ImportError:
|
||||||
|
from StringIO import StringIO
|
||||||
|
|
||||||
from django.template import Template, Context
|
from django.template import Template, Context
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
@@ -9,28 +14,100 @@ from compressor.exceptions import OfflineGenerationError
|
|||||||
from compressor.management.commands.compress import Command as CompressCommand
|
from compressor.management.commands.compress import Command as CompressCommand
|
||||||
from compressor.storage import default_storage
|
from compressor.storage import default_storage
|
||||||
|
|
||||||
from .base import test_dir, css_tag
|
from .base import css_tag
|
||||||
|
|
||||||
class OfflineGenerationTestCase(TestCase):
|
class OfflineTestCaseMixin():
|
||||||
"""Uses templates/test_compressor_offline.html"""
|
template_name = "test_compressor_offline.html"
|
||||||
maxDiff = None
|
templates_dir = "" # Change this for each test class, to separate templates
|
||||||
|
expected_hash = "" # Change this for each test class to the expected result
|
||||||
|
verbosity = 0
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self._old_compress = settings.COMPRESS_ENABLED
|
self._old_compress = settings.COMPRESS_ENABLED
|
||||||
self._old_compress_offline = settings.COMPRESS_OFFLINE
|
self._old_compress_offline = settings.COMPRESS_OFFLINE
|
||||||
|
self._old_template_dirs = settings.TEMPLATE_DIRS
|
||||||
|
self._old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
||||||
|
self._old_template_loaders = settings.TEMPLATE_LOADERS
|
||||||
|
self.log = StringIO()
|
||||||
|
|
||||||
|
# Force template dirs, because it enables us to force compress to
|
||||||
|
# consider only a specific directory (helps us make true,
|
||||||
|
# independant unit tests).
|
||||||
|
settings.TEMPLATE_DIRS = (
|
||||||
|
os.path.join(settings.TEMPLATE_DIRS[0], self.templates_dir),
|
||||||
|
)
|
||||||
|
# Enable offline compress
|
||||||
settings.COMPRESS_ENABLED = True
|
settings.COMPRESS_ENABLED = True
|
||||||
settings.COMPRESS_OFFLINE = True
|
settings.COMPRESS_OFFLINE = True
|
||||||
self.template_file = open(os.path.join(test_dir, "templates/test_compressor_offline.html"))
|
self.template_path = os.path.join(settings.TEMPLATE_DIRS[0], self.template_name)
|
||||||
|
self.template_file = open(self.template_path)
|
||||||
self.template = Template(self.template_file.read().decode(settings.FILE_CHARSET))
|
self.template = Template(self.template_file.read().decode(settings.FILE_CHARSET))
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
settings.COMPRESS_ENABLED = self._old_compress
|
settings.COMPRESS_ENABLED = self._old_compress
|
||||||
settings.COMPRESS_OFFLINE = self._old_compress_offline
|
settings.COMPRESS_OFFLINE = self._old_compress_offline
|
||||||
|
settings.TEMPLATE_DIRS = self._old_template_dirs
|
||||||
|
settings.TEMPLATE_LOADERS = self._old_template_loaders
|
||||||
self.template_file.close()
|
self.template_file.close()
|
||||||
manifest_path = os.path.join('CACHE', 'manifest.json')
|
manifest_path = os.path.join('CACHE', 'manifest.json')
|
||||||
if default_storage.exists(manifest_path):
|
if default_storage.exists(manifest_path):
|
||||||
default_storage.delete(manifest_path)
|
default_storage.delete(manifest_path)
|
||||||
|
|
||||||
|
def test_offline(self):
|
||||||
|
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity)
|
||||||
|
self.assertEqual(1, count)
|
||||||
|
self.assertEqual([
|
||||||
|
u'<script type="text/javascript" src="/media/CACHE/js/%s.js"></script>' % (self.expected_hash, ),
|
||||||
|
], result)
|
||||||
|
rendered_template = self.template.render(Context(settings.COMPRESS_OFFLINE_CONTEXT))
|
||||||
|
self.assertEqual(rendered_template, "".join(result) + "\n")
|
||||||
|
|
||||||
|
class OfflineGenerationBlockSuperTestCase(OfflineTestCaseMixin, TestCase):
|
||||||
|
templates_dir = "test_block_super"
|
||||||
|
expected_hash = "7c02d201f69d"
|
||||||
|
|
||||||
|
class OfflineGenerationConditionTestCase(OfflineTestCaseMixin, TestCase):
|
||||||
|
templates_dir = "test_condition"
|
||||||
|
expected_hash = "4e3758d50224"
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
||||||
|
settings.COMPRESS_OFFLINE_CONTEXT = {
|
||||||
|
'condition': 'red',
|
||||||
|
}
|
||||||
|
super(OfflineGenerationConditionTestCase, self).setUp()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
||||||
|
super(OfflineGenerationConditionTestCase, self).tearDown()
|
||||||
|
|
||||||
|
class OfflineGenerationTemplateTagTestCase(OfflineTestCaseMixin, TestCase):
|
||||||
|
templates_dir = "test_templatetag"
|
||||||
|
expected_hash = "a27e1d3a619a"
|
||||||
|
|
||||||
|
class OfflineGenerationTestCaseWithContext(OfflineTestCaseMixin, TestCase):
|
||||||
|
templates_dir = "test_with_context"
|
||||||
|
expected_hash = "5838e2fd66af"
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
||||||
|
settings.COMPRESS_OFFLINE_CONTEXT = {
|
||||||
|
'content': 'OK!',
|
||||||
|
}
|
||||||
|
super(OfflineGenerationTestCaseWithContext, self).setUp()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
||||||
|
super(OfflineGenerationTestCaseWithContext, self).tearDown()
|
||||||
|
|
||||||
|
class OfflineGenerationTestCaseErrors(OfflineTestCaseMixin, TestCase):
|
||||||
|
templates_dir = "test_error_handling"
|
||||||
|
expected_hash = "cd8870829421"
|
||||||
|
|
||||||
|
class OfflineGenerationTestCase(OfflineTestCaseMixin, TestCase):
|
||||||
|
templates_dir = "basic"
|
||||||
|
expected_hash = "f5e179b8eca4"
|
||||||
|
|
||||||
def test_rendering_without_compressing_raises_exception(self):
|
def test_rendering_without_compressing_raises_exception(self):
|
||||||
self.assertRaises(OfflineGenerationError,
|
self.assertRaises(OfflineGenerationError,
|
||||||
self.template.render, Context({}))
|
self.template.render, Context({}))
|
||||||
@@ -38,40 +115,6 @@ class OfflineGenerationTestCase(TestCase):
|
|||||||
def test_requires_model_validation(self):
|
def test_requires_model_validation(self):
|
||||||
self.assertFalse(CompressCommand.requires_model_validation)
|
self.assertFalse(CompressCommand.requires_model_validation)
|
||||||
|
|
||||||
def test_offline(self):
|
|
||||||
count, result = CompressCommand().compress()
|
|
||||||
self.assertEqual(6, count)
|
|
||||||
self.assertEqual([
|
|
||||||
css_tag('/media/CACHE/css/cd579b7deb7d.css'),
|
|
||||||
u'<script type="text/javascript" src="/media/CACHE/js/0a2bb9a287c0.js"></script>',
|
|
||||||
u'<script type="text/javascript" src="/media/CACHE/js/fb1736ad48b7.js"></script>',
|
|
||||||
u'<script type="text/javascript" src="/media/CACHE/js/1a63aacfe9de.js"></script>',
|
|
||||||
u'<script type="text/javascript" src="/media/CACHE/js/770a7311729e.js"></script>',
|
|
||||||
u'<link rel="stylesheet" href="/media/CACHE/css/67ed6aff7f7b.css" type="text/css" />',
|
|
||||||
], result)
|
|
||||||
|
|
||||||
def test_offline_with_context(self):
|
|
||||||
self._old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
|
||||||
settings.COMPRESS_OFFLINE_CONTEXT = {
|
|
||||||
'color': 'blue',
|
|
||||||
'condition': 'red',
|
|
||||||
}
|
|
||||||
count, result = CompressCommand().compress()
|
|
||||||
self.assertEqual(6, count)
|
|
||||||
self.assertEqual([
|
|
||||||
css_tag('/media/CACHE/css/ee62fbfd116a.css'),
|
|
||||||
u'<script type="text/javascript" src="/media/CACHE/js/0a2bb9a287c0.js"></script>',
|
|
||||||
u'<script type="text/javascript" src="/media/CACHE/js/fb1736ad48b7.js"></script>',
|
|
||||||
u'<script type="text/javascript" src="/media/CACHE/js/4e3758d50224.js"></script>',
|
|
||||||
u'<script type="text/javascript" src="/media/CACHE/js/770a7311729e.js"></script>',
|
|
||||||
u'<link rel="stylesheet" href="/media/CACHE/css/73e015f740c6.css" type="text/css" />',
|
|
||||||
], result)
|
|
||||||
# Template rendering should use the cache. FIXME: how to make sure of it ? Should we test the cache
|
|
||||||
# key<->values ourselves?
|
|
||||||
rendered_template = self.template.render(Context(settings.COMPRESS_OFFLINE_CONTEXT)).replace("\n", "")
|
|
||||||
self.assertEqual(rendered_template, "".join(result).replace("\n", ""))
|
|
||||||
settings.COMPRESS_OFFLINE_CONTEXT = self._old_offline_context
|
|
||||||
|
|
||||||
def test_get_loaders(self):
|
def test_get_loaders(self):
|
||||||
old_loaders = settings.TEMPLATE_LOADERS
|
old_loaders = settings.TEMPLATE_LOADERS
|
||||||
settings.TEMPLATE_LOADERS = (
|
settings.TEMPLATE_LOADERS = (
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
.add { background-image: url("../img/add.png"); }
|
|
||||||
.python { background-image: url("../img/python.png"); }
|
|
||||||
.datauri { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0 vr4MkhoXe0rZigAAAABJRU5ErkJggg=="); }
|
|
@@ -1 +0,0 @@
|
|||||||
.byline:before { content: " — "; }
|
|
@@ -1 +0,0 @@
|
|||||||
body { background:#990; }
|
|
@@ -1 +0,0 @@
|
|||||||
body { color:#fff; }
|
|
@@ -1,4 +0,0 @@
|
|||||||
p { background: url('../../../img/add.png'); }
|
|
||||||
p { background: url(../../../img/add.png); }
|
|
||||||
p { background: url( ../../../img/add.png ); }
|
|
||||||
p { background: url( '../../../img/add.png' ); }
|
|
@@ -1,2 +0,0 @@
|
|||||||
p { background: url( '../../images/test.png' ); }
|
|
||||||
.byline:before { content: " — "; }
|
|
@@ -1 +0,0 @@
|
|||||||
p { background: url('/media/images/image.gif') }
|
|
@@ -1,4 +0,0 @@
|
|||||||
p { background: url('../../img/python.png'); }
|
|
||||||
p { background: url(../../img/python.png); }
|
|
||||||
p { background: url( ../../img/python.png ); }
|
|
||||||
p { background: url( '../../img/python.png' ); }
|
|
Binary file not shown.
Before Width: | Height: | Size: 733 B |
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
@@ -1 +0,0 @@
|
|||||||
var test_value = "<22>berstr<74>ng";
|
|
@@ -1 +0,0 @@
|
|||||||
var test_value = "—";
|
|
@@ -1 +0,0 @@
|
|||||||
# this is a comment.
|
|
@@ -1 +0,0 @@
|
|||||||
obj = {};
|
|
@@ -1,34 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
from __future__ import with_statement
|
|
||||||
import optparse
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def main():
|
|
||||||
p = optparse.OptionParser()
|
|
||||||
p.add_option('-f', '--file', action="store",
|
|
||||||
type="string", dest="filename",
|
|
||||||
help="File to read from, defaults to stdin", default=None)
|
|
||||||
p.add_option('-o', '--output', action="store",
|
|
||||||
type="string", dest="outfile",
|
|
||||||
help="File to write to, defaults to stdout", default=None)
|
|
||||||
|
|
||||||
options, arguments = p.parse_args()
|
|
||||||
|
|
||||||
if options.filename:
|
|
||||||
f = open(options.filename)
|
|
||||||
content = f.read()
|
|
||||||
f.close()
|
|
||||||
else:
|
|
||||||
content = sys.stdin.read()
|
|
||||||
|
|
||||||
content = content.replace('background:', 'color:')
|
|
||||||
|
|
||||||
if options.outfile:
|
|
||||||
with open(options.outfile, 'w') as f:
|
|
||||||
f.write(content)
|
|
||||||
else:
|
|
||||||
print content
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@@ -1,35 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
|
|
||||||
COMPRESS_CACHE_BACKEND = 'locmem://'
|
|
||||||
|
|
||||||
DATABASE_ENGINE = 'sqlite3'
|
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
|
||||||
'django.contrib.contenttypes',
|
|
||||||
'django.contrib.sites',
|
|
||||||
'django.contrib.auth',
|
|
||||||
'django.contrib.admin',
|
|
||||||
'django_jenkins',
|
|
||||||
'compressor',
|
|
||||||
'tests',
|
|
||||||
]
|
|
||||||
|
|
||||||
MEDIA_URL = '/media/'
|
|
||||||
|
|
||||||
MEDIA_ROOT = os.path.join(TEST_DIR, 'media')
|
|
||||||
|
|
||||||
TEMPLATE_DIRS = (
|
|
||||||
# Specifically choose a name that will not be considered
|
|
||||||
# by app_directories loader, to make sure each test uses
|
|
||||||
# a specific template without considering the others.
|
|
||||||
os.path.join(TEST_DIR, 'test_templates'),
|
|
||||||
)
|
|
||||||
|
|
||||||
JENKINS_TASKS = (
|
|
||||||
'django_jenkins.tasks.run_pyflakes',
|
|
||||||
'django_jenkins.tasks.run_pep8',
|
|
||||||
'django_jenkins.tasks.with_coverage',
|
|
||||||
'django_jenkins.tasks.django_tests',
|
|
||||||
)
|
|
@@ -1,12 +0,0 @@
|
|||||||
{% load compress %}
|
|
||||||
|
|
||||||
{% compress css %}
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
background: pink;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endcompress %}
|
|
||||||
|
|
||||||
|
|
||||||
{% fail %}
|
|
@@ -1,10 +0,0 @@
|
|||||||
{% extends "missing.html" %}
|
|
||||||
{% load compress %}
|
|
||||||
|
|
||||||
{% compress css %}
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
background: purple;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endcompress %}
|
|
@@ -1,18 +0,0 @@
|
|||||||
from .base import (CompressorTestCase, CssMediaTestCase, VerboseTestCase,
|
|
||||||
CacheBackendTestCase)
|
|
||||||
from .filters import (CssTidyTestCase, PrecompilerTestCase, CssMinTestCase,
|
|
||||||
CssAbsolutizingTestCase, CssAbsolutizingTestCaseWithHash,
|
|
||||||
CssDataUriTestCase)
|
|
||||||
from .jinja2ext import TestJinja2CompressorExtension
|
|
||||||
from .offline import (
|
|
||||||
OfflineGenerationBlockSuperTestCase,
|
|
||||||
OfflineGenerationConditionTestCase,
|
|
||||||
OfflineGenerationTemplateTagTestCase,
|
|
||||||
OfflineGenerationTestCaseWithContext,
|
|
||||||
OfflineGenerationTestCaseErrors,
|
|
||||||
OfflineGenerationTestCase)
|
|
||||||
from .parsers import (LxmlParserTests, Html5LibParserTests,
|
|
||||||
BeautifulSoupParserTests, HtmlParserTests)
|
|
||||||
from .signals import PostCompressSignalTestCase
|
|
||||||
from .storages import StorageTestCase
|
|
||||||
from .templatetags import TemplatetagTestCase, PrecompilerTemplatetagTestCase
|
|
@@ -1,172 +0,0 @@
|
|||||||
from __future__ import with_statement
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
|
|
||||||
from BeautifulSoup import BeautifulSoup
|
|
||||||
|
|
||||||
from django.core.cache.backends import locmem
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from compressor.base import SOURCE_HUNK, SOURCE_FILE
|
|
||||||
from compressor.conf import settings
|
|
||||||
from compressor.css import CssCompressor
|
|
||||||
from compressor.js import JsCompressor
|
|
||||||
|
|
||||||
|
|
||||||
def css_tag(href, **kwargs):
|
|
||||||
rendered_attrs = ''.join(['%s="%s" ' % (k, v) for k, v in kwargs.items()])
|
|
||||||
template = u'<link rel="stylesheet" href="%s" type="text/css" %s/>'
|
|
||||||
return template % (href, rendered_attrs)
|
|
||||||
|
|
||||||
|
|
||||||
test_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
|
|
||||||
|
|
||||||
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 CssMediaTestCase(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.css = """\
|
|
||||||
<link rel="stylesheet" href="/media/css/one.css" type="text/css" media="screen">
|
|
||||||
<style type="text/css" media="print">p { border:5px solid green;}</style>
|
|
||||||
<link rel="stylesheet" href="/media/css/two.css" type="text/css" media="all">
|
|
||||||
<style type="text/css">h1 { border:5px solid green;}</style>"""
|
|
||||||
self.css_node = CssCompressor(self.css)
|
|
||||||
|
|
||||||
def test_css_output(self):
|
|
||||||
links = BeautifulSoup(self.css_node.output()).findAll('link')
|
|
||||||
media = [u'screen', u'print', u'all', None]
|
|
||||||
self.assertEqual(len(links), 4)
|
|
||||||
self.assertEqual(media, [l.get('media', None) for l in links])
|
|
||||||
|
|
||||||
def test_avoid_reordering_css(self):
|
|
||||||
css = self.css + '<style type="text/css" media="print">p { border:10px solid red;}</style>'
|
|
||||||
node = CssCompressor(css)
|
|
||||||
media = [u'screen', u'print', u'all', None, u'print']
|
|
||||||
links = BeautifulSoup(node.output()).findAll('link')
|
|
||||||
self.assertEqual(media, [l.get('media', None) for l in links])
|
|
||||||
|
|
||||||
|
|
||||||
class VerboseTestCase(CompressorTestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(VerboseTestCase, self).setUp()
|
|
||||||
settings.COMPRESS_VERBOSE = True
|
|
||||||
|
|
||||||
|
|
||||||
class CacheBackendTestCase(CompressorTestCase):
|
|
||||||
|
|
||||||
def test_correct_backend(self):
|
|
||||||
from compressor.cache import cache
|
|
||||||
self.assertEqual(cache.__class__, locmem.CacheClass)
|
|
@@ -1,201 +0,0 @@
|
|||||||
from __future__ import with_statement
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from unittest2 import skipIf
|
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from compressor.cache import get_hashed_mtime, get_hashed_content
|
|
||||||
from compressor.conf import settings
|
|
||||||
from compressor.css import CssCompressor
|
|
||||||
from compressor.utils import find_command
|
|
||||||
from compressor.filters.base import CompilerFilter
|
|
||||||
from compressor.filters.cssmin import CSSMinFilter
|
|
||||||
from compressor.filters.css_default import CssAbsoluteFilter
|
|
||||||
|
|
||||||
from .base import test_dir
|
|
||||||
|
|
||||||
|
|
||||||
class CssTidyTestCase(TestCase):
|
|
||||||
def test_tidy(self):
|
|
||||||
content = """
|
|
||||||
/* Some comment */
|
|
||||||
font,th,td,p{
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
from compressor.filters.csstidy import CSSTidyFilter
|
|
||||||
self.assertEqual(
|
|
||||||
"font,th,td,p{color:#000;}", CSSTidyFilter(content).input())
|
|
||||||
|
|
||||||
CssTidyTestCase = skipIf(
|
|
||||||
find_command(settings.COMPRESS_CSSTIDY_BINARY) is None,
|
|
||||||
'CSStidy binary %r not found' % settings.COMPRESS_CSSTIDY_BINARY
|
|
||||||
)(CssTidyTestCase)
|
|
||||||
|
|
||||||
|
|
||||||
class PrecompilerTestCase(TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.filename = os.path.join(test_dir, 'media/css/one.css')
|
|
||||||
with open(self.filename) as f:
|
|
||||||
self.content = f.read()
|
|
||||||
self.test_precompiler = os.path.join(test_dir, 'precompiler.py')
|
|
||||||
|
|
||||||
def test_precompiler_infile_outfile(self):
|
|
||||||
command = '%s %s -f {infile} -o {outfile}' % (sys.executable, self.test_precompiler)
|
|
||||||
compiler = CompilerFilter(content=self.content, filename=self.filename, command=command)
|
|
||||||
self.assertEqual(u"body { color:#990; }", compiler.input())
|
|
||||||
|
|
||||||
def test_precompiler_infile_stdout(self):
|
|
||||||
command = '%s %s -f {infile}' % (sys.executable, self.test_precompiler)
|
|
||||||
compiler = CompilerFilter(content=self.content, filename=None, command=command)
|
|
||||||
self.assertEqual(u"body { color:#990; }%s" % os.linesep, compiler.input())
|
|
||||||
|
|
||||||
def test_precompiler_stdin_outfile(self):
|
|
||||||
command = '%s %s -o {outfile}' % (sys.executable, self.test_precompiler)
|
|
||||||
compiler = CompilerFilter(content=self.content, filename=None, command=command)
|
|
||||||
self.assertEqual(u"body { color:#990; }", compiler.input())
|
|
||||||
|
|
||||||
def test_precompiler_stdin_stdout(self):
|
|
||||||
command = '%s %s' % (sys.executable, self.test_precompiler)
|
|
||||||
compiler = CompilerFilter(content=self.content, filename=None, command=command)
|
|
||||||
self.assertEqual(u"body { color:#990; }%s" % os.linesep, compiler.input())
|
|
||||||
|
|
||||||
def test_precompiler_stdin_stdout_filename(self):
|
|
||||||
command = '%s %s' % (sys.executable, self.test_precompiler)
|
|
||||||
compiler = CompilerFilter(content=self.content, filename=self.filename, command=command)
|
|
||||||
self.assertEqual(u"body { color:#990; }%s" % os.linesep, compiler.input())
|
|
||||||
|
|
||||||
|
|
||||||
class CssMinTestCase(TestCase):
|
|
||||||
def test_cssmin_filter(self):
|
|
||||||
content = """p {
|
|
||||||
|
|
||||||
|
|
||||||
background: rgb(51,102,153) url('../../images/image.gif');
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
output = "p{background:#369 url('../../images/image.gif')}"
|
|
||||||
self.assertEqual(output, CSSMinFilter(content).output())
|
|
||||||
|
|
||||||
|
|
||||||
class CssAbsolutizingTestCase(TestCase):
|
|
||||||
hashing_method = 'mtime'
|
|
||||||
hashing_func = staticmethod(get_hashed_mtime)
|
|
||||||
content = "p { background: url('../../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')
|
|
||||||
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename))
|
|
||||||
filter = CssAbsoluteFilter(self.content)
|
|
||||||
self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css'))
|
|
||||||
settings.COMPRESS_URL = 'http://media.example.com/'
|
|
||||||
filter = CssAbsoluteFilter(self.content)
|
|
||||||
filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css')
|
|
||||||
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename))
|
|
||||||
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')
|
|
||||||
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename))
|
|
||||||
filter = CssAbsoluteFilter(self.content)
|
|
||||||
self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css'))
|
|
||||||
settings.COMPRESS_URL = 'https://media.example.com/'
|
|
||||||
filter = CssAbsoluteFilter(self.content)
|
|
||||||
filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css')
|
|
||||||
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename))
|
|
||||||
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')
|
|
||||||
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename))
|
|
||||||
filter = CssAbsoluteFilter(self.content)
|
|
||||||
self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css'))
|
|
||||||
settings.COMPRESS_URL = 'https://media.example.com/'
|
|
||||||
filter = CssAbsoluteFilter(self.content)
|
|
||||||
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename))
|
|
||||||
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'); }
|
|
||||||
""" % 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'); }
|
|
||||||
""" % 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 CssAbsolutizingTestCaseWithHash(CssAbsolutizingTestCase):
|
|
||||||
hashing_method = 'content'
|
|
||||||
hashing_func = staticmethod(get_hashed_content)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(CssAbsolutizingTestCaseWithHash, self).setUp()
|
|
||||||
self.css = """
|
|
||||||
<link rel="stylesheet" href="/media/css/url/url1.css" type="text/css" charset="utf-8">
|
|
||||||
<link rel="stylesheet" href="/media/css/url/2/url2.css" type="text/css" charset="utf-8">
|
|
||||||
"""
|
|
||||||
self.css_node = CssCompressor(self.css)
|
|
||||||
|
|
||||||
|
|
||||||
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 = '/media/'
|
|
||||||
settings.COMPRESS_CSS_HASHING_METHOD = 'mtime'
|
|
||||||
self.css = """
|
|
||||||
<link rel="stylesheet" href="/media/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, 'css/datauri.css'))
|
|
||||||
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=="); }\n.python { background-image: url("/media/img/python.png?%s"); }\n.datauri { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0 vr4MkhoXe0rZigAAAABJRU5ErkJggg=="); }\n' % datauri_hash]
|
|
||||||
self.assertEqual(out, list(self.css_node.hunks()))
|
|
@@ -1,126 +0,0 @@
|
|||||||
from __future__ import with_statement
|
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
import jinja2
|
|
||||||
|
|
||||||
from compressor.conf import settings
|
|
||||||
|
|
||||||
from .base import css_tag
|
|
||||||
|
|
||||||
|
|
||||||
class TestJinja2CompressorExtension(TestCase):
|
|
||||||
"""
|
|
||||||
Test case for jinja2 extension.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
At tests we need to make some extra care about whitespace. Please note
|
|
||||||
that we use jinja2 specific controls (*minus* character at block's
|
|
||||||
beginning or end). For more information see jinja2 documentation.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def assertStrippedEqual(self, result, expected):
|
|
||||||
self.assertEqual(result.strip(), expected.strip(), "%r != %r" % (
|
|
||||||
result.strip(), expected.strip()))
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
from compressor.contrib.jinja2ext import CompressorExtension
|
|
||||||
self.env = jinja2.Environment(extensions=[CompressorExtension])
|
|
||||||
|
|
||||||
def test_error_raised_if_no_arguments_given(self):
|
|
||||||
self.assertRaises(jinja2.exceptions.TemplateSyntaxError,
|
|
||||||
self.env.from_string, '{% compress %}Foobar{% endcompress %}')
|
|
||||||
|
|
||||||
def test_error_raised_if_wrong_kind_given(self):
|
|
||||||
self.assertRaises(jinja2.exceptions.TemplateSyntaxError,
|
|
||||||
self.env.from_string, '{% compress foo %}Foobar{% endcompress %}')
|
|
||||||
|
|
||||||
def test_error_raised_if_wrong_mode_given(self):
|
|
||||||
self.assertRaises(jinja2.exceptions.TemplateSyntaxError,
|
|
||||||
self.env.from_string, '{% compress css foo %}Foobar{% endcompress %}')
|
|
||||||
|
|
||||||
def test_compress_is_disabled(self):
|
|
||||||
org_COMPRESS_ENABLED = settings.COMPRESS_ENABLED
|
|
||||||
settings.COMPRESS_ENABLED = False
|
|
||||||
tag_body = '\n'.join([
|
|
||||||
'<link rel="stylesheet" href="css/one.css" type="text/css" charset="utf-8">',
|
|
||||||
'<style type="text/css">p { border:5px solid green;}</style>',
|
|
||||||
'<link rel="stylesheet" href="css/two.css" type="text/css" charset="utf-8">',
|
|
||||||
])
|
|
||||||
template_string = '{% compress css %}' + tag_body + '{% endcompress %}'
|
|
||||||
template = self.env.from_string(template_string)
|
|
||||||
self.assertEqual(tag_body, template.render())
|
|
||||||
settings.COMPRESS_ENABLED = org_COMPRESS_ENABLED
|
|
||||||
|
|
||||||
def test_empty_tag(self):
|
|
||||||
template = self.env.from_string(u"""{% compress js %}{% block js %}
|
|
||||||
{% endblock %}{% endcompress %}""")
|
|
||||||
context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
self.assertEqual(u'', template.render(context))
|
|
||||||
|
|
||||||
def test_css_tag(self):
|
|
||||||
template = self.env.from_string(u"""{% compress css -%}
|
|
||||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/one.css" type="text/css" charset="utf-8">
|
|
||||||
<style type="text/css">p { border:5px solid green;}</style>
|
|
||||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/two.css" type="text/css" charset="utf-8">
|
|
||||||
{% endcompress %}""")
|
|
||||||
context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
out = css_tag("/media/CACHE/css/e41ba2cc6982.css")
|
|
||||||
self.assertEqual(out, template.render(context))
|
|
||||||
|
|
||||||
def test_nonascii_css_tag(self):
|
|
||||||
template = self.env.from_string(u"""{% compress css -%}
|
|
||||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/nonasc.css" type="text/css" charset="utf-8">
|
|
||||||
<style type="text/css">p { border:5px solid green;}</style>
|
|
||||||
{% endcompress %}""")
|
|
||||||
context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
out = css_tag("/media/CACHE/css/799f6defe43c.css")
|
|
||||||
self.assertEqual(out, template.render(context))
|
|
||||||
|
|
||||||
def test_js_tag(self):
|
|
||||||
template = self.env.from_string(u"""{% compress js -%}
|
|
||||||
<script src="{{ MEDIA_URL }}js/one.js" type="text/javascript" charset="utf-8"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">obj.value = "value";</script>
|
|
||||||
{% endcompress %}""")
|
|
||||||
context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
out = u'<script type="text/javascript" src="/media/CACHE/js/066cd253eada.js"></script>'
|
|
||||||
self.assertEqual(out, template.render(context))
|
|
||||||
|
|
||||||
def test_nonascii_js_tag(self):
|
|
||||||
template = self.env.from_string(u"""{% compress js -%}
|
|
||||||
<script src="{{ MEDIA_URL }}js/nonasc.js" type="text/javascript" charset="utf-8"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">var test_value = "\u2014";</script>
|
|
||||||
{% endcompress %}""")
|
|
||||||
context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
out = u'<script type="text/javascript" src="/media/CACHE/js/e214fe629b28.js"></script>'
|
|
||||||
self.assertEqual(out, template.render(context))
|
|
||||||
|
|
||||||
def test_nonascii_latin1_js_tag(self):
|
|
||||||
template = self.env.from_string(u"""{% compress js -%}
|
|
||||||
<script src="{{ MEDIA_URL }}js/nonasc-latin1.js" type="text/javascript" charset="latin-1"></script>
|
|
||||||
<script type="text/javascript">var test_value = "\u2014";</script>
|
|
||||||
{% endcompress %}""")
|
|
||||||
context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
out = u'<script type="text/javascript" src="/media/CACHE/js/be9e078b5ca7.js"></script>'
|
|
||||||
self.assertEqual(out, template.render(context))
|
|
||||||
|
|
||||||
def test_css_inline(self):
|
|
||||||
template = self.env.from_string(u"""{% compress css, inline -%}
|
|
||||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/one.css" type="text/css" charset="utf-8">
|
|
||||||
<style type="text/css">p { border:5px solid green;}</style>
|
|
||||||
{% endcompress %}""")
|
|
||||||
context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
out = '\n'.join([
|
|
||||||
'<style type="text/css">body { background:#990; }',
|
|
||||||
'p { border:5px solid green;}</style>',
|
|
||||||
])
|
|
||||||
self.assertEqual(out, template.render(context))
|
|
||||||
|
|
||||||
def test_js_inline(self):
|
|
||||||
template = self.env.from_string(u"""{% compress js, inline -%}
|
|
||||||
<script src="{{ MEDIA_URL }}js/one.js" type="text/css" type="text/javascript" charset="utf-8"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">obj.value = "value";</script>
|
|
||||||
{% endcompress %}""")
|
|
||||||
context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
out = '<script type="text/javascript">obj={};obj.value="value";</script>'
|
|
||||||
self.assertEqual(out, template.render(context))
|
|
@@ -1,136 +0,0 @@
|
|||||||
from __future__ import with_statement
|
|
||||||
import os
|
|
||||||
|
|
||||||
try:
|
|
||||||
from cStringIO import StringIO
|
|
||||||
except ImportError:
|
|
||||||
from StringIO import StringIO
|
|
||||||
|
|
||||||
from django.template import Template, Context
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from compressor.conf import settings
|
|
||||||
from compressor.exceptions import OfflineGenerationError
|
|
||||||
from compressor.management.commands.compress import Command as CompressCommand
|
|
||||||
from compressor.storage import default_storage
|
|
||||||
|
|
||||||
from .base import css_tag
|
|
||||||
|
|
||||||
class OfflineTestCaseMixin():
|
|
||||||
template_name = "test_compressor_offline.html"
|
|
||||||
templates_dir = "" # Change this for each test class, to separate templates
|
|
||||||
expected_hash = "" # Change this for each test class to the expected result
|
|
||||||
verbosity = 0
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self._old_compress = settings.COMPRESS_ENABLED
|
|
||||||
self._old_compress_offline = settings.COMPRESS_OFFLINE
|
|
||||||
self._old_template_dirs = settings.TEMPLATE_DIRS
|
|
||||||
self._old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
|
||||||
self._old_template_loaders = settings.TEMPLATE_LOADERS
|
|
||||||
self.log = StringIO()
|
|
||||||
|
|
||||||
# Force template dirs, because it enables us to force compress to
|
|
||||||
# consider only a specific directory (helps us make true,
|
|
||||||
# independant unit tests).
|
|
||||||
settings.TEMPLATE_DIRS = (
|
|
||||||
os.path.join(settings.TEMPLATE_DIRS[0], self.templates_dir),
|
|
||||||
)
|
|
||||||
# Enable offline compress
|
|
||||||
settings.COMPRESS_ENABLED = True
|
|
||||||
settings.COMPRESS_OFFLINE = True
|
|
||||||
self.template_path = os.path.join(settings.TEMPLATE_DIRS[0], self.template_name)
|
|
||||||
self.template_file = open(self.template_path)
|
|
||||||
self.template = Template(self.template_file.read().decode(settings.FILE_CHARSET))
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
settings.COMPRESS_ENABLED = self._old_compress
|
|
||||||
settings.COMPRESS_OFFLINE = self._old_compress_offline
|
|
||||||
settings.TEMPLATE_DIRS = self._old_template_dirs
|
|
||||||
settings.TEMPLATE_LOADERS = self._old_template_loaders
|
|
||||||
self.template_file.close()
|
|
||||||
manifest_path = os.path.join('CACHE', 'manifest.json')
|
|
||||||
if default_storage.exists(manifest_path):
|
|
||||||
default_storage.delete(manifest_path)
|
|
||||||
|
|
||||||
def test_offline(self):
|
|
||||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity)
|
|
||||||
self.assertEqual(1, count)
|
|
||||||
self.assertEqual([
|
|
||||||
u'<script type="text/javascript" src="/media/CACHE/js/%s.js"></script>' % (self.expected_hash, ),
|
|
||||||
], result)
|
|
||||||
rendered_template = self.template.render(Context(settings.COMPRESS_OFFLINE_CONTEXT))
|
|
||||||
self.assertEqual(rendered_template, "".join(result) + "\n")
|
|
||||||
|
|
||||||
class OfflineGenerationBlockSuperTestCase(OfflineTestCaseMixin, TestCase):
|
|
||||||
templates_dir = "test_block_super"
|
|
||||||
expected_hash = "7c02d201f69d"
|
|
||||||
|
|
||||||
class OfflineGenerationConditionTestCase(OfflineTestCaseMixin, TestCase):
|
|
||||||
templates_dir = "test_condition"
|
|
||||||
expected_hash = "4e3758d50224"
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
|
||||||
settings.COMPRESS_OFFLINE_CONTEXT = {
|
|
||||||
'condition': 'red',
|
|
||||||
}
|
|
||||||
super(OfflineGenerationConditionTestCase, self).setUp()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
|
||||||
super(OfflineGenerationConditionTestCase, self).tearDown()
|
|
||||||
|
|
||||||
class OfflineGenerationTemplateTagTestCase(OfflineTestCaseMixin, TestCase):
|
|
||||||
templates_dir = "test_templatetag"
|
|
||||||
expected_hash = "a27e1d3a619a"
|
|
||||||
|
|
||||||
class OfflineGenerationTestCaseWithContext(OfflineTestCaseMixin, TestCase):
|
|
||||||
templates_dir = "test_with_context"
|
|
||||||
expected_hash = "5838e2fd66af"
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
|
||||||
settings.COMPRESS_OFFLINE_CONTEXT = {
|
|
||||||
'content': 'OK!',
|
|
||||||
}
|
|
||||||
super(OfflineGenerationTestCaseWithContext, self).setUp()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
|
||||||
super(OfflineGenerationTestCaseWithContext, self).tearDown()
|
|
||||||
|
|
||||||
class OfflineGenerationTestCaseErrors(OfflineTestCaseMixin, TestCase):
|
|
||||||
templates_dir = "test_error_handling"
|
|
||||||
expected_hash = "cd8870829421"
|
|
||||||
|
|
||||||
class OfflineGenerationTestCase(OfflineTestCaseMixin, TestCase):
|
|
||||||
templates_dir = "basic"
|
|
||||||
expected_hash = "f5e179b8eca4"
|
|
||||||
|
|
||||||
def test_rendering_without_compressing_raises_exception(self):
|
|
||||||
self.assertRaises(OfflineGenerationError,
|
|
||||||
self.template.render, Context({}))
|
|
||||||
|
|
||||||
def test_requires_model_validation(self):
|
|
||||||
self.assertFalse(CompressCommand.requires_model_validation)
|
|
||||||
|
|
||||||
def test_get_loaders(self):
|
|
||||||
old_loaders = settings.TEMPLATE_LOADERS
|
|
||||||
settings.TEMPLATE_LOADERS = (
|
|
||||||
('django.template.loaders.cached.Loader', (
|
|
||||||
'django.template.loaders.filesystem.Loader',
|
|
||||||
'django.template.loaders.app_directories.Loader',
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
from django.template.loaders.filesystem import Loader as FileSystemLoader
|
|
||||||
from django.template.loaders.app_directories import Loader as AppDirectoriesLoader
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
loaders = CompressCommand().get_loaders()
|
|
||||||
self.assertTrue(isinstance(loaders[0], FileSystemLoader))
|
|
||||||
self.assertTrue(isinstance(loaders[1], AppDirectoriesLoader))
|
|
||||||
finally:
|
|
||||||
settings.TEMPLATE_LOADERS = old_loaders
|
|
@@ -1,88 +0,0 @@
|
|||||||
from __future__ import with_statement
|
|
||||||
import os
|
|
||||||
from unittest2 import skipIf
|
|
||||||
|
|
||||||
try:
|
|
||||||
import lxml
|
|
||||||
except ImportError:
|
|
||||||
lxml = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
import html5lib
|
|
||||||
except ImportError:
|
|
||||||
html5lib = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
from BeautifulSoup import BeautifulSoup
|
|
||||||
except ImportError:
|
|
||||||
BeautifulSoup = None
|
|
||||||
|
|
||||||
|
|
||||||
from compressor.base import SOURCE_HUNK, SOURCE_FILE
|
|
||||||
from compressor.conf import settings
|
|
||||||
from compressor.css import CssCompressor
|
|
||||||
|
|
||||||
from .base import CompressorTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class ParserTestCase(object):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.old_parser = settings.COMPRESS_PARSER
|
|
||||||
settings.COMPRESS_PARSER = self.parser_cls
|
|
||||||
super(ParserTestCase, self).setUp()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
settings.COMPRESS_PARSER = self.old_parser
|
|
||||||
|
|
||||||
|
|
||||||
class LxmlParserTests(ParserTestCase, CompressorTestCase):
|
|
||||||
parser_cls = 'compressor.parser.LxmlParser'
|
|
||||||
LxmlParserTests = skipIf(lxml is None, 'lxml not found')(LxmlParserTests)
|
|
||||||
|
|
||||||
|
|
||||||
class Html5LibParserTests(ParserTestCase, CompressorTestCase):
|
|
||||||
parser_cls = 'compressor.parser.Html5LibParser'
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(Html5LibParserTests, self).setUp()
|
|
||||||
# special version of the css since the parser sucks
|
|
||||||
self.css = """\
|
|
||||||
<link href="/media/css/one.css" rel="stylesheet" type="text/css">
|
|
||||||
<style type="text/css">p { border:5px solid green;}</style>
|
|
||||||
<link href="/media/css/two.css" rel="stylesheet" type="text/css">"""
|
|
||||||
self.css_node = CssCompressor(self.css)
|
|
||||||
|
|
||||||
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 href="/media/css/one.css" rel="stylesheet" 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 href="/media/css/two.css" rel="stylesheet" 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_js_split(self):
|
|
||||||
out = [
|
|
||||||
(SOURCE_FILE, os.path.join(settings.COMPRESS_ROOT, u'js', u'one.js'), u'js/one.js', u'<script src="/media/js/one.js" type="text/javascript"></script>'),
|
|
||||||
(SOURCE_HUNK, u'obj.value = "value";', None, u'<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)
|
|
||||||
|
|
||||||
Html5LibParserTests = skipIf(
|
|
||||||
html5lib is None, 'html5lib not found')(Html5LibParserTests)
|
|
||||||
|
|
||||||
|
|
||||||
class BeautifulSoupParserTests(ParserTestCase, CompressorTestCase):
|
|
||||||
parser_cls = 'compressor.parser.BeautifulSoupParser'
|
|
||||||
|
|
||||||
BeautifulSoupParserTests = skipIf(
|
|
||||||
BeautifulSoup is None, 'BeautifulSoup not found')(BeautifulSoupParserTests)
|
|
||||||
|
|
||||||
|
|
||||||
class HtmlParserTests(ParserTestCase, CompressorTestCase):
|
|
||||||
parser_cls = 'compressor.parser.HtmlParser'
|
|
||||||
|
|
@@ -1,67 +0,0 @@
|
|||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from mock import Mock
|
|
||||||
|
|
||||||
from compressor.conf import settings
|
|
||||||
from compressor.css import CssCompressor
|
|
||||||
from compressor.js import JsCompressor
|
|
||||||
from compressor.signals import post_compress
|
|
||||||
|
|
||||||
|
|
||||||
class PostCompressSignalTestCase(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 tearDown(self):
|
|
||||||
post_compress.disconnect()
|
|
||||||
|
|
||||||
def test_js_signal_sent(self):
|
|
||||||
def listener(sender, **kwargs):
|
|
||||||
pass
|
|
||||||
callback = Mock(wraps=listener)
|
|
||||||
post_compress.connect(callback)
|
|
||||||
self.js_node.output()
|
|
||||||
args, kwargs = callback.call_args
|
|
||||||
self.assertEquals(JsCompressor, kwargs['sender'])
|
|
||||||
self.assertEquals('js', kwargs['type'])
|
|
||||||
self.assertEquals('file', kwargs['mode'])
|
|
||||||
context = kwargs['context']
|
|
||||||
assert 'url' in context['compressed']
|
|
||||||
|
|
||||||
def test_css_signal_sent(self):
|
|
||||||
def listener(sender, **kwargs):
|
|
||||||
pass
|
|
||||||
callback = Mock(wraps=listener)
|
|
||||||
post_compress.connect(callback)
|
|
||||||
self.css_node.output()
|
|
||||||
args, kwargs = callback.call_args
|
|
||||||
self.assertEquals(CssCompressor, kwargs['sender'])
|
|
||||||
self.assertEquals('css', kwargs['type'])
|
|
||||||
self.assertEquals('file', kwargs['mode'])
|
|
||||||
context = kwargs['context']
|
|
||||||
assert 'url' in context['compressed']
|
|
||||||
|
|
||||||
def test_css_signal_multiple_media_attributes(self):
|
|
||||||
css = """\
|
|
||||||
<link rel="stylesheet" href="/media/css/one.css" media="handheld" type="text/css" />
|
|
||||||
<style type="text/css" media="print">p { border:5px solid green;}</style>
|
|
||||||
<link rel="stylesheet" href="/media/css/two.css" type="text/css" />"""
|
|
||||||
css_node = CssCompressor(css)
|
|
||||||
def listener(sender, **kwargs):
|
|
||||||
pass
|
|
||||||
callback = Mock(wraps=listener)
|
|
||||||
post_compress.connect(callback)
|
|
||||||
css_node.output()
|
|
||||||
self.assertEquals(3, callback.call_count)
|
|
@@ -1,53 +0,0 @@
|
|||||||
from __future__ import with_statement
|
|
||||||
import errno
|
|
||||||
import os
|
|
||||||
|
|
||||||
from django.core.files.base import ContentFile
|
|
||||||
from django.core.files.storage import get_storage_class
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from compressor import base
|
|
||||||
from compressor.conf import settings
|
|
||||||
|
|
||||||
from .base import css_tag
|
|
||||||
from .templatetags import render
|
|
||||||
|
|
||||||
|
|
||||||
class StorageTestCase(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self._storage = base.default_storage
|
|
||||||
base.default_storage = get_storage_class(
|
|
||||||
'compressor.storage.GzipCompressorFileStorage')()
|
|
||||||
settings.COMPRESS_ENABLED = True
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
base.default_storage = self._storage
|
|
||||||
|
|
||||||
def test_css_tag_with_storage(self):
|
|
||||||
template = u"""{% load compress %}{% compress css %}
|
|
||||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/one.css" type="text/css">
|
|
||||||
<style type="text/css">p { border:5px solid white;}</style>
|
|
||||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/two.css" type="text/css">
|
|
||||||
{% endcompress %}
|
|
||||||
"""
|
|
||||||
context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
out = css_tag("/media/CACHE/css/1d4424458f88.css")
|
|
||||||
self.assertEqual(out, render(template, context))
|
|
||||||
|
|
||||||
def test_race_condition_handling(self):
|
|
||||||
# Hold on to original os.remove
|
|
||||||
original_remove = os.remove
|
|
||||||
|
|
||||||
def race_remove(path):
|
|
||||||
"Patched os.remove to raise ENOENT (No such file or directory)"
|
|
||||||
original_remove(path)
|
|
||||||
raise OSError(errno.ENOENT, u'Fake ENOENT')
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.remove = race_remove
|
|
||||||
self._storage.save('race.file', ContentFile('Fake ENOENT'))
|
|
||||||
self._storage.delete('race.file')
|
|
||||||
self.assertFalse(self._storage.exists('race.file'))
|
|
||||||
finally:
|
|
||||||
# Restore os.remove
|
|
||||||
os.remove = original_remove
|
|
@@ -1,238 +0,0 @@
|
|||||||
from __future__ import with_statement
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from mock import Mock
|
|
||||||
|
|
||||||
from django.template import Template, Context, TemplateSyntaxError
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from compressor.conf import settings
|
|
||||||
from compressor.signals import post_compress
|
|
||||||
|
|
||||||
from .base import css_tag, test_dir
|
|
||||||
|
|
||||||
|
|
||||||
def render(template_string, context_dict=None):
|
|
||||||
"""
|
|
||||||
A shortcut for testing template output.
|
|
||||||
"""
|
|
||||||
if context_dict is None:
|
|
||||||
context_dict = {}
|
|
||||||
c = Context(context_dict)
|
|
||||||
t = Template(template_string)
|
|
||||||
return t.render(c).strip()
|
|
||||||
|
|
||||||
|
|
||||||
class TemplatetagTestCase(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.old_enabled = settings.COMPRESS_ENABLED
|
|
||||||
settings.COMPRESS_ENABLED = True
|
|
||||||
self.context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
settings.COMPRESS_ENABLED = self.old_enabled
|
|
||||||
|
|
||||||
def test_empty_tag(self):
|
|
||||||
template = u"""{% load compress %}{% compress js %}{% block js %}
|
|
||||||
{% endblock %}{% endcompress %}"""
|
|
||||||
self.assertEqual(u'', render(template, self.context))
|
|
||||||
|
|
||||||
def test_css_tag(self):
|
|
||||||
template = u"""{% load compress %}{% compress css %}
|
|
||||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/one.css" type="text/css">
|
|
||||||
<style type="text/css">p { border:5px solid green;}</style>
|
|
||||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/two.css" type="text/css">
|
|
||||||
{% endcompress %}"""
|
|
||||||
out = css_tag("/media/CACHE/css/e41ba2cc6982.css")
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
|
|
||||||
def test_uppercase_rel(self):
|
|
||||||
template = u"""{% load compress %}{% compress css %}
|
|
||||||
<link rel="StyleSheet" href="{{ MEDIA_URL }}css/one.css" type="text/css">
|
|
||||||
<style type="text/css">p { border:5px solid green;}</style>
|
|
||||||
<link rel="StyleSheet" href="{{ MEDIA_URL }}css/two.css" type="text/css">
|
|
||||||
{% endcompress %}"""
|
|
||||||
out = css_tag("/media/CACHE/css/e41ba2cc6982.css")
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
|
|
||||||
def test_nonascii_css_tag(self):
|
|
||||||
template = u"""{% load compress %}{% compress css %}
|
|
||||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/nonasc.css" type="text/css">
|
|
||||||
<style type="text/css">p { border:5px solid green;}</style>
|
|
||||||
{% endcompress %}
|
|
||||||
"""
|
|
||||||
out = css_tag("/media/CACHE/css/799f6defe43c.css")
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
|
|
||||||
def test_js_tag(self):
|
|
||||||
template = u"""{% load compress %}{% compress js %}
|
|
||||||
<script src="{{ MEDIA_URL }}js/one.js" type="text/javascript"></script>
|
|
||||||
<script type="text/javascript">obj.value = "value";</script>
|
|
||||||
{% endcompress %}
|
|
||||||
"""
|
|
||||||
out = u'<script type="text/javascript" src="/media/CACHE/js/066cd253eada.js"></script>'
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
|
|
||||||
def test_nonascii_js_tag(self):
|
|
||||||
template = u"""{% load compress %}{% compress js %}
|
|
||||||
<script src="{{ MEDIA_URL }}js/nonasc.js" type="text/javascript"></script>
|
|
||||||
<script type="text/javascript">var test_value = "\u2014";</script>
|
|
||||||
{% endcompress %}
|
|
||||||
"""
|
|
||||||
out = u'<script type="text/javascript" src="/media/CACHE/js/e214fe629b28.js"></script>'
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
|
|
||||||
def test_nonascii_latin1_js_tag(self):
|
|
||||||
template = u"""{% load compress %}{% compress js %}
|
|
||||||
<script src="{{ MEDIA_URL }}js/nonasc-latin1.js" type="text/javascript" charset="latin-1"></script>
|
|
||||||
<script type="text/javascript">var test_value = "\u2014";</script>
|
|
||||||
{% endcompress %}
|
|
||||||
"""
|
|
||||||
out = u'<script type="text/javascript" src="/media/CACHE/js/be9e078b5ca7.js"></script>'
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
|
|
||||||
def test_compress_tag_with_illegal_arguments(self):
|
|
||||||
template = u"""{% load compress %}{% compress pony %}
|
|
||||||
<script type="pony/application">unicorn</script>
|
|
||||||
{% endcompress %}"""
|
|
||||||
self.assertRaises(TemplateSyntaxError, render, template, {})
|
|
||||||
|
|
||||||
def test_debug_toggle(self):
|
|
||||||
template = u"""{% load compress %}{% compress js %}
|
|
||||||
<script src="{{ MEDIA_URL }}js/one.js" type="text/javascript"></script>
|
|
||||||
<script type="text/javascript">obj.value = "value";</script>
|
|
||||||
{% endcompress %}
|
|
||||||
"""
|
|
||||||
class MockDebugRequest(object):
|
|
||||||
GET = {settings.COMPRESS_DEBUG_TOGGLE: 'true'}
|
|
||||||
context = dict(self.context, request=MockDebugRequest())
|
|
||||||
out = u"""<script src="/media/js/one.js" type="text/javascript"></script>
|
|
||||||
<script type="text/javascript">obj.value = "value";</script>"""
|
|
||||||
self.assertEqual(out, render(template, context))
|
|
||||||
|
|
||||||
def test_named_compress_tag(self):
|
|
||||||
template = u"""{% load compress %}{% compress js inline foo %}
|
|
||||||
<script type="text/javascript">obj.value = "value";</script>
|
|
||||||
{% endcompress %}
|
|
||||||
"""
|
|
||||||
def listener(sender, **kwargs):
|
|
||||||
pass
|
|
||||||
callback = Mock(wraps=listener)
|
|
||||||
post_compress.connect(callback)
|
|
||||||
render(template)
|
|
||||||
args, kwargs = callback.call_args
|
|
||||||
context = kwargs['context']
|
|
||||||
self.assertEqual('foo', context['compressed']['name'])
|
|
||||||
|
|
||||||
|
|
||||||
class PrecompilerTemplatetagTestCase(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.old_enabled = settings.COMPRESS_ENABLED
|
|
||||||
self.old_precompilers = settings.COMPRESS_PRECOMPILERS
|
|
||||||
|
|
||||||
precompiler = os.path.join(test_dir, 'precompiler.py')
|
|
||||||
python = sys.executable
|
|
||||||
|
|
||||||
settings.COMPRESS_ENABLED = True
|
|
||||||
settings.COMPRESS_PRECOMPILERS = (
|
|
||||||
('text/coffeescript', '%s %s' % (python, precompiler)),
|
|
||||||
)
|
|
||||||
self.context = {'MEDIA_URL': settings.COMPRESS_URL}
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
settings.COMPRESS_ENABLED = self.old_enabled
|
|
||||||
settings.COMPRESS_PRECOMPILERS = self.old_precompilers
|
|
||||||
|
|
||||||
def test_compress_coffeescript_tag(self):
|
|
||||||
template = u"""{% load compress %}{% compress js %}
|
|
||||||
<script type="text/coffeescript"># this is a comment.</script>
|
|
||||||
{% endcompress %}"""
|
|
||||||
out = script(src="/media/CACHE/js/e920d58f166d.js")
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
|
|
||||||
def test_compress_coffeescript_tag_and_javascript_tag(self):
|
|
||||||
template = u"""{% load compress %}{% compress js %}
|
|
||||||
<script type="text/coffeescript"># this is a comment.</script>
|
|
||||||
<script type="text/javascript"># this too is a comment.</script>
|
|
||||||
{% endcompress %}"""
|
|
||||||
out = script(src="/media/CACHE/js/ef6b32a54575.js")
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
|
|
||||||
def test_coffeescript_and_js_tag_with_compress_enabled_equals_false(self):
|
|
||||||
self.old_enabled = settings.COMPRESS_ENABLED
|
|
||||||
settings.COMPRESS_ENABLED = False
|
|
||||||
try:
|
|
||||||
template = u"""{% load compress %}{% compress js %}
|
|
||||||
<script type="text/coffeescript"># this is a comment.</script>
|
|
||||||
<script type="text/javascript"># this too is a comment.</script>
|
|
||||||
{% endcompress %}"""
|
|
||||||
out = (script('# this is a comment.\n') + '\n' +
|
|
||||||
script('# this too is a comment.'))
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
finally:
|
|
||||||
settings.COMPRESS_ENABLED = self.old_enabled
|
|
||||||
|
|
||||||
def test_compress_coffeescript_tag_compress_enabled_is_false(self):
|
|
||||||
self.old_enabled = settings.COMPRESS_ENABLED
|
|
||||||
settings.COMPRESS_ENABLED = False
|
|
||||||
try:
|
|
||||||
template = u"""{% load compress %}{% compress js %}
|
|
||||||
<script type="text/coffeescript"># this is a comment.</script>
|
|
||||||
{% endcompress %}"""
|
|
||||||
out = script("# this is a comment.\n")
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
finally:
|
|
||||||
settings.COMPRESS_ENABLED = self.old_enabled
|
|
||||||
|
|
||||||
def test_compress_coffeescript_file_tag_compress_enabled_is_false(self):
|
|
||||||
self.old_enabled = settings.COMPRESS_ENABLED
|
|
||||||
settings.COMPRESS_ENABLED = False
|
|
||||||
try:
|
|
||||||
template = u"""
|
|
||||||
{% load compress %}{% compress js %}
|
|
||||||
<script type="text/coffeescript" src="{{ MEDIA_URL }}js/one.coffee">
|
|
||||||
</script>
|
|
||||||
{% endcompress %}"""
|
|
||||||
|
|
||||||
out = script(src="/media/CACHE/js/one.95cfb869eead.js")
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
finally:
|
|
||||||
settings.COMPRESS_ENABLED = self.old_enabled
|
|
||||||
|
|
||||||
def test_multiple_file_order_conserved(self):
|
|
||||||
self.old_enabled = settings.COMPRESS_ENABLED
|
|
||||||
settings.COMPRESS_ENABLED = False
|
|
||||||
try:
|
|
||||||
template = u"""
|
|
||||||
{% load compress %}{% compress js %}
|
|
||||||
<script type="text/coffeescript" src="{{ MEDIA_URL }}js/one.coffee">
|
|
||||||
</script>
|
|
||||||
<script src="{{ MEDIA_URL }}js/one.js"></script>
|
|
||||||
<script type="text/coffeescript" src="{{ MEDIA_URL }}js/one.js">
|
|
||||||
</script>
|
|
||||||
{% endcompress %}"""
|
|
||||||
|
|
||||||
out = '\n'.join([
|
|
||||||
script(src="/media/CACHE/js/one.95cfb869eead.js"),
|
|
||||||
script(scripttype="", src="/media/js/one.js"),
|
|
||||||
script(src="/media/CACHE/js/one.81a2cd965815.js"),])
|
|
||||||
|
|
||||||
self.assertEqual(out, render(template, self.context))
|
|
||||||
finally:
|
|
||||||
settings.COMPRESS_ENABLED = self.old_enabled
|
|
||||||
|
|
||||||
def script(content="", src="", scripttype="text/javascript"):
|
|
||||||
"""
|
|
||||||
returns a unicode text html script element.
|
|
||||||
|
|
||||||
>>> script('#this is a comment', scripttype="text/applescript")
|
|
||||||
'<script type="text/applescript">#this is a comment</script>'
|
|
||||||
"""
|
|
||||||
out_script = u'<script '
|
|
||||||
if scripttype:
|
|
||||||
out_script += u'type="%s" ' % scripttype
|
|
||||||
if src:
|
|
||||||
out_script += u'src="%s" ' % src
|
|
||||||
return out_script[:-1] + u'>%s</script>' % content
|
|
Reference in New Issue
Block a user