Commit 148271bd by Timothée Peignier

Improve unit tests

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