# -*- coding: utf-8 -*- """ werkzeug.utils test ~~~~~~~~~~~~~~~~~~~ :copyright: (c) 2010 by the Werkzeug Team, see AUTHORS for more details. :license: BSD license. """ import sys from datetime import datetime from StringIO import StringIO from nose.tools import assert_raises from werkzeug.utils import * from werkzeug.wrappers import BaseResponse, Request from werkzeug.http import parse_date from werkzeug.test import Client, run_wsgi_app, create_environ def test_import_patch(): """Import patch""" import werkzeug from werkzeug import __all__ as public_methods for name in public_methods: getattr(werkzeug, name) def test_cached_property(): """Cached property decorator""" foo = [] class A(object): def prop(self): foo.append(42) return 42 prop = cached_property(prop) a = A() p = a.prop q = a.prop assert p == q == 42 assert foo == [42] foo = [] class A(object): def _prop(self): foo.append(42) return 42 prop = cached_property(_prop, name='prop') del _prop a = A() p = a.prop q = a.prop assert p == q == 42 assert foo == [42] def test_environ_property(): """Environ property descriptor""" class A(object): environ = {'string': 'abc', 'number': '42'} string = environ_property('string') missing = environ_property('missing', 'spam') read_only = environ_property('number') number = environ_property('number', load_func=int) broken_number = environ_property('broken_number', load_func=int) date = environ_property('date', None, parse_date, http_date, read_only=False) foo = environ_property('foo') a = A() assert a.string == 'abc' assert a.missing == 'spam' def test_assign(): a.read_only = 'something' assert_raises(AttributeError, test_assign) assert a.number == 42 assert a.broken_number == None assert a.date is None a.date = datetime(2008, 1, 22, 10, 0, 0, 0) assert a.environ['date'] == 'Tue, 22 Jan 2008 10:00:00 GMT' def test_escape(): """XML/HTML escaping""" class Foo(str): def __html__(self): return unicode(self) assert escape(None) == '' assert escape(42) == '42' assert escape('<>') == '<>' assert escape('"foo"') == '"foo"' assert escape('"foo"', True) == '"foo"' assert escape(Foo('')) == '' def test_unescape(): """XML/HTML unescaping""" assert unescape('<ä>') == u'<รค>' def test_run_wsgi_app(): """WSGI test-runner""" def foo(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) yield '1' yield '2' yield '3' app_iter, status, headers = run_wsgi_app(foo, {}) assert status == '200 OK' assert headers == [('Content-Type', 'text/plain')] assert app_iter.next() == '1' assert app_iter.next() == '2' assert app_iter.next() == '3' assert_raises(StopIteration, app_iter.next) got_close = [] class CloseIter(object): def __init__(self): self.iterated = False def __iter__(self): return self def close(self): got_close.append(None) def next(self): if self.iterated: raise StopIteration() self.iterated = True return 'bar' def bar(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return CloseIter() app_iter, status, headers = run_wsgi_app(bar, {}) assert status == '200 OK' assert headers == [('Content-Type', 'text/plain')] assert app_iter.next() == 'bar' assert_raises(StopIteration, app_iter.next) app_iter.close() assert run_wsgi_app(bar, {}, True)[0] == ['bar'] assert len(got_close) == 2 def test_dates(): """Date formatting""" assert cookie_date(0) == 'Thu, 01-Jan-1970 00:00:00 GMT' assert cookie_date(datetime(1970, 1, 1)) == 'Thu, 01-Jan-1970 00:00:00 GMT' assert http_date(0) == 'Thu, 01 Jan 1970 00:00:00 GMT' assert http_date(datetime(1970, 1, 1)) == 'Thu, 01 Jan 1970 00:00:00 GMT' def test_cookies(): """Cookie parsing""" assert parse_cookie('dismiss-top=6; CP=null*; PHPSESSID=0a539d42abc001cd' 'c762809248d4beed; a=42') == { 'CP': u'null*', 'PHPSESSID': u'0a539d42abc001cdc762809248d4beed', 'a': u'42', 'dismiss-top': u'6' } assert set(dump_cookie('foo', 'bar baz blub', 360, httponly=True, sync_expires=False).split('; ')) == \ set(['HttpOnly', 'Max-Age=360', 'Path=/', 'foo="bar baz blub"']) assert parse_cookie('fo234{=bar blub=Blah') == {'blub': 'Blah'} def test_cookie_quoting(): """Cookie value quoting.""" val = dump_cookie("foo", "?foo") assert val == 'foo="?foo"; Path=/' assert parse_cookie(val) == {'foo': '?foo'} def test_import_string(): """String based importing""" import cgi from werkzeug.debug import DebuggedApplication assert import_string('cgi.escape') is cgi.escape assert import_string(u'cgi.escape') is cgi.escape assert import_string('cgi:escape') is cgi.escape assert import_string('XXXXXXXXXXXX', True) is None assert import_string('cgi.XXXXXXXXXXXX', True) is None assert import_string(u'cgi.escape') is cgi.escape assert import_string(u'werkzeug.debug.DebuggedApplication') is DebuggedApplication assert_raises(ImportError, import_string, 'XXXXXXXXXXXXXXXX') assert_raises(AttributeError, import_string, 'cgi.XXXXXXXXXX') def test_find_modules(): """Module and package lookup""" assert list(find_modules('werkzeug.debug')) == \ ['werkzeug.debug.console', 'werkzeug.debug.render', 'werkzeug.debug.repr', 'werkzeug.debug.tbtools', 'werkzeug.debug.utils'] def test_html_builder(): """HTML builder""" assert html.p('Hello World') == '

