1# -*- coding: utf-8 -*-
2
3#
4# furl - URL manipulation made simple.
5#
6# Ansgar Grunseid
7# grunseid.com
8# grunseid@gmail.com
9#
10# License: Build Amazing Things (Unlicense)
11#
12
13import unittest
14from itertools import chain, product, permutations
15
16import six
17from furl.omdict1D import omdict1D
18from orderedmultidict import omdict
19
20_unique = object()
21
22
23class TestOmdict1D(unittest.TestCase):
24
25    def setUp(self):
26        self.key = 'sup'
27        self.keys = [1, 2, -1, 'a', None, 0.9]
28        self.values = [1, 2, None]
29        self.valuelists = [[], [1], [1, 2, 3], [None, None, 1]]
30
31    def test_update_updateall(self):
32        data, omd1, omd2 = omdict(), omdict1D(), omdict1D()
33
34        # All permutations of (self.keys, self.values) and (self.keys,
35        # self.valuelists).
36        allitems = chain(product(self.keys, self.values),
37                         product(self.keys, self.valuelists))
38
39        # All updates of length one item, two items, and three items.
40        iterators = [permutations(allitems, 1),
41                     permutations(allitems, 2),
42                     permutations(allitems, 3),
43                     permutations(allitems, 4),
44                     ]
45
46        for iterator in iterators:
47            for update in iterator:
48                data.update(update)
49                omd1.update(update)
50                omd2.updateall(update)
51                for key in six.iterkeys(omd1):
52                    if isinstance(data[key], list):
53                        assert omd1[key] == data[key][-1]
54                    else:
55                        assert omd1[key] == data[key]
56                for key in six.iterkeys(omd2):
57                    data_values_unpacked = []
58                    for value in data.getlist(key):
59                        if isinstance(value, list):
60                            data_values_unpacked.extend(value)
61                        else:
62                            data_values_unpacked.append(value)
63
64                    assert omd2.getlist(key) == data_values_unpacked
65
66        # Test different empty list value locations.
67        update_tests = [([(1, None), (2, None)],
68                         [(1, [1, 11]), (2, [2, 22])],
69                         [(1, 11), (2, 22)]),
70                        ([(1, None), (2, None)],
71                         [(1, []), (1, 1), (1, 11)],
72                         [(1, 11), (2, None)]),
73                        ([(1, None), (2, None)],
74                         [(1, 1), (1, []), (1, 11)],
75                         [(1, 11), (2, None)]),
76                        ([(1, None), (2, None)],
77                         [(1, 1), (1, 11), (1, [])],
78                         [(2, None)]),
79                        ]
80        for init, update, result in update_tests:
81            omd = omdict1D(init)
82            omd.update(update)
83            assert omd.allitems() == result
84
85        updateall_tests = [([(1, None), (2, None)],
86                            [(1, [1, 11]), (2, [2, 22])],
87                            [(1, 1), (2, 2), (1, 11), (2, 22)]),
88                           ([(1, None), (2, None)],
89                            [(1, []), (1, 1), (1, 11)],
90                            [(1, 1), (2, None), (1, 11)]),
91                           ([(1, None), (2, None)],
92                            [(1, 1), (1, []), (1, 11)],
93                            [(1, 11), (2, None)]),
94                           ([(1, None), (2, None)],
95                            [(1, 1), (1, 11), (1, [])],
96                            [(2, None)]),
97                           ]
98        for init, update, result in updateall_tests:
99            omd = omdict1D(init)
100            omd.updateall(update)
101            assert omd.allitems() == result
102
103    def test_add(self):
104        runningsum = []
105        omd = omdict1D()
106        for valuelist in self.valuelists:
107            runningsum += valuelist
108            if valuelist:
109                assert omd.add(self.key, valuelist) == omd
110                assert omd[self.key] == omd.get(self.key) == runningsum[0]
111                assert omd.getlist(self.key) == runningsum
112            else:
113                assert self.key not in omd
114
115        runningsum = []
116        omd = omdict1D()
117        for value in self.values:
118            runningsum += [value]
119            assert omd.add(self.key, value) == omd
120            assert omd[self.key] == omd.get(self.key) == runningsum[0]
121            assert omd.getlist(self.key) == runningsum
122
123        # Empty list of values adds nothing.
124        assert _unique not in omd
125        assert omd.add(_unique, []) == omd
126        assert _unique not in omd
127
128    def test_set(self):
129        omd1, omd2, omd3 = omdict1D(), omdict1D(), omdict1D()
130
131        for valuelist in self.valuelists:
132            omd1[self.key] = valuelist
133            assert omd2.set(self.key, valuelist) == omd2
134            assert omd3.setlist(self.key, valuelist) == omd3
135            assert omd1 == omd2 == omd3 and omd1.getlist(self.key) == valuelist
136
137        # Empty list of values deletes that key and all its values,
138        # equivalent to del omd[somekey].
139        omd = omdict1D()
140        assert _unique not in omd
141        omd.set(_unique, [])
142        assert omd == omd
143        assert _unique not in omd
144
145        omd.set(_unique, [1, 2, 3])
146        assert omd.getlist(_unique) == [1, 2, 3]
147        omd.set(_unique, [])
148        assert _unique not in omd
149
150    def test_setitem(self):
151        omd = omdict1D()
152        for value, valuelist in six.moves.zip(self.values, self.valuelists):
153            if valuelist:
154                omd[self.key] = valuelist
155                assert omd[self.key] == omd.get(self.key) == valuelist[0]
156                assert omd.getlist(self.key) == valuelist
157            else:
158                assert self.key not in omd
159
160            omd[self.key] = value
161            assert omd[self.key] == omd.get(self.key) == value
162            assert omd.getlist(self.key) == [value]
163
164        # Empty list of values deletes that key and all its values,
165        # equivalent to del omd[somekey].
166        omd = omdict1D()
167        assert _unique not in omd
168        omd[_unique] = []
169        assert omd == omd
170        assert _unique not in omd
171
172        omd[_unique] = [1, 2, 3]
173        assert omd.getlist(_unique) == [1, 2, 3]
174        omd[_unique] = []
175        assert _unique not in omd
176