Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/websdk/werkzeug/testsuite/datastructures.py
diff options
context:
space:
mode:
Diffstat (limited to 'websdk/werkzeug/testsuite/datastructures.py')
-rw-r--r--websdk/werkzeug/testsuite/datastructures.py618
1 files changed, 618 insertions, 0 deletions
diff --git a/websdk/werkzeug/testsuite/datastructures.py b/websdk/werkzeug/testsuite/datastructures.py
new file mode 100644
index 0000000..3efedb7
--- /dev/null
+++ b/websdk/werkzeug/testsuite/datastructures.py
@@ -0,0 +1,618 @@
+# -*- coding: utf-8 -*-
+"""
+ werkzeug.testsuite.datastructures
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Tests the functionality of the provided Werkzeug
+ datastructures.
+
+ TODO:
+
+ - FileMultiDict
+ - convert to proper asserts
+ - Immutable types undertested
+ - Split up dict tests
+
+ :copyright: (c) 2011 by Armin Ronacher.
+ :license: BSD, see LICENSE for more details.
+"""
+
+from __future__ import with_statement
+
+import unittest
+import pickle
+from copy import copy
+from werkzeug.testsuite import WerkzeugTestCase
+
+from werkzeug import datastructures
+from werkzeug.exceptions import BadRequestKeyError
+
+
+class MutableMultiDictBaseTestCase(WerkzeugTestCase):
+ storage_class = None
+
+ def test_pickle(self):
+ cls = self.storage_class
+
+ for protocol in xrange(pickle.HIGHEST_PROTOCOL + 1):
+ d = cls()
+ d.setlist('foo', [1, 2, 3, 4])
+ d.setlist('bar', 'foo bar baz'.split())
+ s = pickle.dumps(d, protocol)
+ ud = pickle.loads(s)
+ self.assert_equal(type(ud), type(d))
+ self.assert_equal(ud, d)
+ self.assert_equal(pickle.loads(
+ s.replace('werkzeug.datastructures', 'werkzeug')), d)
+ ud['newkey'] = 'bla'
+ self.assert_not_equal(ud, d)
+
+ def test_basic_interface(self):
+ md = self.storage_class()
+ assert isinstance(md, dict)
+
+ mapping = [('a', 1), ('b', 2), ('a', 2), ('d', 3),
+ ('a', 1), ('a', 3), ('d', 4), ('c', 3)]
+ md = self.storage_class(mapping)
+
+ # simple getitem gives the first value
+ assert md['a'] == 1
+ assert md['c'] == 3
+ with self.assert_raises(KeyError):
+ md['e']
+ assert md.get('a') == 1
+
+ # list getitem
+ assert md.getlist('a') == [1, 2, 1, 3]
+ assert md.getlist('d') == [3, 4]
+ # do not raise if key not found
+ assert md.getlist('x') == []
+
+ # simple setitem overwrites all values
+ md['a'] = 42
+ assert md.getlist('a') == [42]
+
+ # list setitem
+ md.setlist('a', [1, 2, 3])
+ assert md['a'] == 1
+ assert md.getlist('a') == [1, 2, 3]
+
+ # verify that it does not change original lists
+ l1 = [1, 2, 3]
+ md.setlist('a', l1)
+ del l1[:]
+ assert md['a'] == 1
+
+ # setdefault, setlistdefault
+ assert md.setdefault('u', 23) == 23
+ assert md.getlist('u') == [23]
+ del md['u']
+
+ md.setlist('u', [-1, -2])
+
+ # delitem
+ del md['u']
+ with self.assert_raises(KeyError):
+ md['u']
+ del md['d']
+ assert md.getlist('d') == []
+
+ # keys, values, items, lists
+ assert list(sorted(md.keys())) == ['a', 'b', 'c']
+ assert list(sorted(md.iterkeys())) == ['a', 'b', 'c']
+
+ assert list(sorted(md.values())) == [1, 2, 3]
+ assert list(sorted(md.itervalues())) == [1, 2, 3]
+
+ assert list(sorted(md.items())) == [('a', 1), ('b', 2), ('c', 3)]
+ assert list(sorted(md.items(multi=True))) == \
+ [('a', 1), ('a', 2), ('a', 3), ('b', 2), ('c', 3)]
+ assert list(sorted(md.iteritems())) == [('a', 1), ('b', 2), ('c', 3)]
+ assert list(sorted(md.iteritems(multi=True))) == \
+ [('a', 1), ('a', 2), ('a', 3), ('b', 2), ('c', 3)]
+
+ assert list(sorted(md.lists())) == [('a', [1, 2, 3]), ('b', [2]), ('c', [3])]
+ assert list(sorted(md.iterlists())) == [('a', [1, 2, 3]), ('b', [2]), ('c', [3])]
+
+ # copy method
+ c = md.copy()
+ assert c['a'] == 1
+ assert c.getlist('a') == [1, 2, 3]
+
+ # copy method 2
+ c = copy(md)
+ assert c['a'] == 1
+ assert c.getlist('a') == [1, 2, 3]
+
+ # update with a multidict
+ od = self.storage_class([('a', 4), ('a', 5), ('y', 0)])
+ md.update(od)
+ assert md.getlist('a') == [1, 2, 3, 4, 5]
+ assert md.getlist('y') == [0]
+
+ # update with a regular dict
+ md = c
+ od = {'a': 4, 'y': 0}
+ md.update(od)
+ assert md.getlist('a') == [1, 2, 3, 4]
+ assert md.getlist('y') == [0]
+
+ # pop, poplist, popitem, popitemlist
+ assert md.pop('y') == 0
+ assert 'y' not in md
+ assert md.poplist('a') == [1, 2, 3, 4]
+ assert 'a' not in md
+ assert md.poplist('missing') == []
+
+ # remaining: b=2, c=3
+ popped = md.popitem()
+ assert popped in [('b', 2), ('c', 3)]
+ popped = md.popitemlist()
+ assert popped in [('b', [2]), ('c', [3])]
+
+ # type conversion
+ md = self.storage_class({'a': '4', 'b': ['2', '3']})
+ assert md.get('a', type=int) == 4
+ assert md.getlist('b', type=int) == [2, 3]
+
+ # repr
+ md = self.storage_class([('a', 1), ('a', 2), ('b', 3)])
+ assert "('a', 1)" in repr(md)
+ assert "('a', 2)" in repr(md)
+ assert "('b', 3)" in repr(md)
+
+ # add and getlist
+ md.add('c', '42')
+ md.add('c', '23')
+ assert md.getlist('c') == ['42', '23']
+ md.add('c', 'blah')
+ assert md.getlist('c', type=int) == [42, 23]
+
+ # setdefault
+ md = self.storage_class()
+ md.setdefault('x', []).append(42)
+ md.setdefault('x', []).append(23)
+ assert md['x'] == [42, 23]
+
+ # to dict
+ md = self.storage_class()
+ md['foo'] = 42
+ md.add('bar', 1)
+ md.add('bar', 2)
+ assert md.to_dict() == {'foo': 42, 'bar': 1}
+ assert md.to_dict(flat=False) == {'foo': [42], 'bar': [1, 2]}
+
+ # popitem from empty dict
+ with self.assert_raises(KeyError):
+ self.storage_class().popitem()
+
+ with self.assert_raises(KeyError):
+ self.storage_class().popitemlist()
+
+ # key errors are of a special type
+ with self.assert_raises(BadRequestKeyError):
+ self.storage_class()[42]
+
+ # setlist works
+ md = self.storage_class()
+ md['foo'] = 42
+ md.setlist('foo', [1, 2])
+ assert md.getlist('foo') == [1, 2]
+
+
+class ImmutableDictBaseTestCase(WerkzeugTestCase):
+ storage_class = None
+
+ def test_follows_dict_interface(self):
+ cls = self.storage_class
+
+ data = {'foo': 1, 'bar': 2, 'baz': 3}
+ d = cls(data)
+
+ self.assert_equal(d['foo'], 1)
+ self.assert_equal(d['bar'], 2)
+ self.assert_equal(d['baz'], 3)
+ self.assert_equal(sorted(d.keys()), ['bar', 'baz', 'foo'])
+ self.assert_('foo' in d)
+ self.assert_('foox' not in d)
+ self.assert_equal(len(d), 3)
+
+ def test_copies_are_mutable(self):
+ cls = self.storage_class
+ immutable = cls({'a': 1})
+ with self.assert_raises(TypeError):
+ immutable.pop('a')
+
+ mutable = immutable.copy()
+ mutable.pop('a')
+ self.assert_('a' in immutable)
+ self.assert_(mutable is not immutable)
+ self.assert_(copy(immutable) is immutable)
+
+ def test_dict_is_hashable(self):
+ cls = self.storage_class
+ immutable = cls({'a': 1, 'b': 2})
+ immutable2 = cls({'a': 2, 'b': 2})
+ x = set([immutable])
+ self.assert_(immutable in x)
+ self.assert_(immutable2 not in x)
+ x.discard(immutable)
+ self.assert_(immutable not in x)
+ self.assert_(immutable2 not in x)
+ x.add(immutable2)
+ self.assert_(immutable not in x)
+ self.assert_(immutable2 in x)
+ x.add(immutable)
+ self.assert_(immutable in x)
+ self.assert_(immutable2 in x)
+
+
+class ImmutableTypeConversionDictTestCase(ImmutableDictBaseTestCase):
+ storage_class = datastructures.ImmutableTypeConversionDict
+
+
+class ImmutableMultiDictTestCase(ImmutableDictBaseTestCase):
+ storage_class = datastructures.ImmutableMultiDict
+
+ def test_multidict_is_hashable(self):
+ cls = self.storage_class
+ immutable = cls({'a': [1, 2], 'b': 2})
+ immutable2 = cls({'a': [1], 'b': 2})
+ x = set([immutable])
+ self.assert_(immutable in x)
+ self.assert_(immutable2 not in x)
+ x.discard(immutable)
+ self.assert_(immutable not in x)
+ self.assert_(immutable2 not in x)
+ x.add(immutable2)
+ self.assert_(immutable not in x)
+ self.assert_(immutable2 in x)
+ x.add(immutable)
+ self.assert_(immutable in x)
+ self.assert_(immutable2 in x)
+
+
+class ImmutableDictTestCase(ImmutableDictBaseTestCase):
+ storage_class = datastructures.ImmutableDict
+
+
+class ImmutableOrderedMultiDictTestCase(ImmutableDictBaseTestCase):
+ storage_class = datastructures.ImmutableOrderedMultiDict
+
+ def test_ordered_multidict_is_hashable(self):
+ a = self.storage_class([('a', 1), ('b', 1), ('a', 2)])
+ b = self.storage_class([('a', 1), ('a', 2), ('b', 1)])
+ self.assert_not_equal(hash(a), hash(b))
+
+
+class MultiDictTestCase(MutableMultiDictBaseTestCase):
+ storage_class = datastructures.MultiDict
+
+ def test_multidict_pop(self):
+ make_d = lambda: self.storage_class({'foo': [1, 2, 3, 4]})
+ d = make_d()
+ assert d.pop('foo') == 1
+ assert not d
+ d = make_d()
+ assert d.pop('foo', 32) == 1
+ assert not d
+ d = make_d()
+ assert d.pop('foos', 32) == 32
+ assert d
+
+ with self.assert_raises(KeyError):
+ d.pop('foos')
+
+ def test_setlistdefault(self):
+ md = self.storage_class()
+ assert md.setlistdefault('u', [-1, -2]) == [-1, -2]
+ assert md.getlist('u') == [-1, -2]
+ assert md['u'] == -1
+
+ def test_iter_interfaces(self):
+ mapping = [('a', 1), ('b', 2), ('a', 2), ('d', 3),
+ ('a', 1), ('a', 3), ('d', 4), ('c', 3)]
+ md = self.storage_class(mapping)
+ assert list(zip(md.keys(), md.listvalues())) == list(md.lists())
+ assert list(zip(md, md.iterlistvalues())) == list(md.iterlists())
+ assert list(zip(md.iterkeys(), md.iterlistvalues())) == list(md.iterlists())
+
+
+class OrderedMultiDictTestCase(MutableMultiDictBaseTestCase):
+ storage_class = datastructures.OrderedMultiDict
+
+ def test_ordered_interface(self):
+ cls = self.storage_class
+
+ d = cls()
+ assert not d
+ d.add('foo', 'bar')
+ assert len(d) == 1
+ d.add('foo', 'baz')
+ assert len(d) == 1
+ assert d.items() == [('foo', 'bar')]
+ assert list(d) == ['foo']
+ assert d.items(multi=True) == [('foo', 'bar'),
+ ('foo', 'baz')]
+ del d['foo']
+ assert not d
+ assert len(d) == 0
+ assert list(d) == []
+
+ d.update([('foo', 1), ('foo', 2), ('bar', 42)])
+ d.add('foo', 3)
+ assert d.getlist('foo') == [1, 2, 3]
+ assert d.getlist('bar') == [42]
+ assert d.items() == [('foo', 1), ('bar', 42)]
+ assert d.keys() == list(d) == list(d.iterkeys()) == ['foo', 'bar']
+ assert d.items(multi=True) == [('foo', 1), ('foo', 2),
+ ('bar', 42), ('foo', 3)]
+ assert len(d) == 2
+
+ assert d.pop('foo') == 1
+ assert d.pop('blafasel', None) is None
+ assert d.pop('blafasel', 42) == 42
+ assert len(d) == 1
+ assert d.poplist('bar') == [42]
+ assert not d
+
+ d.get('missingkey') is None
+
+ d.add('foo', 42)
+ d.add('foo', 23)
+ d.add('bar', 2)
+ d.add('foo', 42)
+ assert d == datastructures.MultiDict(d)
+ id = self.storage_class(d)
+ assert d == id
+ d.add('foo', 2)
+ assert d != id
+
+ d.update({'blah': [1, 2, 3]})
+ assert d['blah'] == 1
+ assert d.getlist('blah') == [1, 2, 3]
+
+ # setlist works
+ d = self.storage_class()
+ d['foo'] = 42
+ d.setlist('foo', [1, 2])
+ assert d.getlist('foo') == [1, 2]
+
+ with self.assert_raises(BadRequestKeyError):
+ d.pop('missing')
+ with self.assert_raises(BadRequestKeyError):
+ d['missing']
+
+ # popping
+ d = self.storage_class()
+ d.add('foo', 23)
+ d.add('foo', 42)
+ d.add('foo', 1)
+ assert d.popitem() == ('foo', 23)
+ with self.assert_raises(BadRequestKeyError):
+ d.popitem()
+ assert not d
+
+ d.add('foo', 23)
+ d.add('foo', 42)
+ d.add('foo', 1)
+ assert d.popitemlist() == ('foo', [23, 42, 1])
+
+ with self.assert_raises(BadRequestKeyError):
+ d.popitemlist()
+
+
+class CombinedMultiDictTestCase(WerkzeugTestCase):
+ storage_class = datastructures.CombinedMultiDict
+
+ def test_basic_interface(self):
+ d1 = datastructures.MultiDict([('foo', '1')])
+ d2 = datastructures.MultiDict([('bar', '2'), ('bar', '3')])
+ d = self.storage_class([d1, d2])
+
+ # lookup
+ assert d['foo'] == '1'
+ assert d['bar'] == '2'
+ assert d.getlist('bar') == ['2', '3']
+
+ assert sorted(d.items()) == [('bar', '2'), ('foo', '1')], d.items()
+ assert sorted(d.items(multi=True)) == [('bar', '2'), ('bar', '3'), ('foo', '1')]
+ assert 'missingkey' not in d
+ assert 'foo' in d
+
+ # type lookup
+ assert d.get('foo', type=int) == 1
+ assert d.getlist('bar', type=int) == [2, 3]
+
+ # get key errors for missing stuff
+ with self.assert_raises(KeyError):
+ d['missing']
+
+ # make sure that they are immutable
+ with self.assert_raises(TypeError):
+ d['foo'] = 'blub'
+
+ # copies are immutable
+ d = d.copy()
+ with self.assert_raises(TypeError):
+ d['foo'] = 'blub'
+
+ # make sure lists merges
+ md1 = datastructures.MultiDict((("foo", "bar"),))
+ md2 = datastructures.MultiDict((("foo", "blafasel"),))
+ x = self.storage_class((md1, md2))
+ assert x.lists() == [('foo', ['bar', 'blafasel'])]
+
+
+class HeadersTestCase(WerkzeugTestCase):
+ storage_class = datastructures.Headers
+
+ def test_basic_interface(self):
+ headers = self.storage_class()
+ headers.add('Content-Type', 'text/plain')
+ headers.add('X-Foo', 'bar')
+ assert 'x-Foo' in headers
+ assert 'Content-type' in headers
+
+ headers['Content-Type'] = 'foo/bar'
+ assert headers['Content-Type'] == 'foo/bar'
+ assert len(headers.getlist('Content-Type')) == 1
+
+ # list conversion
+ assert headers.to_list() == [
+ ('Content-Type', 'foo/bar'),
+ ('X-Foo', 'bar')
+ ]
+ assert str(headers) == (
+ "Content-Type: foo/bar\r\n"
+ "X-Foo: bar\r\n"
+ "\r\n")
+ assert str(self.storage_class()) == "\r\n"
+
+ # extended add
+ headers.add('Content-Disposition', 'attachment', filename='foo')
+ assert headers['Content-Disposition'] == 'attachment; filename=foo'
+
+ headers.add('x', 'y', z='"')
+ assert headers['x'] == r'y; z="\""'
+
+ def test_defaults_and_conversion(self):
+ # defaults
+ headers = self.storage_class([
+ ('Content-Type', 'text/plain'),
+ ('X-Foo', 'bar'),
+ ('X-Bar', '1'),
+ ('X-Bar', '2')
+ ])
+ assert headers.getlist('x-bar') == ['1', '2']
+ assert headers.get('x-Bar') == '1'
+ assert headers.get('Content-Type') == 'text/plain'
+
+ assert headers.setdefault('X-Foo', 'nope') == 'bar'
+ assert headers.setdefault('X-Bar', 'nope') == '1'
+ assert headers.setdefault('X-Baz', 'quux') == 'quux'
+ assert headers.setdefault('X-Baz', 'nope') == 'quux'
+ headers.pop('X-Baz')
+
+ # type conversion
+ assert headers.get('x-bar', type=int) == 1
+ assert headers.getlist('x-bar', type=int) == [1, 2]
+
+ # list like operations
+ assert headers[0] == ('Content-Type', 'text/plain')
+ assert headers[:1] == self.storage_class([('Content-Type', 'text/plain')])
+ del headers[:2]
+ del headers[-1]
+ assert headers == self.storage_class([('X-Bar', '1')])
+
+ def test_copying(self):
+ a = self.storage_class([('foo', 'bar')])
+ b = a.copy()
+ a.add('foo', 'baz')
+ assert a.getlist('foo') == ['bar', 'baz']
+ assert b.getlist('foo') == ['bar']
+
+ def test_popping(self):
+ headers = self.storage_class([('a', 1)])
+ assert headers.pop('a') == 1
+ assert headers.pop('b', 2) == 2
+
+ with self.assert_raises(KeyError):
+ headers.pop('c')
+
+ def test_set_arguments(self):
+ a = self.storage_class()
+ a.set('Content-Disposition', 'useless')
+ a.set('Content-Disposition', 'attachment', filename='foo')
+ assert a['Content-Disposition'] == 'attachment; filename=foo'
+
+ def test_reject_newlines(self):
+ h = self.storage_class()
+
+ for variation in 'foo\nbar', 'foo\r\nbar', 'foo\rbar':
+ with self.assert_raises(ValueError):
+ h['foo'] = variation
+ with self.assert_raises(ValueError):
+ h.add('foo', variation)
+ with self.assert_raises(ValueError):
+ h.add('foo', 'test', option=variation)
+ with self.assert_raises(ValueError):
+ h.set('foo', variation)
+ with self.assert_raises(ValueError):
+ h.set('foo', 'test', option=variation)
+
+
+class EnvironHeadersTestCase(WerkzeugTestCase):
+ storage_class = datastructures.EnvironHeaders
+
+ def test_basic_interface(self):
+ # this happens in multiple WSGI servers because they
+ # use a vary naive way to convert the headers;
+ broken_env = {
+ 'HTTP_CONTENT_TYPE': 'text/html',
+ 'CONTENT_TYPE': 'text/html',
+ 'HTTP_CONTENT_LENGTH': '0',
+ 'CONTENT_LENGTH': '0',
+ 'HTTP_ACCEPT': '*',
+ 'wsgi.version': (1, 0)
+ }
+ headers = self.storage_class(broken_env)
+ assert headers
+ assert len(headers) == 3
+ assert sorted(headers) == [
+ ('Accept', '*'),
+ ('Content-Length', '0'),
+ ('Content-Type', 'text/html')
+ ]
+ assert not self.storage_class({'wsgi.version': (1, 0)})
+ assert len(self.storage_class({'wsgi.version': (1, 0)})) == 0
+
+
+class HeaderSetTestCase(WerkzeugTestCase):
+ storage_class = datastructures.HeaderSet
+
+ def test_basic_interface(self):
+ hs = self.storage_class()
+ hs.add('foo')
+ hs.add('bar')
+ assert 'Bar' in hs
+ assert hs.find('foo') == 0
+ assert hs.find('BAR') == 1
+ assert hs.find('baz') < 0
+ hs.discard('missing')
+ hs.discard('foo')
+ assert hs.find('foo') < 0
+ assert hs.find('bar') == 0
+
+ with self.assert_raises(IndexError):
+ hs.index('missing')
+
+ assert hs.index('bar') == 0
+ assert hs
+ hs.clear()
+ assert not hs
+
+
+class ImmutableListTestCase(WerkzeugTestCase):
+ storage_class = datastructures.ImmutableList
+
+ def test_list_hashable(self):
+ t = (1, 2, 3, 4)
+ l = self.storage_class(t)
+ self.assert_equal(hash(t), hash(l))
+ self.assert_not_equal(t, l)
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(MultiDictTestCase))
+ suite.addTest(unittest.makeSuite(OrderedMultiDictTestCase))
+ suite.addTest(unittest.makeSuite(CombinedMultiDictTestCase))
+ suite.addTest(unittest.makeSuite(ImmutableTypeConversionDictTestCase))
+ suite.addTest(unittest.makeSuite(ImmutableMultiDictTestCase))
+ suite.addTest(unittest.makeSuite(ImmutableDictTestCase))
+ suite.addTest(unittest.makeSuite(ImmutableOrderedMultiDictTestCase))
+ suite.addTest(unittest.makeSuite(HeadersTestCase))
+ suite.addTest(unittest.makeSuite(EnvironHeadersTestCase))
+ suite.addTest(unittest.makeSuite(HeaderSetTestCase))
+ return suite