Commit 148271bd by Timothée Peignier

Improve unit tests

parent 1f6b48ae
......@@ -139,4 +139,3 @@ class SubProcessCompiler(CompilerBase):
os.rename(stdout.name, os.path.join(cwd or os.curdir, stdout_captured))
else:
os.remove(stdout.name)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import collections
import shlex
from django.conf import settings as _settings
from django.core.signals import setting_changed
from django.dispatch import receiver
from django.utils.six import string_types
DEFAULTS = {
'PIPELINE_ENABLED': not _settings.DEBUG,
......@@ -78,27 +83,42 @@ DEFAULTS = {
}
class PipelineSettings(object):
class PipelineSettings(collections.MutableMapping):
"""
Container object for pipeline settings
"""
def __init__(self, wrapped_settings):
DEFAULTS.update(wrapped_settings)
self.__dict__ = DEFAULTS
self.settings = DEFAULTS.copy()
self.settings.update(wrapped_settings)
def __getattr__(self, name):
if hasattr(self, name):
value = getattr(self, name)
elif name in self:
value = DEFAULTS[name]
else:
raise AttributeError("'%s' setting not found" % name)
if name.endswith(("_BINARY", "_ARGUMENTS")):
if isinstance(value, (type(u""), type(b""))):
def __getitem__(self, key):
value = self.settings[key]
if key.endswith(("_BINARY", "_ARGUMENTS")):
if isinstance(value, string_types):
return tuple(shlex.split(value))
return tuple(value)
return value
def __setitem__(self, key, value):
self.settings[key] = value
def __delitem__(self, key):
del self.store[key]
def __iter__(self):
return iter(self.settings)
def __len__(self):
return len(self.settings)
def __getattr__(self, name):
return self.__getitem__(name)
settings = PipelineSettings(_settings.PIPELINE)
@receiver(setting_changed)
def reload_settings(**kwargs):
if kwargs['setting'] == 'PIPELINE':
settings.update(kwargs['value'])
......@@ -57,6 +57,7 @@ STATICFILES_FINDERS = (
SECRET_KEY = "django-pipeline"
PIPELINE = {
'PIPELINE_ENABLED': True,
'STYLESHEETS': {
'screen': {
'source_filenames': (
......
from __future__ import unicode_literals
import os
import sys
from unittest import skipIf
from django.test import TestCase
from pipeline.conf import settings
from pipeline.compilers import Compiler, CompilerBase, SubProcessCompiler
from pipeline.collector import default_collector
from pipeline.compilers import Compiler, CompilerBase, SubProcessCompiler
from pipeline.conf import settings
from pipeline.exceptions import CompilerError
from tests.utils import _
from tests.utils import _, pipeline_settings
class FailingCompiler(SubProcessCompiler):
......@@ -46,8 +47,7 @@ class CopyingCompiler(SubProcessCompiler):
def compile_file(self, infile, outfile, outdated=False, force=False):
command = (
("cp",),
("--no-dereference", "--preserve=links",),
"cp",
infile,
outfile
)
......@@ -75,12 +75,11 @@ class DummyCompiler(CompilerBase):
return
@pipeline_settings(COMPILERS=['tests.tests.test_compiler.DummyCompiler'])
class DummyCompilerTest(TestCase):
def setUp(self):
default_collector.collect()
self.compiler = Compiler()
self.old_compilers = settings.COMPILERS
settings.COMPILERS = ['tests.tests.test_compiler.DummyCompiler']
def test_output_path(self):
output_path = self.compiler.output_path("js/helpers.coffee", "js")
......@@ -99,15 +98,14 @@ class DummyCompilerTest(TestCase):
def tearDown(self):
default_collector.clear()
settings.COMPILERS = self.old_compilers
@skipIf(sys.platform.startswith("win"), "requires posix platform")
@pipeline_settings(COMPILERS=['tests.tests.test_compiler.LineNumberingCompiler'])
class CompilerStdoutTest(TestCase):
def setUp(self):
default_collector.collect()
self.compiler = Compiler()
self.old_compilers = settings.COMPILERS
settings.PIPELINE_COMPILERS = ['tests.tests.test_compiler.LineNumberingCompiler']
def test_output_path(self):
output_path = self.compiler.output_path("js/helpers.coffee", "js")
......@@ -119,15 +117,14 @@ class CompilerStdoutTest(TestCase):
def tearDown(self):
default_collector.clear()
settings.PIPELINE_COMPILERS = self.old_compilers
@skipIf(sys.platform.startswith("win"), "requires posix platform")
@pipeline_settings(COMPILERS=['tests.tests.test_compiler.CopyingCompiler'])
class CompilerSelfWriterTest(TestCase):
def setUp(self):
default_collector.collect()
self.compiler = Compiler()
self.old_compilers = settings.PIPELINE_COMPILERS
settings.PIPELINE_COMPILERS = ['tests.tests.test_compiler.CopyingCompiler']
def test_output_path(self):
output_path = self.compiler.output_path("js/helpers.coffee", "js")
......@@ -140,36 +137,30 @@ class CompilerSelfWriterTest(TestCase):
def tearDown(self):
default_collector.clear()
settings.COMPILERS = self.old_compilers
@pipeline_settings(COMPILERS=['tests.tests.test_compiler.InvalidCompiler'])
class InvalidCompilerTest(TestCase):
def setUp(self):
default_collector.collect()
self.compiler = Compiler()
self.old_compilers = settings.COMPILERS
settings.COMPILERS = ['tests.tests.test_compiler.InvalidCompiler']
def test_compile(self):
self.assertRaises(CompilerError,
self.compiler.compile, [_('pipeline/js/dummy.coffee')])
self.assertRaises(CompilerError, self.compiler.compile, [_('pipeline/js/dummy.coffee')])
def tearDown(self):
default_collector.clear()
settings.COMPILERS = self.old_compilers
@skipIf(sys.platform.startswith("win"), "requires posix platform")
@pipeline_settings(COMPILERS=['tests.tests.test_compiler.FailingCompiler'])
class FailingCompilerTest(TestCase):
def setUp(self):
default_collector.collect()
self.compiler = Compiler()
self.old_compilers = settings.COMPILERS
settings.COMPILERS = ['tests.tests.test_compiler.FailingCompiler']
def test_compile(self):
self.assertRaises(CompilerError,
self.compiler.compile, [_('pipeline/js/dummy.coffee'),])
self.assertRaises(CompilerError, self.compiler.compile, [_('pipeline/js/dummy.coffee')])
def tearDown(self):
default_collector.clear()
settings.COMPILERS = self.old_compilers
......@@ -91,12 +91,8 @@ class CompressorTest(TestCase):
'templates\\')
self.assertEqual(name, 'photo_detail')
from pipeline.conf import DEFAULTS
pipeline_settings = DEFAULTS.copy()
pipeline_settings['TEMPLATE_SEPARATOR'] = '/'
@pipeline_settings(TEMPLATE_SEPARATOR='/')
def test_template_name_separator(self):
with pipeline_settings(TEMPLATE_SEPARATOR='/'):
name = self.compressor.template_name('templates/photo/detail.jst',
'templates/')
self.assertEqual(name, 'photo/detail')
......
......@@ -5,28 +5,28 @@ from django.test import TestCase
from pipeline.conf import PipelineSettings
class TestSettings(TestCase):
class TestSettings(TestCase):
def test_3unicode(self):
s = PipelineSettings(dict(), DEFAULTS={ "PIPELINE_FOO_BINARY": "env actualprogram" })
self.assertEqual(s.PIPELINE_FOO_BINARY, ('env', 'actualprogram'))
s = PipelineSettings({"FOO_BINARY": "env actualprogram"})
self.assertEqual(s.FOO_BINARY, ('env', 'actualprogram'))
def test_2unicode(self):
s = PipelineSettings(dict(), DEFAULTS={ "PIPELINE_FOO_BINARY": u"env actualprogram" })
self.assertEqual(s.PIPELINE_FOO_BINARY, ('env', 'actualprogram'))
s = PipelineSettings({"FOO_BINARY": u"env actualprogram"})
self.assertEqual(s.FOO_BINARY, ('env', 'actualprogram'))
def test_2bytes(self):
s = PipelineSettings(dict(), DEFAULTS={ "PIPELINE_FOO_BINARY": "env actualprogram" })
self.assertEqual(s.PIPELINE_FOO_BINARY, ('env', 'actualprogram'))
s = PipelineSettings({"FOO_BINARY": "env actualprogram"})
self.assertEqual(s.FOO_BINARY, ('env', 'actualprogram'))
def test_expected_splitting(self):
s = PipelineSettings(dict(), DEFAULTS={ "PIPELINE_FOO_BINARY": "env actualprogram" })
self.assertEqual(s.PIPELINE_FOO_BINARY, ('env', 'actualprogram'))
s = PipelineSettings({"FOO_BINARY": "env actualprogram"})
self.assertEqual(s.FOO_BINARY, ('env', 'actualprogram'))
def test_expected_preservation(self):
s = PipelineSettings(dict(), DEFAULTS={ "PIPELINE_FOO_BINARY": r"actual\ program" })
self.assertEqual(s.PIPELINE_FOO_BINARY, ('actual program',))
s = PipelineSettings({"FOO_BINARY": r"actual\ program"})
self.assertEqual(s.FOO_BINARY, ('actual program',))
def test_tuples_are_normal(self):
s = PipelineSettings(dict(), DEFAULTS={ "PIPELINE_FOO_ARGUMENTS": ("explicit", "with", "args") })
self.assertEqual(s.PIPELINE_FOO_ARGUMENTS, ('explicit', 'with', 'args'))
s = PipelineSettings({"FOO_ARGUMENTS": ("explicit", "with", "args")})
self.assertEqual(s.FOO_ARGUMENTS, ('explicit', 'with', 'args'))
......@@ -5,7 +5,7 @@ from django.contrib.staticfiles import finders
from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.management import call_command
from django.test import TestCase
from django.test.utils import override_settings
from django.test.utils import override_settings, modify_settings
from pipeline.storage import PipelineStorage
......@@ -48,50 +48,54 @@ class StorageTest(TestCase):
def tearDown(self):
staticfiles_storage._setup()
@pipeline_settings(JS_COMPRESSOR=None, CSS_COMPRESSOR=None)
def test_post_process_dry_run(self):
with pipeline_settings(JS_COMPRESSOR=None, CSS_COMPRESSOR=None):
processed_files = PipelineStorage().post_process({}, True)
self.assertEqual(list(processed_files), [])
@pipeline_settings(JS_COMPRESSOR=None, CSS_COMPRESSOR=None)
def test_post_process(self):
storage = PipelineStorage()
with pipeline_settings(JS_COMPRESSOR=None, CSS_COMPRESSOR=None):
processed_files = storage.post_process({})
self.assertTrue(('screen.css', 'screen.css', True) in processed_files)
self.assertTrue(('scripts.js', 'scripts.js', True) in processed_files)
@override_settings(STATICFILES_STORAGE='tests.tests.test_storage.PipelineNoPathStorage')
@pipeline_settings(JS_COMPRESSOR=None, CSS_COMPRESSOR=None, COMPILERS=['tests.tests.test_storage.DummyCSSCompiler'])
def test_post_process_no_path(self):
"""
Test post_process with a storage that doesn't implement the path method.
"""
with override_settings(STATICFILES_STORAGE='tests.tests.test_storage.PipelineNoPathStorage'):
with pipeline_settings(JS_COMPRESSOR=None, CSS_COMPRESSOR=None, COMPILERS=['tests.tests.test_storage.DummyCSSCompiler']):
staticfiles_storage._setup()
try:
call_command('collectstatic', verbosity=0, interactive=False)
except NotImplementedError:
self.fail('Received an error running collectstatic')
@modify_settings(STATICFILES_FINDERS={
'append': 'pipeline.finders.PipelineFinder'
})
def test_nonexistent_file_pipeline_finder(self):
CUSTOM_FINDERS = settings.STATICFILES_FINDERS + ('pipeline.finders.PipelineFinder',)
with self.settings(STATICFILES_FINDERS=CUSTOM_FINDERS):
path = finders.find('nothing.css')
self.assertIsNone(path)
@modify_settings(STATICFILES_FINDERS={
'append': 'pipeline.finders.CachedFileFinder'
})
def test_nonexistent_file_cached_finder(self):
CUSTOM_FINDERS = settings.STATICFILES_FINDERS + ('pipeline.finders.CachedFileFinder',)
with self.settings(STATICFILES_FINDERS=CUSTOM_FINDERS):
path = finders.find('nothing.css')
self.assertIsNone(path)
@modify_settings(STATICFILES_FINDERS={
'append': 'pipeline.finders.PipelineFinder'
})
def test_nonexistent_double_extension_file_pipeline_finder(self):
CUSTOM_FINDERS = settings.STATICFILES_FINDERS + ('pipeline.finders.PipelineFinder',)
with self.settings(STATICFILES_FINDERS=CUSTOM_FINDERS):
path = finders.find('app.css.map')
self.assertIsNone(path)
@modify_settings(STATICFILES_FINDERS={
'append': 'pipeline.finders.CachedFileFinder'
})
def test_nonexistent_double_extension_file_cached_finder(self):
CUSTOM_FINDERS = settings.STATICFILES_FINDERS + ('pipeline.finders.CachedFileFinder',)
with self.settings(STATICFILES_FINDERS=CUSTOM_FINDERS):
path = finders.find('app.css.map')
self.assertIsNone(path)
......@@ -7,6 +7,7 @@ from django.template import Template, Context
from django.test import TestCase
from pipeline.jinja2 import PipelineExtension
from pipeline.conf import settings
from tests.utils import pipeline_settings
......@@ -26,8 +27,8 @@ class JinjaTest(TestCase):
template = self.env.from_string(u"""{% stylesheet "screen" %}""")
self.assertEqual(u'<link href="/static/screen.css" rel="stylesheet" type="text/css" />', template.render())
@pipeline_settings(PIPELINE_ENABLED=False)
def test_package_css_disabled(self):
with pipeline_settings(PIPELINE_ENABLED=False):
template = self.env.from_string(u"""{% stylesheet "screen" %}""")
self.assertEqual(u'''<link href="/static/pipeline/css/first.css" rel="stylesheet" type="text/css" />
<link href="/static/pipeline/css/second.css" rel="stylesheet" type="text/css" />
......
import contextlib
import os
from pipeline.conf import settings
from django.test import override_settings
def _(path):
......@@ -9,14 +8,6 @@ def _(path):
return path.replace('/', os.sep).replace('\\', os.sep)
@contextlib.contextmanager
def pipeline_settings(**kwargs):
try:
saved = {}
for name, value in kwargs.items():
saved[name] = getattr(settings, name)
setattr(settings, name, value)
yield
finally:
for name, value in saved.items():
setattr(settings, name, value)
class pipeline_settings(override_settings):
def __init__(self, **kwargs):
self.options = {'PIPELINE': kwargs}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment