diff --git a/src/webassets/bundle.py b/src/webassets/bundle.py index 2cf66e10..febc73c9 100644 --- a/src/webassets/bundle.py +++ b/src/webassets/bundle.py @@ -56,6 +56,7 @@ def __init__(self, *contents, **options): self.depends = options.pop('depends', []) self.version = options.pop('version', []) self.extra = options.pop('extra', {}) + self.prefix = options.pop('prefix', '') if options: raise TypeError("got unexpected keyword argument '%s'" % list(options.keys())[0]) @@ -667,7 +668,7 @@ def _urls(self, env, extra_filters, *args, **kwargs): url = env.resolver.resolve_source_to_url(external, org) urls.append(url) - return urls + return ["%s%s" % (self.prefix, url) for url in urls] def urls(self, env=None, *args, **kwargs): """Return a list of urls for this bundle. diff --git a/src/webassets/filter/__init__.py b/src/webassets/filter/__init__.py index ecc201b9..4d17845c 100644 --- a/src/webassets/filter/__init__.py +++ b/src/webassets/filter/__init__.py @@ -480,7 +480,7 @@ def created(self): raise ValueError( '{input} placeholder given, but no data passed') with os.fdopen(input_file.fd, 'wb') as f: - f.write(data.read() if hasattr(data, 'read') else data) + f.write(data.read().encode('utf-8') if hasattr(data, 'read') else data) # No longer pass to stdin data = None @@ -504,7 +504,7 @@ def created(self): else: if output_file.created: with open(output_file.filename, 'rb') as f: - out.write(f.read()) + out.write(f.read().decode('utf-8')) else: out.write(stdout.decode('utf-8')) finally: diff --git a/src/webassets/test.py b/src/webassets/test.py index 7c830ff7..150cec74 100644 --- a/src/webassets/test.py +++ b/src/webassets/test.py @@ -52,6 +52,7 @@ def create_files(self, files): """Helper that allows to quickly create a bunch of files in the media directory of the current test run. """ + import codecs # Allow passing a list of filenames to create empty files if not hasattr(files, 'items'): files = dict(map(lambda n: (n, ''), files)) @@ -59,7 +60,7 @@ def create_files(self, files): dirs = path.dirname(self.path(name)) if not path.exists(dirs): os.makedirs(dirs) - f = open(self.path(name), 'w') + f = codecs.open(self.path(name), 'w', 'utf-8') f.write(data) f.close() diff --git a/tests/helpers.py b/tests/helpers.py index 024a5369..ba243721 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -28,9 +28,9 @@ def assert_raises_regex(expected, regexp, callable, *a, **kw): except expected as e: if isinstance(regexp, basestring): regexp = re.compile(regexp) - if not regexp.search(str(e.message)): - raise self.failureException('"%s" does not match "%s"' % - (regexp.pattern, str(e.message))) + if not regexp.search(str(e)): + raise Exception('"%s" does not match "%s"' % + (regexp.pattern, str(e))) else: if hasattr(expected,'__name__'): excName = expected.__name__ else: excName = str(expected) diff --git a/tests/test_filters.py b/tests/test_filters.py index b335b61f..27cdfeb0 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -1,3 +1,4 @@ +# coding: utf-8 from __future__ import print_function from __future__ import with_statement @@ -203,8 +204,8 @@ class Filter(self.MockTool): method = 'input' assert getattr(Filter, 'output') is None assert getattr(Filter, 'open') is None - Filter().input(StringIO('bla'), StringIO()) - assert Filter.result == ([], 'bla') + Filter().input(StringIO(u'błä'), StringIO()) + assert Filter.result == ([], u'błä') def test_method_output(self): """The method=output.""" @@ -212,8 +213,8 @@ class Filter(self.MockTool): method = 'output' assert getattr(Filter, 'input') is None assert getattr(Filter, 'open') is None - Filter().output(StringIO('bla'), StringIO()) - assert Filter.result == ([], 'bla') + Filter().output(StringIO(u'błä'), StringIO()) + assert Filter.result == ([], u'błä') def test_method_open(self): """The method=open.""" @@ -449,18 +450,24 @@ def my_filter(_in, out): class TestBuiltinFilters(TempEnvironmentHelper): default_files = { - 'foo.css': """ + 'foo.css': u""" + /* Cômment wíth sóme Ünicòde */ h1 { font-family: "Verdana" ; color: #FFFFFF; } """, - 'foo.js': """ + 'foo.js': u""" + // Cômment wíth sóme Ünicòde function foo(bar) { var dummy; document.write ( bar ); /* Write */ + var a = "Ünícôdè"; } """, + 'foo2.js': """ + more(); + """ } def test_cssmin(self): @@ -488,12 +495,25 @@ def test_clevercss(self): self.mkbundle('in', filters='clevercss', output='out.css').build() assert self.get('out.css') == """a {\n color: #7f7f7f;\n}""" - def test_uglifyjs(self): + def test_uglifyjs_ascii(self): + if not find_executable('uglifyjs'): + raise SkipTest() + self.mkbundle('foo2.js', filters='uglifyjs', output='out.js').build() + print(self.get('out.js')) + assert self.get('out.js') == 'more();' + + def test_uglifyjs_unicode(self): if not find_executable('uglifyjs'): raise SkipTest() self.mkbundle('foo.js', filters='uglifyjs', output='out.js').build() - assert self.get('out.js') == 'function foo(bar){var dummy;document.write(bar)}' + assert self.get('out.js') == 'function foo(bar){var dummy;document.write(bar);var a="Ünícôdè"}' + def test_uglifyjs_ascii_and_unicode(self): + if not find_executable('uglifyjs'): + raise SkipTest() + self.mkbundle('foo.js', 'foo2.js', filters='uglifyjs', output='out.js').build() + assert self.get('out.js') == 'function foo(bar){var dummy;document.write(bar);var a="Ünícôdè"}more();' + def test_less_ruby(self): # TODO: Currently no way to differentiate the ruby lessc from the # JS one. Maybe the solution is just to remove the old ruby filter. @@ -509,9 +529,9 @@ def test_jsmin(self): self.mkbundle('foo.js', filters='jsmin', output='out.js').build() assert self.get('out.js') in ( # Builtin jsmin - "\nfunction foo(bar){var dummy;document.write(bar);}", + "\nfunction foo(bar){var dummy;document.write(bar);var a=\"Ünícôdè\"}", # jsmin from PyPI - "function foo(bar){var dummy;document.write(bar);}", + "function foo(bar){var dummy;document.write(bar);var a=\"Ünícôdè\"}", ) def test_rjsmin(self): @@ -520,7 +540,7 @@ def test_rjsmin(self): except ImportError: raise SkipTest() self.mkbundle('foo.js', filters='rjsmin', output='out.js').build() - assert self.get('out.js') == "function foo(bar){var dummy;document.write(bar);}" + assert self.get('out.js') == "function foo(bar){var dummy;document.write(bar);var a=\"Ünícôdè\"}" def test_jspacker(self): self.mkbundle('foo.js', filters='jspacker', output='out.js').build() @@ -642,7 +662,8 @@ def test_bare_option(self): class TestClosure(TempEnvironmentHelper): default_files = { - 'foo.js': """ + 'foo.js': u""" + // Cômment wíth sóme Ünicòde function foo(bar) { var dummy; document.write ( bar ); /* Write */