1b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# -*- coding: utf-8 -*-
2b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# (c) 2007 Ian Bicking and Philip Jenvey; written for Paste (http://pythonpaste.org)
3b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
4b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport cgi
5b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport six
6b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom six.moves import StringIO
7b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
8b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom nose.tools import assert_raises
9b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
10b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom paste.util.multidict import MultiDict, UnicodeMultiDict
11b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
12b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef test_dict():
13b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d = MultiDict({'a': 1})
14b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [('a', 1)]
15b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
16b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d['b'] = 2
17b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d['c'] = 3
18b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [('a', 1), ('b', 2), ('c', 3)]
19b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
20b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d['b'] = 4
21b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [('a', 1), ('c', 3), ('b', 4)]
22b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
23b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d.add('b', 5)
24b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert_raises(KeyError, d.getone, "b")
25b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.getall('b') == [4, 5]
26b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [('a', 1), ('c', 3), ('b', 4), ('b', 5)]
27b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
28b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    del d['b']
29b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [('a', 1), ('c', 3)]
30b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.pop('xxx', 5) == 5
31b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.getone('a') == 1
32b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.popitem() == ('c', 3)
33b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [('a', 1)]
34b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
35b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    item = []
36b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.setdefault('z', item) is item
37b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [('a', 1), ('z', item)]
38b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
39b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.setdefault('y', 6) == 6
40b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
41b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.mixed() == {'a': 1, 'y': 6, 'z': item}
42b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.dict_of_lists() == {'a': [1], 'y': [6], 'z': [item]}
43b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
44b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert 'a' in d
45b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    dcopy = d.copy()
46b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert dcopy is not d
47b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert dcopy == d
48b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d['x'] = 'x test'
49b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert dcopy != d
50b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
51b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d[(1, None)] = (None, 1)
52b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [('a', 1), ('z', []), ('y', 6), ('x', 'x test'),
53b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik                         ((1, None), (None, 1))]
54b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
55b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef test_unicode_dict():
56b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    _test_unicode_dict()
57b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    _test_unicode_dict(decode_param_names=True)
58b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
59b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef _test_unicode_dict(decode_param_names=False):
60b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d = UnicodeMultiDict(MultiDict({b'a': 'a test'}))
61b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d.encoding = 'utf-8'
62b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d.errors = 'ignore'
63b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
64b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    if decode_param_names:
65b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        key_str = six.text_type
66b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        k = lambda key: key
67b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        d.decode_keys = True
68b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    else:
69b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        key_str = six.binary_type
70b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        k = lambda key: key.encode()
71b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
72b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    def assert_unicode(obj):
73b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        assert isinstance(obj, six.text_type)
74b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
75b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    def assert_key_str(obj):
76b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        assert isinstance(obj, key_str)
77b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
78b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    def assert_unicode_item(obj):
79b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        key, value = obj
80b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        assert isinstance(key, key_str)
81b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik        assert isinstance(value, six.text_type)
82b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
83b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [(k('a'), u'a test')]
84b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    map(assert_key_str, d.keys())
85b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    map(assert_unicode, d.values())
86b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
87b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d[b'b'] = b'2 test'
88b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d[b'c'] = b'3 test'
89b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [(k('a'), u'a test'), (k('b'), u'2 test'), (k('c'), u'3 test')]
90b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    list(map(assert_unicode_item, d.items()))
91b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
92b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d[k('b')] = b'4 test'
93b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [(k('a'), u'a test'), (k('c'), u'3 test'), (k('b'), u'4 test')], d.items()
94b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    list(map(assert_unicode_item, d.items()))
95b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
96b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d.add(k('b'), b'5 test')
97b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert_raises(KeyError, d.getone, k("b"))
98b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.getall(k('b')) == [u'4 test', u'5 test']
99b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    map(assert_unicode, d.getall('b'))
100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [(k('a'), u'a test'), (k('c'), u'3 test'), (k('b'), u'4 test'),
101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik                         (k('b'), u'5 test')]
102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    list(map(assert_unicode_item, d.items()))
103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    del d[k('b')]
105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [(k('a'), u'a test'), (k('c'), u'3 test')]
106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    list(map(assert_unicode_item, d.items()))
107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.pop('xxx', u'5 test') == u'5 test'
108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(d.pop('xxx', u'5 test'), six.text_type)
109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.getone(k('a')) == u'a test'
110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(d.getone(k('a')), six.text_type)
111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.popitem() == (k('c'), u'3 test')
112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d[k('c')] = b'3 test'
113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert_unicode_item(d.popitem())
114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [(k('a'), u'a test')]
115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    list(map(assert_unicode_item, d.items()))
116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    item = []
118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.setdefault(k('z'), item) is item
119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    items = d.items()
120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert items == [(k('a'), u'a test'), (k('z'), item)]
121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(items[1][0], key_str)
122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(items[1][1], list)
123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(d.setdefault(k('y'), b'y test'), six.text_type)
125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(d[k('y')], six.text_type)
126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.mixed() == {k('a'): u'a test', k('y'): u'y test', k('z'): item}
128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.dict_of_lists() == {k('a'): [u'a test'], k('y'): [u'y test'],
129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik                                 k('z'): [item]}
130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    del d[k('z')]
131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    list(map(assert_unicode_item, six.iteritems(d.mixed())))
132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    list(map(assert_unicode_item, [(key, value[0]) for \
133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik                                   key, value in six.iteritems(d.dict_of_lists())]))
134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert k('a') in d
136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    dcopy = d.copy()
137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert dcopy is not d
138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert dcopy == d
139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d[k('x')] = 'x test'
140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert dcopy != d
141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d[(1, None)] = (None, 1)
143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert d.items() == [(k('a'), u'a test'), (k('y'), u'y test'), (k('x'), u'x test'),
144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik                         ((1, None), (None, 1))]
145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    item = d.items()[-1]
146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(item[0], tuple)
147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(item[1], tuple)
148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    fs = cgi.FieldStorage()
150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    fs.name = 'thefile'
151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    fs.filename = 'hello.txt'
152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    fs.file = StringIO('hello')
153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    d[k('f')] = fs
154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    ufs = d[k('f')]
155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(ufs, cgi.FieldStorage)
156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert ufs is not fs
157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert ufs.name == fs.name
158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(ufs.name, str if six.PY3 else key_str)
159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert ufs.filename == fs.filename
160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(ufs.filename, six.text_type)
161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert isinstance(ufs.value, str)
162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik    assert ufs.value == 'hello'
163