Merge pull request #667 from diox/override_settings_in_tests
Refactor offline tests to make them always use override_settings
This commit is contained in:
@@ -30,7 +30,7 @@ else:
|
||||
# The Jinja2 tests fail on Python 3.2 due to the following:
|
||||
# The line in compressor/management/commands/compress.py:
|
||||
# compressor_nodes.setdefault(template, []).extend(nodes)
|
||||
# causes the error "unhashable type: 'Template'"
|
||||
# causes the error 'unhashable type: 'Template''
|
||||
_TEST_JINJA2 = not(sys.version_info[0] == 3 and sys.version_info[1] == 2)
|
||||
|
||||
|
||||
@@ -40,16 +40,17 @@ def offline_context_generator():
|
||||
|
||||
|
||||
class OfflineTestCaseMixin(object):
|
||||
template_name = "test_compressor_offline.html"
|
||||
template_name = 'test_compressor_offline.html'
|
||||
verbosity = 0
|
||||
# Change this for each test class
|
||||
templates_dir = ""
|
||||
expected_hash = ""
|
||||
templates_dir = ''
|
||||
expected_hash = ''
|
||||
# Engines to test
|
||||
if _TEST_JINJA2:
|
||||
engines = ("django", "jinja2")
|
||||
engines = ('django', 'jinja2')
|
||||
else:
|
||||
engines = ("django",)
|
||||
engines = ('django',)
|
||||
additional_test_settings = None
|
||||
|
||||
def setUp(self):
|
||||
self.log = StringIO()
|
||||
@@ -57,11 +58,13 @@ class OfflineTestCaseMixin(object):
|
||||
# Reset template dirs, because it enables us to force compress to
|
||||
# consider only a specific directory (helps us make true,
|
||||
# independent unit tests).
|
||||
# Specify both Jinja2 and Django template locations. When the wrong engine
|
||||
# is used to parse a template, the TemplateSyntaxError will cause the
|
||||
# template to be skipped over.
|
||||
django_template_dir = os.path.join(settings.TEST_DIR, 'test_templates', self.templates_dir)
|
||||
jinja2_template_dir = os.path.join(settings.TEST_DIR, 'test_templates_jinja2', self.templates_dir)
|
||||
# Specify both Jinja2 and Django template locations. When the wrong
|
||||
# engine is used to parse a template, the TemplateSyntaxError will
|
||||
# cause the template to be skipped over.
|
||||
django_template_dir = os.path.join(
|
||||
settings.TEST_DIR, 'test_templates', self.templates_dir)
|
||||
jinja2_template_dir = os.path.join(
|
||||
settings.TEST_DIR, 'test_templates_jinja2', self.templates_dir)
|
||||
|
||||
override_settings = {
|
||||
'TEMPLATE_DIRS': (django_template_dir, jinja2_template_dir,),
|
||||
@@ -69,24 +72,32 @@ class OfflineTestCaseMixin(object):
|
||||
'COMPRESS_OFFLINE': True
|
||||
}
|
||||
|
||||
if "jinja2" in self.engines:
|
||||
override_settings["COMPRESS_JINJA2_GET_ENVIRONMENT"] = lambda: self._get_jinja2_env()
|
||||
if 'jinja2' in self.engines:
|
||||
override_settings['COMPRESS_JINJA2_GET_ENVIRONMENT'] = (
|
||||
lambda: self._get_jinja2_env())
|
||||
|
||||
if self.additional_test_settings is not None:
|
||||
override_settings.update(self.additional_test_settings)
|
||||
|
||||
self.override_settings = self.settings(**override_settings)
|
||||
self.override_settings.__enter__()
|
||||
|
||||
if "django" in self.engines:
|
||||
self.template_path = os.path.join(django_template_dir, self.template_name)
|
||||
if 'django' in self.engines:
|
||||
self.template_path = os.path.join(
|
||||
django_template_dir, self.template_name)
|
||||
|
||||
with io.open(self.template_path, encoding=settings.FILE_CHARSET) as file:
|
||||
self.template = Template(file.read())
|
||||
with io.open(self.template_path,
|
||||
encoding=settings.FILE_CHARSET) as file_:
|
||||
self.template = Template(file_.read())
|
||||
|
||||
if "jinja2" in self.engines:
|
||||
jinja2_env = override_settings["COMPRESS_JINJA2_GET_ENVIRONMENT"]()
|
||||
self.template_path_jinja2 = os.path.join(jinja2_template_dir, self.template_name)
|
||||
if 'jinja2' in self.engines:
|
||||
self.template_path_jinja2 = os.path.join(
|
||||
jinja2_template_dir, self.template_name)
|
||||
jinja2_env = override_settings['COMPRESS_JINJA2_GET_ENVIRONMENT']()
|
||||
|
||||
with io.open(self.template_path_jinja2, encoding=settings.FILE_CHARSET) as file:
|
||||
self.template_jinja2 = jinja2_env.from_string(file.read())
|
||||
with io.open(self.template_path_jinja2,
|
||||
encoding=settings.FILE_CHARSET) as file_:
|
||||
self.template_jinja2 = jinja2_env.from_string(file_.read())
|
||||
|
||||
def tearDown(self):
|
||||
self.override_settings.__exit__(None, None, None)
|
||||
@@ -107,16 +118,20 @@ class OfflineTestCaseMixin(object):
|
||||
if engine == 'django':
|
||||
return ''.join(self.template.render(c) for c in contexts)
|
||||
if engine == 'jinja2':
|
||||
return '\n'.join(self.template_jinja2.render(c) for c in contexts) + "\n"
|
||||
return '\n'.join(
|
||||
self.template_jinja2.render(c) for c in contexts) + '\n'
|
||||
return None
|
||||
|
||||
def _test_offline(self, engine):
|
||||
hashes = self.expected_hash
|
||||
if not isinstance(hashes, (list, tuple)):
|
||||
hashes = [hashes]
|
||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
count, result = CompressCommand().compress(
|
||||
log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
self.assertEqual(len(hashes), count)
|
||||
self.assertEqual(['<script type="text/javascript" src="/static/CACHE/js/%s.js"></script>' % h for h in hashes], result)
|
||||
self.assertEqual([
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'%s.js"></script>' % h for h in hashes], result)
|
||||
rendered_template = self._render_template(engine)
|
||||
self.assertEqual(rendered_template, '\n'.join(result) + '\n')
|
||||
|
||||
@@ -146,134 +161,175 @@ class OfflineTestCaseMixin(object):
|
||||
def _get_jinja2_loader(self):
|
||||
import jinja2
|
||||
|
||||
loader = jinja2.FileSystemLoader(settings.TEMPLATE_DIRS, encoding=settings.FILE_CHARSET)
|
||||
loader = jinja2.FileSystemLoader(
|
||||
settings.TEMPLATE_DIRS, encoding=settings.FILE_CHARSET)
|
||||
return loader
|
||||
|
||||
|
||||
class OfflineGenerationSkipDuplicatesTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_duplicate"
|
||||
class OfflineCompressBasicTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'basic'
|
||||
expected_hash = 'f5e179b8eca4'
|
||||
|
||||
# We don't need to test multiples engines here.
|
||||
engines = ("django",)
|
||||
def test_rendering_without_manifest_raises_exception(self):
|
||||
# flush cached manifest
|
||||
flush_offline_manifest()
|
||||
self.assertRaises(OfflineGenerationError,
|
||||
self.template.render, Context({}))
|
||||
|
||||
def _test_offline(self, engine):
|
||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
# Only one block compressed, the second identical one was skipped.
|
||||
@unittest.skipIf(not _TEST_JINJA2, 'No Jinja2 testing')
|
||||
def test_rendering_without_manifest_raises_exception_jinja2(self):
|
||||
# flush cached manifest
|
||||
flush_offline_manifest()
|
||||
self.assertRaises(OfflineGenerationError,
|
||||
self.template_jinja2.render, {})
|
||||
|
||||
def _test_deleting_manifest_does_not_affect_rendering(self, engine):
|
||||
count, result = CompressCommand().compress(
|
||||
log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
get_offline_manifest()
|
||||
manifest_path = os.path.join('CACHE', 'manifest.json')
|
||||
if default_storage.exists(manifest_path):
|
||||
default_storage.delete(manifest_path)
|
||||
self.assertEqual(1, count)
|
||||
# Only 1 <script> block in returned result as well.
|
||||
self.assertEqual([
|
||||
'<script type="text/javascript" src="/static/CACHE/js/f5e179b8eca4.js"></script>',
|
||||
], result)
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'%s.js"></script>' % (self.expected_hash, )], result)
|
||||
rendered_template = self._render_template(engine)
|
||||
# But rendering the template returns both (identical) scripts.
|
||||
self.assertEqual(rendered_template, "".join(result * 2) + "\n")
|
||||
self.assertEqual(rendered_template, ''.join(result) + '\n')
|
||||
|
||||
def test_deleting_manifest_does_not_affect_rendering(self):
|
||||
for engine in self.engines:
|
||||
self._test_deleting_manifest_does_not_affect_rendering(engine)
|
||||
|
||||
class OfflineGenerationBlockSuperTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_block_super"
|
||||
expected_hash = "7c02d201f69d"
|
||||
# Block.super not supported for Jinja2 yet.
|
||||
engines = ("django",)
|
||||
def test_requires_model_validation(self):
|
||||
self.assertFalse(CompressCommand.requires_model_validation)
|
||||
|
||||
|
||||
class OfflineGenerationBlockSuperMultipleTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_block_super_multiple"
|
||||
expected_hash = "f8891c416981"
|
||||
# Block.super not supported for Jinja2 yet.
|
||||
engines = ("django",)
|
||||
|
||||
|
||||
class OfflineGenerationBlockSuperMultipleWithCachedLoaderTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_block_super_multiple_cached"
|
||||
expected_hash = "2f6ef61c488e"
|
||||
# Block.super not supported for Jinja2 yet.
|
||||
engines = ("django",)
|
||||
|
||||
def setUp(self):
|
||||
self._old_template_loaders = settings.TEMPLATE_LOADERS
|
||||
settings.TEMPLATE_LOADERS = (
|
||||
def test_get_loaders(self):
|
||||
TEMPLATE_LOADERS = (
|
||||
('django.template.loaders.cached.Loader', (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
)),
|
||||
)
|
||||
super(OfflineGenerationBlockSuperMultipleWithCachedLoaderTestCase, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super(OfflineGenerationBlockSuperMultipleWithCachedLoaderTestCase, self).tearDown()
|
||||
settings.TEMPLATE_LOADERS = self._old_template_loaders
|
||||
with self.settings(TEMPLATE_LOADERS=TEMPLATE_LOADERS):
|
||||
from django.template.loaders.filesystem import (
|
||||
Loader as FileSystemLoader)
|
||||
from django.template.loaders.app_directories import (
|
||||
Loader as AppDirectoriesLoader)
|
||||
loaders = CompressCommand().get_loaders()
|
||||
self.assertTrue(isinstance(loaders[0], FileSystemLoader))
|
||||
self.assertTrue(isinstance(loaders[1], AppDirectoriesLoader))
|
||||
|
||||
|
||||
class OfflineGenerationBlockSuperTestCaseWithExtraContent(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_block_super_extra"
|
||||
# Block.super not supported for Jinja2 yet.
|
||||
engines = ("django",)
|
||||
class OfflineCompressSkipDuplicatesTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_duplicate'
|
||||
|
||||
# We don't need to test multiples engines here.
|
||||
engines = ('django',)
|
||||
|
||||
def _test_offline(self, engine):
|
||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
self.assertEqual(2, count)
|
||||
count, result = CompressCommand().compress(
|
||||
log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
# Only one block compressed, the second identical one was skipped.
|
||||
self.assertEqual(1, count)
|
||||
# Only 1 <script> block in returned result as well.
|
||||
self.assertEqual([
|
||||
'<script type="text/javascript" src="/static/CACHE/js/ced14aec5856.js"></script>',
|
||||
'<script type="text/javascript" src="/static/CACHE/js/7c02d201f69d.js"></script>'
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'f5e179b8eca4.js"></script>',
|
||||
], result)
|
||||
rendered_template = self._render_template(engine)
|
||||
self.assertEqual(rendered_template, "".join(result) + "\n")
|
||||
# But rendering the template returns both (identical) scripts.
|
||||
self.assertEqual(rendered_template, ''.join(result * 2) + '\n')
|
||||
|
||||
|
||||
class OfflineGenerationConditionTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_condition"
|
||||
expected_hash = "4e3758d50224"
|
||||
class OfflineCompressBlockSuperTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_block_super'
|
||||
expected_hash = '7c02d201f69d'
|
||||
# Block.super not supported for Jinja2 yet.
|
||||
engines = ('django',)
|
||||
|
||||
def setUp(self):
|
||||
self.old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = {
|
||||
|
||||
class OfflineCompressBlockSuperMultipleTestCase(
|
||||
OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_block_super_multiple'
|
||||
expected_hash = 'f8891c416981'
|
||||
# Block.super not supported for Jinja2 yet.
|
||||
engines = ('django',)
|
||||
|
||||
|
||||
class OfflineCompressBlockSuperMultipleCachedLoaderTestCase(
|
||||
OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_block_super_multiple_cached'
|
||||
expected_hash = '2f6ef61c488e'
|
||||
# Block.super not supported for Jinja2 yet.
|
||||
engines = ('django',)
|
||||
additional_test_settings = {
|
||||
'TEMPLATE_LOADERS': (
|
||||
('django.template.loaders.cached.Loader', (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
class OfflineCompressBlockSuperTestCaseWithExtraContent(
|
||||
OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_block_super_extra'
|
||||
# Block.super not supported for Jinja2 yet.
|
||||
engines = ('django',)
|
||||
|
||||
def _test_offline(self, engine):
|
||||
count, result = CompressCommand().compress(
|
||||
log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
self.assertEqual(2, count)
|
||||
self.assertEqual([
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'ced14aec5856.js"></script>',
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'7c02d201f69d.js"></script>',
|
||||
], result)
|
||||
rendered_template = self._render_template(engine)
|
||||
self.assertEqual(rendered_template, ''.join(result) + '\n')
|
||||
|
||||
|
||||
class OfflineCompressConditionTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_condition'
|
||||
expected_hash = '4e3758d50224'
|
||||
additional_test_settings = {
|
||||
'COMPRESS_OFFLINE_CONTEXT': {
|
||||
'condition': 'red',
|
||||
}
|
||||
super(OfflineGenerationConditionTestCase, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
||||
super(OfflineGenerationConditionTestCase, self).tearDown()
|
||||
}
|
||||
|
||||
|
||||
class OfflineGenerationTemplateTagTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_templatetag"
|
||||
expected_hash = "a27e1d3a619a"
|
||||
class OfflineCompressTemplateTagTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_templatetag'
|
||||
expected_hash = 'a27e1d3a619a'
|
||||
|
||||
|
||||
class OfflineGenerationStaticTemplateTagTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_static_templatetag"
|
||||
expected_hash = "dfa2bb387fa8"
|
||||
class OfflineCompressStaticTemplateTagTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_static_templatetag'
|
||||
expected_hash = 'dfa2bb387fa8'
|
||||
|
||||
|
||||
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 = {
|
||||
class OfflineCompressTestCaseWithContext(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_with_context'
|
||||
expected_hash = '5838e2fd66af'
|
||||
additional_test_settings = {
|
||||
'COMPRESS_OFFLINE_CONTEXT': {
|
||||
'content': 'OK!',
|
||||
}
|
||||
super(OfflineGenerationTestCaseWithContext, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
||||
super(OfflineGenerationTestCaseWithContext, self).tearDown()
|
||||
}
|
||||
|
||||
|
||||
class OfflineGenerationTestCaseWithContextList(OfflineTestCaseMixin, TestCase):
|
||||
class OfflineCompressTestCaseWithContextList(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_with_context'
|
||||
expected_hash = ['f8bcaea049b3', 'db12749b1e80', 'e9f4a0054a06']
|
||||
|
||||
def setUp(self):
|
||||
self.old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = [{'content': 'OK %d!' % i} for i in range(1, 4)]
|
||||
super(OfflineGenerationTestCaseWithContextList, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
||||
super(OfflineGenerationTestCaseWithContextList, self).tearDown()
|
||||
additional_test_settings = {
|
||||
'COMPRESS_OFFLINE_CONTEXT': [{
|
||||
'content': 'OK %d!' % i} for i in range(1, 4)]
|
||||
}
|
||||
|
||||
def _prepare_contexts(self, engine):
|
||||
if engine == 'django':
|
||||
@@ -283,18 +339,14 @@ class OfflineGenerationTestCaseWithContextList(OfflineTestCaseMixin, TestCase):
|
||||
return None
|
||||
|
||||
|
||||
class OfflineGenerationTestCaseWithContextGenerator(OfflineTestCaseMixin, TestCase):
|
||||
class OfflineCompressTestCaseWithContextGenerator(
|
||||
OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_with_context'
|
||||
expected_hash = ['f8bcaea049b3', 'db12749b1e80', 'e9f4a0054a06']
|
||||
|
||||
def setUp(self):
|
||||
self.old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = 'compressor.tests.test_offline.offline_context_generator'
|
||||
super(OfflineGenerationTestCaseWithContextGenerator, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
||||
super(OfflineGenerationTestCaseWithContextGenerator, self).tearDown()
|
||||
additional_test_settings = {
|
||||
'COMPRESS_OFFLINE_CONTEXT': 'compressor.tests.test_offline.'
|
||||
'offline_context_generator'
|
||||
}
|
||||
|
||||
def _prepare_contexts(self, engine):
|
||||
module, function = get_mod_func(settings.COMPRESS_OFFLINE_CONTEXT)
|
||||
@@ -306,69 +358,85 @@ class OfflineGenerationTestCaseWithContextGenerator(OfflineTestCaseMixin, TestCa
|
||||
return None
|
||||
|
||||
|
||||
class OfflineGenerationTestCaseWithContextGeneratorImportError(OfflineTestCaseMixin, TestCase):
|
||||
class OfflineCompressTestCaseWithContextGeneratorImportError(
|
||||
OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_with_context'
|
||||
|
||||
def _test_offline(self, engine):
|
||||
old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
||||
# Test that we are properly generating ImportError when
|
||||
# COMPRESS_OFFLINE_CONTEXT looks like a function but can't be imported
|
||||
# for whatever reason.
|
||||
|
||||
try:
|
||||
with self.settings(
|
||||
COMPRESS_OFFLINE_CONTEXT='invalid_mod.invalid_func'):
|
||||
# Path with invalid module name -- ImportError:
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = 'invalid_module.invalid_function'
|
||||
self.assertRaises(ImportError, CompressCommand().compress, engine=engine)
|
||||
self.assertRaises(
|
||||
ImportError, CompressCommand().compress, engine=engine)
|
||||
|
||||
# Module name only without function -- AttributeError:
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = 'compressor'
|
||||
self.assertRaises(ImportError, CompressCommand().compress, engine=engine)
|
||||
with self.settings(COMPRESS_OFFLINE_CONTEXT='compressor'):
|
||||
# Valid module name only without function -- AttributeError:
|
||||
self.assertRaises(
|
||||
ImportError, CompressCommand().compress, engine=engine)
|
||||
|
||||
with self.settings(
|
||||
COMPRESS_OFFLINE_CONTEXT='compressor.tests.invalid_function'):
|
||||
# Path with invalid function name -- AttributeError:
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = 'compressor.tests.invalid_function'
|
||||
self.assertRaises(ImportError, CompressCommand().compress, engine=engine)
|
||||
self.assertRaises(
|
||||
ImportError, CompressCommand().compress, engine=engine)
|
||||
|
||||
with self.settings(
|
||||
COMPRESS_OFFLINE_CONTEXT='compressor.tests.test_offline'):
|
||||
# Path without function attempts call on module -- TypeError:
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = 'compressor.tests.test_offline'
|
||||
self.assertRaises(ImportError, CompressCommand().compress, engine=engine)
|
||||
self.assertRaises(
|
||||
ImportError, CompressCommand().compress, engine=engine)
|
||||
|
||||
valid_path = 'compressor.tests.test_offline.offline_context_generator'
|
||||
with self.settings(COMPRESS_OFFLINE_CONTEXT=valid_path):
|
||||
# Valid path to generator function -- no ImportError:
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = 'compressor.tests.test_offline.offline_context_generator'
|
||||
|
||||
try:
|
||||
CompressCommand().compress(engine=engine)
|
||||
except ImportError:
|
||||
self.fail("Valid path to offline context generator mustn't raise ImportError.")
|
||||
|
||||
finally:
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = old_offline_context
|
||||
self.fail('Valid path to offline context generator must'
|
||||
' not raise ImportError.')
|
||||
|
||||
|
||||
class OfflineGenerationTestCaseErrors(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_error_handling"
|
||||
class OfflineCompressTestCaseErrors(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_error_handling'
|
||||
|
||||
def _test_offline(self, engine):
|
||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
count, result = CompressCommand().compress(
|
||||
log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
|
||||
if engine == "django":
|
||||
if engine == 'django':
|
||||
self.assertEqual(2, count)
|
||||
else:
|
||||
# Because we use env.parse in Jinja2Parser, the engine does not
|
||||
# actually load the "extends" and "includes" templates, and so
|
||||
# it is unable to detect that they are missing. So all the "compress"
|
||||
# nodes are processed correctly.
|
||||
# actually load the 'extends' and 'includes' templates, and so
|
||||
# it is unable to detect that they are missing. So all the
|
||||
# 'compress' nodes are processed correctly.
|
||||
self.assertEqual(4, count)
|
||||
self.assertEqual(engine, "jinja2")
|
||||
self.assertIn('<link rel="stylesheet" href="/static/CACHE/css/78bd7a762e2d.css" type="text/css" />', result)
|
||||
self.assertIn('<link rel="stylesheet" href="/static/CACHE/css/e31030430724.css" type="text/css" />', result)
|
||||
self.assertEqual(engine, 'jinja2')
|
||||
self.assertIn(
|
||||
'<link rel="stylesheet" href="/static/CACHE/css/'
|
||||
'78bd7a762e2d.css" type="text/css" />', result)
|
||||
self.assertIn(
|
||||
'<link rel="stylesheet" href="/static/CACHE/css/'
|
||||
'e31030430724.css" type="text/css" />', result)
|
||||
|
||||
self.assertIn('<script type="text/javascript" src="/static/CACHE/js/3872c9ae3f42.js"></script>', result)
|
||||
self.assertIn('<script type="text/javascript" src="/static/CACHE/js/cd8870829421.js"></script>', result)
|
||||
self.assertIn(
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'3872c9ae3f42.js"></script>', result)
|
||||
self.assertIn(
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'cd8870829421.js"></script>', result)
|
||||
|
||||
|
||||
class OfflineGenerationTestCaseWithError(OfflineTestCaseMixin, TestCase):
|
||||
class OfflineCompressTestCaseWithError(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_error_handling'
|
||||
|
||||
def setUp(self):
|
||||
self._old_compress_precompilers = settings.COMPRESS_PRECOMPILERS
|
||||
settings.COMPRESS_PRECOMPILERS = (('text/coffeescript', 'non-existing-binary'),)
|
||||
super(OfflineGenerationTestCaseWithError, self).setUp()
|
||||
additional_test_settings = {
|
||||
'COMPRESS_PRECOMPILERS': (('text/coffeescript', 'nonexisting-binary'),)
|
||||
}
|
||||
|
||||
def _test_offline(self, engine):
|
||||
"""
|
||||
@@ -376,184 +444,118 @@ class OfflineGenerationTestCaseWithError(OfflineTestCaseMixin, TestCase):
|
||||
True, as otherwise errors in configuration will never show in
|
||||
production.
|
||||
"""
|
||||
self._old_debug = settings.DEBUG
|
||||
with self.settings(DEBUG=True):
|
||||
self.assertRaises(
|
||||
CommandError, CompressCommand().compress, engine=engine)
|
||||
|
||||
try:
|
||||
settings.DEBUG = True
|
||||
self.assertRaises(CommandError, CompressCommand().compress, engine=engine)
|
||||
|
||||
settings.DEBUG = False
|
||||
self.assertRaises(CommandError, CompressCommand().compress, engine=engine)
|
||||
|
||||
finally:
|
||||
settings.DEBUG = self._old_debug
|
||||
|
||||
def tearDown(self):
|
||||
settings.COMPRESS_PRECOMPILERS = self._old_compress_precompilers
|
||||
super(OfflineGenerationTestCaseWithError, self).tearDown()
|
||||
with self.settings(DEBUG=False):
|
||||
self.assertRaises(
|
||||
CommandError, CompressCommand().compress, engine=engine)
|
||||
|
||||
|
||||
class OfflineGenerationTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "basic"
|
||||
expected_hash = "f5e179b8eca4"
|
||||
|
||||
def test_rendering_without_manifest_raises_exception(self):
|
||||
# flush cached manifest
|
||||
flush_offline_manifest()
|
||||
self.assertRaises(OfflineGenerationError,
|
||||
self.template.render, Context({}))
|
||||
|
||||
@unittest.skipIf(not _TEST_JINJA2, "No Jinja2 testing")
|
||||
def test_rendering_without_manifest_raises_exception_jinja2(self):
|
||||
# flush cached manifest
|
||||
flush_offline_manifest()
|
||||
self.assertRaises(OfflineGenerationError,
|
||||
self.template_jinja2.render, {})
|
||||
|
||||
def _test_deleting_manifest_does_not_affect_rendering(self, engine):
|
||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
get_offline_manifest()
|
||||
manifest_path = os.path.join('CACHE', 'manifest.json')
|
||||
if default_storage.exists(manifest_path):
|
||||
default_storage.delete(manifest_path)
|
||||
self.assertEqual(1, count)
|
||||
self.assertEqual([
|
||||
'<script type="text/javascript" src="/static/CACHE/js/%s.js"></script>' % (self.expected_hash, ),
|
||||
], result)
|
||||
rendered_template = self._render_template(engine)
|
||||
self.assertEqual(rendered_template, "".join(result) + "\n")
|
||||
|
||||
def test_deleting_manifest_does_not_affect_rendering(self):
|
||||
for engine in self.engines:
|
||||
self._test_deleting_manifest_does_not_affect_rendering(engine)
|
||||
|
||||
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
|
||||
|
||||
|
||||
class OfflineGenerationEmptyTag(OfflineTestCaseMixin, TestCase):
|
||||
class OfflineCompressEmptyTag(OfflineTestCaseMixin, TestCase):
|
||||
"""
|
||||
In case of a compress template tag with no content, an entry
|
||||
will be added to the manifest with an empty string as value.
|
||||
This test makes sure there is no recompression happening when
|
||||
compressor encounters such an emptystring in the manifest.
|
||||
"""
|
||||
templates_dir = "basic"
|
||||
expected_hash = "f5e179b8eca4"
|
||||
engines = ("django",)
|
||||
templates_dir = 'basic'
|
||||
expected_hash = 'f5e179b8eca4'
|
||||
engines = ('django',)
|
||||
|
||||
def _test_offline(self, engine):
|
||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
count, result = CompressCommand().compress(
|
||||
log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
manifest = get_offline_manifest()
|
||||
manifest[list(manifest)[0]] = ""
|
||||
self.assertEqual(self._render_template(engine), "\n")
|
||||
manifest[list(manifest)[0]] = ''
|
||||
self.assertEqual(self._render_template(engine), '\n')
|
||||
|
||||
|
||||
class OfflineGenerationBlockSuperBaseCompressed(OfflineTestCaseMixin, TestCase):
|
||||
template_names = ["base.html", "base2.html", "test_compressor_offline.html"]
|
||||
class OfflineCompressBlockSuperBaseCompressed(OfflineTestCaseMixin, TestCase):
|
||||
template_names = ['base.html', 'base2.html',
|
||||
'test_compressor_offline.html']
|
||||
templates_dir = 'test_block_super_base_compressed'
|
||||
expected_hash = ['028c3fc42232', '2e9d3f5545a6', 'f8891c416981']
|
||||
# Block.super not supported for Jinja2 yet.
|
||||
engines = ("django",)
|
||||
engines = ('django',)
|
||||
|
||||
def setUp(self):
|
||||
super(OfflineGenerationBlockSuperBaseCompressed, self).setUp()
|
||||
super(OfflineCompressBlockSuperBaseCompressed, self).setUp()
|
||||
|
||||
self.template_paths = []
|
||||
self.templates = []
|
||||
for template_name in self.template_names:
|
||||
template_path = os.path.join(settings.TEMPLATE_DIRS[0], template_name)
|
||||
template_path = os.path.join(
|
||||
settings.TEMPLATE_DIRS[0], template_name)
|
||||
self.template_paths.append(template_path)
|
||||
with io.open(template_path, encoding=settings.FILE_CHARSET) as file:
|
||||
template = Template(file.read())
|
||||
with io.open(template_path,
|
||||
encoding=settings.FILE_CHARSET) as file_:
|
||||
template = Template(file_.read())
|
||||
self.templates.append(template)
|
||||
|
||||
def _render_template(self, template, engine):
|
||||
if engine == "django":
|
||||
if engine == 'django':
|
||||
return template.render(Context(settings.COMPRESS_OFFLINE_CONTEXT))
|
||||
elif engine == "jinja2":
|
||||
return template.render(settings.COMPRESS_OFFLINE_CONTEXT) + "\n"
|
||||
elif engine == 'jinja2':
|
||||
return template.render(settings.COMPRESS_OFFLINE_CONTEXT) + '\n'
|
||||
else:
|
||||
return None
|
||||
|
||||
def _test_offline(self, engine):
|
||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
count, result = CompressCommand().compress(
|
||||
log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
self.assertEqual(len(self.expected_hash), count)
|
||||
for expected_hash, template in zip(self.expected_hash, self.templates):
|
||||
expected_output = '<script type="text/javascript" src="/static/CACHE/js/%s.js"></script>' % (expected_hash, )
|
||||
self.assertIn(expected_output, result)
|
||||
expected = ('<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'%s.js"></script>' % (expected_hash, ))
|
||||
self.assertIn(expected, result)
|
||||
rendered_template = self._render_template(template, engine)
|
||||
self.assertEqual(rendered_template, expected_output + '\n')
|
||||
self.assertEqual(rendered_template, expected + '\n')
|
||||
|
||||
|
||||
class OfflineGenerationInlineNonAsciiTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_inline_non_ascii"
|
||||
|
||||
def setUp(self):
|
||||
self.old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = {
|
||||
class OfflineCompressInlineNonAsciiTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_inline_non_ascii'
|
||||
additional_test_settings = {
|
||||
'COMPRESS_OFFLINE_CONTEXT': {
|
||||
'test_non_ascii_value': '\u2014',
|
||||
}
|
||||
super(OfflineGenerationInlineNonAsciiTestCase, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
||||
super(OfflineGenerationInlineNonAsciiTestCase, self).tearDown()
|
||||
}
|
||||
|
||||
def _test_offline(self, engine):
|
||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
count, result = CompressCommand().compress(
|
||||
log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
rendered_template = self._render_template(engine)
|
||||
self.assertEqual(rendered_template, "".join(result) + "\n")
|
||||
self.assertEqual(rendered_template, ''.join(result) + '\n')
|
||||
|
||||
|
||||
class OfflineGenerationComplexTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_complex"
|
||||
|
||||
def setUp(self):
|
||||
self.old_offline_context = settings.COMPRESS_OFFLINE_CONTEXT
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = {
|
||||
class OfflineCompressComplexTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_complex'
|
||||
additional_test_settings = {
|
||||
'COMPRESS_OFFLINE_CONTEXT': {
|
||||
'condition': 'OK!',
|
||||
# Django templating does not allow definition of tuples in the
|
||||
# templates. Make sure this is same as test_templates_jinja2/test_complex.
|
||||
'my_names': ("js/one.js", "js/nonasc.js"),
|
||||
# templates.
|
||||
# Make sure this is same as test_templates_jinja2/test_complex.
|
||||
'my_names': ('js/one.js', 'js/nonasc.js'),
|
||||
}
|
||||
super(OfflineGenerationComplexTestCase, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
settings.COMPRESS_OFFLINE_CONTEXT = self.old_offline_context
|
||||
super(OfflineGenerationComplexTestCase, self).tearDown()
|
||||
}
|
||||
|
||||
def _test_offline(self, engine):
|
||||
count, result = CompressCommand().compress(log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
count, result = CompressCommand().compress(
|
||||
log=self.log, verbosity=self.verbosity, engine=engine)
|
||||
self.assertEqual(3, count)
|
||||
self.assertEqual([
|
||||
'<script type="text/javascript" src="/static/CACHE/js/0e8807bebcee.js"></script>',
|
||||
'<script type="text/javascript" src="/static/CACHE/js/eed1d222933e.js"></script>',
|
||||
'<script type="text/javascript" src="/static/CACHE/js/00b4baffe335.js"></script>',
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'0e8807bebcee.js"></script>',
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'eed1d222933e.js"></script>',
|
||||
'<script type="text/javascript" src="/static/CACHE/js/'
|
||||
'00b4baffe335.js"></script>',
|
||||
], result)
|
||||
rendered_template = self._render_template(engine)
|
||||
result = (result[0], result[2])
|
||||
self.assertEqual(rendered_template, "".join(result) + "\n")
|
||||
self.assertEqual(rendered_template, ''.join(result) + '\n')
|
||||
|
||||
|
||||
# Coffin does not work on Python 3.2+ due to:
|
||||
@@ -561,14 +563,12 @@ class OfflineGenerationComplexTestCase(OfflineTestCaseMixin, TestCase):
|
||||
# from library import *
|
||||
# causing 'ImportError: No module named library'.
|
||||
# It seems there is no evidence nor indicated support for Python 3+.
|
||||
@unittest.skipIf(sys.version_info >= (3, 2),
|
||||
"Coffin does not support 3.2+")
|
||||
@unittest.skipIf(django.VERSION >= (1, 8),
|
||||
"Import error on 1.8")
|
||||
class OfflineGenerationCoffinTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_coffin"
|
||||
expected_hash = "32c8281e3346"
|
||||
engines = ("jinja2",)
|
||||
@unittest.skipIf(sys.version_info >= (3, 2), 'Coffin does not support 3.2+')
|
||||
@unittest.skipIf(django.VERSION >= (1, 8), 'Import error on 1.8')
|
||||
class OfflineCompressCoffinTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_coffin'
|
||||
expected_hash = '32c8281e3346'
|
||||
engines = ('jinja2',)
|
||||
|
||||
def _get_jinja2_env(self):
|
||||
import jinja2
|
||||
@@ -584,17 +584,16 @@ class OfflineGenerationCoffinTestCase(OfflineTestCaseMixin, TestCase):
|
||||
|
||||
|
||||
# Jingo does not work when using Python 3.2 due to the use of Unicode string
|
||||
# prefix (and possibly other stuff), but it actually works when using Python 3.3
|
||||
# since it tolerates the use of the Unicode string prefix. Python 3.3 support
|
||||
# is also evident in its tox.ini file.
|
||||
# prefix (and possibly other stuff), but it actually works when using Python
|
||||
# 3.3 since it tolerates the use of the Unicode string prefix. Python 3.3
|
||||
# support is also evident in its tox.ini file.
|
||||
@unittest.skipIf(sys.version_info >= (3, 2) and sys.version_info < (3, 3),
|
||||
"Jingo does not support 3.2")
|
||||
@unittest.skipIf(django.VERSION >= (1, 8),
|
||||
"Import error on 1.8")
|
||||
class OfflineGenerationJingoTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = "test_jingo"
|
||||
expected_hash = "61ec584468eb"
|
||||
engines = ("jinja2",)
|
||||
'Jingo does not support 3.2')
|
||||
@unittest.skipIf(django.VERSION >= (1, 8), 'Import error on 1.8')
|
||||
class OfflineCompressJingoTestCase(OfflineTestCaseMixin, TestCase):
|
||||
templates_dir = 'test_jingo'
|
||||
expected_hash = '61ec584468eb'
|
||||
engines = ('jinja2',)
|
||||
|
||||
def _get_jinja2_env(self):
|
||||
import jinja2
|
||||
@@ -605,7 +604,8 @@ class OfflineGenerationJingoTestCase(OfflineTestCaseMixin, TestCase):
|
||||
|
||||
# Could have used the env.add_extension method, but it's only available
|
||||
# in Jinja2 v2.5
|
||||
new_env = jinja2.Environment(extensions=[CompressorExtension, SpacelessExtension, jinja2.ext.with_])
|
||||
new_env = jinja2.Environment(extensions=[
|
||||
CompressorExtension, SpacelessExtension, jinja2.ext.with_])
|
||||
env.extensions.update(new_env.extensions)
|
||||
env.globals['url_for'] = url_for
|
||||
|
||||
|
||||
Reference in New Issue
Block a user