Commit 48a25dac by Timothée Peignier

Merge branch 'master' into jinja-ext

Conflicts:
	pipeline/jinja2/ext.py
parents b7ac2edc 782de377
...@@ -5,6 +5,7 @@ These people have provided bug fixes, new features, improved the documentation ...@@ -5,6 +5,7 @@ These people have provided bug fixes, new features, improved the documentation
or just made Pipeline more awesome. or just made Pipeline more awesome.
* Adam Charnock <adam@omniwiki.co.uk> * Adam Charnock <adam@omniwiki.co.uk>
* Alan Lu <gotoalanlu@gmail.com>
* Alexander Artemenko <svetlyak40wt> * Alexander Artemenko <svetlyak40wt>
* Alexander Pugachev <alexander.pugachev@gmail.com> * Alexander Pugachev <alexander.pugachev@gmail.com>
* Alexis Svinartchouk <zvin@free.fr> * Alexis Svinartchouk <zvin@free.fr>
......
...@@ -3,19 +3,36 @@ ...@@ -3,19 +3,36 @@
History History
======= =======
1.3.1
-----
* Improve exceptions hierarchy.
* Improve our sub-process calls.
* Update uglify-js documentation. Thanks to Andrey Antukh.
1.3.0
-----
* Add support Python 3, with some help from Alan Lu.
* Add support for Django 1.5.
* Remove support for Django < 1.4.
* Drop support for Python < 2.6.
* Drop support for ``staticfiles`` app, in favor of ``django.contrib.staticfiles``.
* Drop ``PIPELINE`` settings, in favor of ``DEBUG`` to avoid confusion.
* Drop support for ``jinja2`` temporarily.
1.1.24 1.2.24
------ ------
* Fix yui/yuglify settings overriding each other. Thanks to Fábio Santos. * Fix yui/yuglify settings overriding each other. Thanks to Fábio Santos.
1.1.23 1.2.23
------ ------
* Separate yuglify compressor from YUI compressor. * Separate yuglify compressor from YUI compressor.
* Improve HTML compression middleware. * Improve HTML compression middleware.
1.1.22 1.2.22
------ ------
* Better compressor error messages. Thanks to Steven Cummings. * Better compressor error messages. Thanks to Steven Cummings.
...@@ -23,7 +40,7 @@ History ...@@ -23,7 +40,7 @@ History
* Fix packaging metadata. Thanks to Rui Coelho for noticing it. * Fix packaging metadata. Thanks to Rui Coelho for noticing it.
* Add documentation about non-packing storage. * Add documentation about non-packing storage.
1.1.21 1.2.21
------ ------
* Run stylus even if file is considered outdated. * Run stylus even if file is considered outdated.
......
...@@ -121,7 +121,7 @@ To use it add this to your ``PIPELINE_JS_COMPRESSOR`` :: ...@@ -121,7 +121,7 @@ To use it add this to your ``PIPELINE_JS_COMPRESSOR`` ::
UglifyJS compressor UglifyJS compressor
=================== ===================
The UglifyJS compressor uses `UglifyJS <https://github.com/mishoo/UglifyJS/>`_ to The UglifyJS compressor uses `UglifyJS <https://github.com/mishoo/UglifyJS2/>`_ to
compress javascripts. compress javascripts.
To use it add this to your ``PIPELINE_JS_COMPRESSOR`` :: To use it add this to your ``PIPELINE_JS_COMPRESSOR`` ::
......
...@@ -4,16 +4,6 @@ ...@@ -4,16 +4,6 @@
Storages Storages
======== ========
Using with a custom storage
===========================
Pipeline uses `Django Storage <https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#storages>`_
to read, save and delete files, by default it use an improved ``StaticFilesStorage``.
You can provide your own via ``PIPELINE_STORAGE`` : ::
PIPELINE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
Using with staticfiles Using with staticfiles
====================== ======================
...@@ -36,11 +26,6 @@ Also available if you want versioning :: ...@@ -36,11 +26,6 @@ Also available if you want versioning ::
STATICFILES_STORAGE = 'pipeline.storage.NonPackagingPipelineCachedStorage' STATICFILES_STORAGE = 'pipeline.storage.NonPackagingPipelineCachedStorage'
Pipeline is also providing a storage that play nicely with staticfiles app
particularly for development : ::
PIPELINE_STORAGE = 'pipeline.storage.PipelineFinderStorage'
Using with other storages Using with other storages
========================= =========================
......
...@@ -65,42 +65,3 @@ Pipeline provide a way to add your javascripts and stylesheets files to a ...@@ -65,42 +65,3 @@ Pipeline provide a way to add your javascripts and stylesheets files to a
cache-manifest via `Manifesto <http://manifesto.readthedocs.org/>`_. cache-manifest via `Manifesto <http://manifesto.readthedocs.org/>`_.
To do so, you just need to add manifesto app to your ``INSTALLED_APPS``. To do so, you just need to add manifesto app to your ``INSTALLED_APPS``.
Jinja2
======
Pipeline also includes Jinja2 support and is used almost identically to the Django
Template tags implementation.
.. note::
You have to expose the Jinja2 functions provided by pipeline to the Jinja2
environment yourself, Pipeline will not do this for you. There are several implementations
of Jinja2 for Django, like ``django-ninja`` or ``coffin``.
See the vendor documentation for examples on how to expose functions to the Jinja2 environment
and pick a solution that best suites your use case.
For more information on Jinja2 see the documentation at http://jinja.pocoo.org/docs/.
Functions
---------
The functions to expose to the Jinja2 environment are: ::
pipeline.jinja2.ext.compressed_css
pipeline.jinja2.ext.compressed_js
Example
-------
To use in the templates: ::
{{ compressed_css('group_name') }}
{{ compressed_js('group_name') }}
Templates
---------
Unlike the Django template tag implementation the Jinja2 implementation uses different templates, so if you
wish to override them please override ``pipeline/css.jinja`` and ``pipeline/js.jinja``.
...@@ -4,11 +4,11 @@ import os ...@@ -4,11 +4,11 @@ import os
import subprocess import subprocess
from django.contrib.staticfiles import finders from django.contrib.staticfiles import finders
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.utils.encoding import smart_str from django.utils.encoding import smart_str
from pipeline.conf import settings from pipeline.conf import settings
from pipeline.exceptions import CompilerError
from pipeline.storage import default_storage from pipeline.storage import default_storage
from pipeline.utils import to_class from pipeline.utils import to_class
...@@ -18,9 +18,9 @@ class Compiler(object): ...@@ -18,9 +18,9 @@ class Compiler(object):
self.storage = storage self.storage = storage
self.verbose = verbose self.verbose = verbose
@property
def compilers(self): def compilers(self):
return [to_class(compiler) for compiler in settings.PIPELINE_COMPILERS] return [to_class(compiler) for compiler in settings.PIPELINE_COMPILERS]
compilers = property(compilers)
def compile(self, paths, force=False): def compile(self, paths, force=False):
for index, input_path in enumerate(paths): for index, input_path in enumerate(paths):
...@@ -39,7 +39,7 @@ class Compiler(object): ...@@ -39,7 +39,7 @@ class Compiler(object):
outdated = self.is_outdated(input_path, output_path) outdated = self.is_outdated(input_path, output_path)
compiler.compile_file(infile, outfile, outdated=outdated, force=force) compiler.compile_file(infile, outfile, outdated=outdated, force=force)
except CompilerError: except CompilerError:
if not self.storage.exists(output_path) or not settings.PIPELINE: if not self.storage.exists(output_path) or settings.DEBUG:
raise raise
return paths return paths
...@@ -75,32 +75,16 @@ class CompilerBase(object): ...@@ -75,32 +75,16 @@ class CompilerBase(object):
return content return content
class CompilerError(Exception):
pass
class SubProcessCompiler(CompilerBase): class SubProcessCompiler(CompilerBase):
def execute_command(self, command, content=None, cwd=None): def execute_command(self, command, content=None, cwd=None):
pipe = subprocess.Popen(command, shell=True, cwd=cwd, pipe = subprocess.Popen(command, shell=True, cwd=cwd,
stdout=subprocess.PIPE, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE) stderr=subprocess.PIPE)
if not content:
if content: return content
pipe.stdin.write(content) stdout, stderr = pipe.communicate(content)
pipe.stdin.close() if stderr:
raise CompilerError(stderr)
compressed_content = pipe.stdout.read()
pipe.stdout.close()
error = pipe.stderr.read()
pipe.stderr.close()
if pipe.wait() != 0:
if not error:
error = "Unable to apply %s compiler" % self.__class__.__name__
raise CompilerError(error)
if self.verbose: if self.verbose:
print(error) print(stderr)
return stdout
return compressed_content
...@@ -13,10 +13,9 @@ class StylusCompiler(SubProcessCompiler): ...@@ -13,10 +13,9 @@ class StylusCompiler(SubProcessCompiler):
return filename.endswith('.styl') return filename.endswith('.styl')
def compile_file(self, infile, outfile, outdated=False, force=False): def compile_file(self, infile, outfile, outdated=False, force=False):
command = "%s %s < %s > %s" % ( command = "%s %s %s" % (
settings.PIPELINE_STYLUS_BINARY, settings.PIPELINE_STYLUS_BINARY,
settings.PIPELINE_STYLUS_ARGUMENTS, settings.PIPELINE_STYLUS_ARGUMENTS,
infile, infile
outfile
) )
return self.execute_command(command, cwd=dirname(infile)) return self.execute_command(command, cwd=dirname(infile))
...@@ -13,6 +13,7 @@ from django.utils.encoding import smart_bytes, force_text ...@@ -13,6 +13,7 @@ from django.utils.encoding import smart_bytes, force_text
from pipeline.conf import settings from pipeline.conf import settings
from pipeline.storage import default_storage from pipeline.storage import default_storage
from pipeline.utils import to_class, relpath from pipeline.utils import to_class, relpath
from pipeline.exceptions import CompressorError
URL_DETECTOR = r'url\([\'"]?([^\s)]+\.[a-z]+[\?\#\d\w]*)[\'"]?\)' URL_DETECTOR = r'url\([\'"]?([^\s)]+\.[a-z]+[\?\#\d\w]*)[\'"]?\)'
URL_REPLACER = r'url\(__EMBED__(.+?)(\?\d+)?\)' URL_REPLACER = r'url\(__EMBED__(.+?)(\?\d+)?\)'
...@@ -42,13 +43,13 @@ class Compressor(object): ...@@ -42,13 +43,13 @@ class Compressor(object):
self.storage = storage self.storage = storage
self.verbose = verbose self.verbose = verbose
@property
def js_compressor(self): def js_compressor(self):
return to_class(settings.PIPELINE_JS_COMPRESSOR) return to_class(settings.PIPELINE_JS_COMPRESSOR)
js_compressor = property(js_compressor)
@property
def css_compressor(self): def css_compressor(self):
return to_class(settings.PIPELINE_CSS_COMPRESSOR) return to_class(settings.PIPELINE_CSS_COMPRESSOR)
css_compressor = property(css_compressor)
def compress_js(self, paths, templates=None, **kwargs): def compress_js(self, paths, templates=None, **kwargs):
"""Concatenate and compress JS files""" """Concatenate and compress JS files"""
...@@ -224,34 +225,15 @@ class CompressorBase(object): ...@@ -224,34 +225,15 @@ class CompressorBase(object):
raise NotImplementedError raise NotImplementedError
class CompressorError(Exception):
"""This exception is raised when a filter fails"""
pass
class SubProcessCompressor(CompressorBase): class SubProcessCompressor(CompressorBase):
def execute_command(self, command, content): def execute_command(self, command, content):
pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
stdin=subprocess.PIPE, stderr=subprocess.PIPE) stdin=subprocess.PIPE, stderr=subprocess.PIPE)
if not content:
try: return content
pipe.stdin.write(smart_bytes(content)) stdout, stderr = pipe.communicate(smart_bytes(content))
except IOError as e: if stderr:
message = "Unable to pipe content to command: %s" % command raise CompressorError(stderr)
raise CompressorError(message, e)
pipe.stdin.close()
compressed_content = pipe.stdout.read()
pipe.stdout.close()
error = pipe.stderr.read()
pipe.stderr.close()
if pipe.wait() != 0:
if not error:
error = "Unable to apply %s compressor" % self.__class__.__name__
raise CompressorError(error)
if self.verbose: if self.verbose:
print(error) print(stderr)
return compressed_content return stdout
...@@ -6,7 +6,7 @@ from pipeline.compressors import SubProcessCompressor ...@@ -6,7 +6,7 @@ from pipeline.compressors import SubProcessCompressor
class UglifyJSCompressor(SubProcessCompressor): class UglifyJSCompressor(SubProcessCompressor):
def compress_js(self, js): def compress_js(self, js):
command = '%s -nc %s' % (settings.PIPELINE_UGLIFYJS_BINARY, settings.PIPELINE_UGLIFYJS_ARGUMENTS) command = '%s %s' % (settings.PIPELINE_UGLIFYJS_BINARY, settings.PIPELINE_UGLIFYJS_ARGUMENTS)
if self.verbose: if self.verbose:
command += ' --verbose' command += ' --verbose'
return self.execute_command(command, js) return self.execute_command(command, js)
...@@ -2,7 +2,8 @@ from __future__ import unicode_literals ...@@ -2,7 +2,8 @@ from __future__ import unicode_literals
from django.conf import settings from django.conf import settings
PIPELINE = getattr(settings, 'PIPELINE', not settings.DEBUG) DEBUG = getattr(settings, 'DEBUG', False)
PIPELINE_ROOT = getattr(settings, 'PIPELINE_ROOT', settings.STATIC_ROOT) PIPELINE_ROOT = getattr(settings, 'PIPELINE_ROOT', settings.STATIC_ROOT)
PIPELINE_URL = getattr(settings, 'PIPELINE_URL', settings.STATIC_URL) PIPELINE_URL = getattr(settings, 'PIPELINE_URL', settings.STATIC_URL)
......
from __future__ import unicode_literals
class PipelineException(Exception):
pass
class PackageNotFound(PipelineException):
pass
class CompilerError(PipelineException):
pass
class CompressorError(PipelineException):
pass
...@@ -33,7 +33,7 @@ class PipelineManifest(Manifest): ...@@ -33,7 +33,7 @@ class PipelineManifest(Manifest):
def cache(self): def cache(self):
ignore_patterns = getattr(settings, "STATICFILES_IGNORE_PATTERNS", None) ignore_patterns = getattr(settings, "STATICFILES_IGNORE_PATTERNS", None)
if settings.PIPELINE: if not settings.DEBUG:
for package in self.packages: for package in self.packages:
self.package_files.append(package.output_filename) self.package_files.append(package.output_filename)
yield str(self.packager.individual_url(package.output_filename)) yield str(self.packager.individual_url(package.output_filename))
......
from __future__ import unicode_literals from __future__ import unicode_literals
from django.contrib.staticfiles.finders import find
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.utils.encoding import smart_str from django.utils.encoding import smart_str
from pipeline.conf import settings
from pipeline.compilers import Compiler from pipeline.compilers import Compiler
from pipeline.compressors import Compressor from pipeline.compressors import Compressor
from pipeline.conf import settings
from pipeline.exceptions import PackageNotFound
from pipeline.glob import glob from pipeline.glob import glob
from pipeline.signals import css_compressed, js_compressed from pipeline.signals import css_compressed, js_compressed
from pipeline.storage import default_storage from pipeline.storage import default_storage
...@@ -22,7 +24,7 @@ class Package(object): ...@@ -22,7 +24,7 @@ class Package(object):
paths = [] paths = []
for pattern in self.config.get('source_filenames', []): for pattern in self.config.get('source_filenames', []):
for path in glob(pattern): for path in glob(pattern):
if not path in paths: if not path in paths and find(path):
paths.append(str(path)) paths.append(str(path))
self._sources = paths self._sources = paths
return self._sources return self._sources
...@@ -120,7 +122,3 @@ class Packager(object): ...@@ -120,7 +122,3 @@ class Packager(object):
for name in config: for name in config:
packages[name] = Package(config[name]) packages[name] = Package(config[name])
return packages return packages
class PackageNotFound(Exception):
pass
...@@ -28,7 +28,7 @@ class CompressedCSSNode(template.Node): ...@@ -28,7 +28,7 @@ class CompressedCSSNode(template.Node):
except PackageNotFound: except PackageNotFound:
return '' # fail silently, do not return anything if an invalid group is specified return '' # fail silently, do not return anything if an invalid group is specified
if settings.PIPELINE: if not settings.DEBUG:
return self.render_css(package, package.output_filename) return self.render_css(package, package.output_filename)
else: else:
paths = self.packager.compile(package.paths) paths = self.packager.compile(package.paths)
...@@ -64,7 +64,7 @@ class CompressedJSNode(template.Node): ...@@ -64,7 +64,7 @@ class CompressedJSNode(template.Node):
except PackageNotFound: except PackageNotFound:
return '' # fail silently, do not return anything if an invalid group is specified return '' # fail silently, do not return anything if an invalid group is specified
if settings.PIPELINE: if not settings.DEBUG:
return self.render_js(package, package.output_filename) return self.render_js(package, package.output_filename)
else: else:
paths = self.packager.compile(package.paths) paths = self.packager.compile(package.paths)
...@@ -94,19 +94,19 @@ class CompressedJSNode(template.Node): ...@@ -94,19 +94,19 @@ class CompressedJSNode(template.Node):
return '\n'.join(tags) return '\n'.join(tags)
@register.tag
def compressed_css(parser, token): def compressed_css(parser, token):
try: try:
tag_name, name = token.split_contents() tag_name, name = token.split_contents()
except ValueError: except ValueError:
raise template.TemplateSyntaxError, '%r requires exactly one argument: the name of a group in the PIPELINE_CSS setting' % token.split_contents()[0] raise template.TemplateSyntaxError('%r requires exactly one argument: the name of a group in the PIPELINE_CSS setting' % token.split_contents()[0])
return CompressedCSSNode(name) return CompressedCSSNode(name)
compressed_css = register.tag(compressed_css)
@register.tag
def compressed_js(parser, token): def compressed_js(parser, token):
try: try:
tag_name, name = token.split_contents() tag_name, name = token.split_contents()
except ValueError: except ValueError:
raise template.TemplateSyntaxError, '%r requires exactly one argument: the name of a group in the PIPELINE_JS setting' % token.split_contents()[0] raise template.TemplateSyntaxError('%r requires exactly one argument: the name of a group in the PIPELINE_JS setting' % token.split_contents()[0])
return CompressedJSNode(name) return CompressedJSNode(name)
compressed_js = register.tag(compressed_js)
...@@ -4,7 +4,7 @@ from setuptools import setup, find_packages ...@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
setup( setup(
name='django-pipeline', name='django-pipeline',
version='1.3.0', version='1.3.1',
description='Pipeline is an asset packaging library for Django.', description='Pipeline is an asset packaging library for Django.',
long_description=open('README.rst').read() + '\n\n' + long_description=open('README.rst').read() + '\n\n' +
open('HISTORY.rst').read(), open('HISTORY.rst').read(),
...@@ -18,9 +18,11 @@ setup( ...@@ -18,9 +18,11 @@ setup(
classifiers=[ classifiers=[
'Environment :: Web Environment', 'Environment :: Web Environment',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: MIT License', 'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Topic :: Utilities', 'Topic :: Utilities',
] ]
) )
...@@ -26,18 +26,18 @@ class CompilerTest(TestCase): ...@@ -26,18 +26,18 @@ class CompilerTest(TestCase):
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")
self.assertEquals(output_path, "js/helpers.js") self.assertEqual(output_path, "js/helpers.js")
def test_compilers_class(self): def test_compilers_class(self):
compilers_class = self.compiler.compilers compilers_class = self.compiler.compilers
self.assertEquals(compilers_class[0], DummyCompiler) self.assertEqual(compilers_class[0], DummyCompiler)
def test_compile(self): def test_compile(self):
paths = self.compiler.compile([ paths = self.compiler.compile([
_('pipeline/js/dummy.coffee'), _('pipeline/js/dummy.coffee'),
_('pipeline/js/application.js'), _('pipeline/js/application.js'),
]) ])
self.assertEquals([_('pipeline/js/dummy.js'), _('pipeline/js/application.js')], paths) self.assertEqual([_('pipeline/js/dummy.js'), _('pipeline/js/application.js')], paths)
def tearDown(self): def tearDown(self):
settings.PIPELINE_COMPILERS = self.old_compilers settings.PIPELINE_COMPILERS = self.old_compilers
...@@ -22,24 +22,24 @@ class CompressorTest(TestCase): ...@@ -22,24 +22,24 @@ class CompressorTest(TestCase):
self.compressor = Compressor() self.compressor = Compressor()
def test_js_compressor_class(self): def test_js_compressor_class(self):
self.assertEquals(self.compressor.js_compressor, YuglifyCompressor) self.assertEqual(self.compressor.js_compressor, YuglifyCompressor)
def test_css_compressor_class(self): def test_css_compressor_class(self):
self.assertEquals(self.compressor.css_compressor, YuglifyCompressor) self.assertEqual(self.compressor.css_compressor, YuglifyCompressor)
def test_concatenate_and_rewrite(self): def test_concatenate_and_rewrite(self):
css = self.compressor.concatenate_and_rewrite([ css = self.compressor.concatenate_and_rewrite([
_('pipeline/css/first.css'), _('pipeline/css/first.css'),
_('pipeline/css/second.css') _('pipeline/css/second.css')
], 'css/screen.css') ], 'css/screen.css')
self.assertEquals(""".concat {\n display: none;\n}\n\n.concatenate {\n display: block;\n}\n""", css) self.assertEqual(""".concat {\n display: none;\n}\n\n.concatenate {\n display: block;\n}\n""", css)
def test_concatenate(self): def test_concatenate(self):
js = self.compressor.concatenate([ js = self.compressor.concatenate([
_('pipeline/js/first.js'), _('pipeline/js/first.js'),
_('pipeline/js/second.js') _('pipeline/js/second.js')
]) ])
self.assertEquals("""function concat() {\n console.log(arguments);\n}\n\nfunction cat() {\n console.log("hello world");\n}\n""", js) self.assertEqual("""function concat() {\n console.log(arguments);\n}\n\nfunction cat() {\n console.log("hello world");\n}\n""", js)
@patch.object(base64, 'b64encode') @patch.object(base64, 'b64encode')
def test_encoded_content(self, mock): def test_encoded_content(self, mock):
...@@ -51,35 +51,35 @@ class CompressorTest(TestCase): ...@@ -51,35 +51,35 @@ class CompressorTest(TestCase):
def test_relative_path(self): def test_relative_path(self):
relative_path = self.compressor.relative_path("images/sprite.png", 'css/screen.css') relative_path = self.compressor.relative_path("images/sprite.png", 'css/screen.css')
self.assertEquals(relative_path, '../images/sprite.png') self.assertEqual(relative_path, '../images/sprite.png')
def test_base_path(self): def test_base_path(self):
base_path = self.compressor.base_path([ base_path = self.compressor.base_path([
_('js/templates/form.jst'), _('js/templates/field.jst') _('js/templates/form.jst'), _('js/templates/field.jst')
]) ])
self.assertEquals(base_path, _('js/templates')) self.assertEqual(base_path, _('js/templates'))
def test_absolute_path(self): def test_absolute_path(self):
absolute_path = self.compressor.absolute_path('../../images/sprite.png', absolute_path = self.compressor.absolute_path('../../images/sprite.png',
'css/plugins/') 'css/plugins/')
self.assertEquals(absolute_path, 'images/sprite.png') self.assertEqual(absolute_path, 'images/sprite.png')
absolute_path = self.compressor.absolute_path('/images/sprite.png', absolute_path = self.compressor.absolute_path('/images/sprite.png',
'css/plugins/') 'css/plugins/')
self.assertEquals(absolute_path, '/images/sprite.png') self.assertEqual(absolute_path, '/images/sprite.png')
def test_template_name(self): def test_template_name(self):
name = self.compressor.template_name('templates/photo/detail.jst', name = self.compressor.template_name('templates/photo/detail.jst',
'templates/') 'templates/')
self.assertEquals(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.assertEquals(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.assertEquals(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')])
self.assertEquals(templates, """window.JST = window.JST || {};\n%s\nwindow.JST[\'list\'] = template(\'<div class="photo">\\n <img src="<%%= src %%>" />\\n <div class="caption">\\n <%%= caption %%>\\n </div>\\n</div>\');\n""" % TEMPLATE_FUNC) self.assertEqual(templates, """window.JST = window.JST || {};\n%s\nwindow.JST[\'list\'] = template(\'<div class="photo">\\n <img src="<%%= src %%>" />\\n <div class="caption">\\n <%%= caption %%>\\n </div>\\n</div>\');\n""" % TEMPLATE_FUNC)
templates = self.compressor.compile_templates([ templates = self.compressor.compile_templates([
_('pipeline/templates/video/detail.jst'), _('pipeline/templates/video/detail.jst'),
_('pipeline/templates/photo/detail.jst') _('pipeline/templates/photo/detail.jst')
...@@ -95,16 +95,16 @@ class CompressorTest(TestCase): ...@@ -95,16 +95,16 @@ class CompressorTest(TestCase):
def test_construct_asset_path(self): def test_construct_asset_path(self):
asset_path = self.compressor.construct_asset_path("../../images/sprite.png", asset_path = self.compressor.construct_asset_path("../../images/sprite.png",
"css/plugins/gallery.css", "css/gallery.css") "css/plugins/gallery.css", "css/gallery.css")
self.assertEquals(asset_path, "../images/sprite.png") self.assertEqual(asset_path, "../images/sprite.png")
asset_path = self.compressor.construct_asset_path("/images/sprite.png", asset_path = self.compressor.construct_asset_path("/images/sprite.png",
"css/plugins/gallery.css", "css/gallery.css") "css/plugins/gallery.css", "css/gallery.css")
self.assertEquals(asset_path, "/images/sprite.png") self.assertEqual(asset_path, "/images/sprite.png")
def test_url_rewrite(self): def test_url_rewrite(self):
output = self.compressor.concatenate_and_rewrite([ output = self.compressor.concatenate_and_rewrite([
_('pipeline/css/urls.css'), _('pipeline/css/urls.css'),
], 'css/screen.css') ], 'css/screen.css')
self.assertEquals("""@font-face { self.assertEqual("""@font-face {
font-family: 'Pipeline'; font-family: 'Pipeline';
src: url(../pipeline/fonts/pipeline.eot); src: url(../pipeline/fonts/pipeline.eot);
src: url(../pipeline/fonts/pipeline.eot?#iefix) format('embedded-opentype'); src: url(../pipeline/fonts/pipeline.eot?#iefix) format('embedded-opentype');
......
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