Hello World

' assert html.a('Test', href='#') == 'Test' assert html.br() == '
' assert xhtml.br() == '
' assert html.img(src='foo') == '' assert xhtml.img(src='foo') == '' assert html.html( html.head( html.title('foo'), html.script(type='text/javascript') ) ) == 'foo' assert html('') == '<foo>' def test_validate_arguments(): """Function argument validator""" take_none = lambda: None take_two = lambda a, b: None take_two_one_default = lambda a, b=0: None assert validate_arguments(take_two, (1, 2,), {}) == ((1, 2), {}) assert validate_arguments(take_two, (1,), {'b': 2}) == ((1, 2), {}) assert validate_arguments(take_two_one_default, (1,), {}) == ((1, 0), {}) assert validate_arguments(take_two_one_default, (1, 2), {}) == ((1, 2), {}) assert_raises(ArgumentValidationError, validate_arguments, take_two, (), {}) assert validate_arguments(take_none, (1, 2,), {'c': 3}) == ((), {}) assert_raises(ArgumentValidationError, validate_arguments, take_none, (1,), {}, drop_extra=False) assert_raises(ArgumentValidationError, validate_arguments, take_none, (), {'a': 1}, drop_extra=False) def test_header_set_duplication_bug(): """Header duplication bug on set""" from werkzeug.datastructures import Headers headers = Headers([ ('Content-Type', 'text/html'), ('Foo', 'bar'), ('Blub', 'blah') ]) headers['blub'] = 'hehe' headers['blafasel'] = 'humm' assert headers == Headers([ ('Content-Type', 'text/html'), ('Foo', 'bar'), ('blub', 'hehe'), ('blafasel', 'humm') ]) def test_append_slash_redirect(): """Append slash redirect""" def app(env, sr): return append_slash_redirect(env)(env, sr) client = Client(app, BaseResponse) response = client.get('foo', base_url='http://example.org/app') assert response.status_code == 301 assert response.headers['Location'] == 'http://example.org/app/foo/' def test_cached_property_doc(): """Documentation of cached_property is kept""" @cached_property def foo(): """testing""" return 42 assert foo.__doc__ == 'testing' assert foo.__name__ == 'foo' assert foo.__module__ == __name__