move sections
[python/dscho.git] / Lib / test / test_userdict.py
blobd5cecd8612f14a000c21d2baf4e35876e013fcc4
1 # Check every path through every method of UserDict
3 from test import test_support, mapping_tests
4 import UserDict
6 d0 = {}
7 d1 = {"one": 1}
8 d2 = {"one": 1, "two": 2}
9 d3 = {"one": 1, "two": 3, "three": 5}
10 d4 = {"one": None, "two": None}
11 d5 = {"one": 1, "two": 1}
13 class UserDictTest(mapping_tests.TestHashMappingProtocol):
14 type2test = UserDict.IterableUserDict
16 def test_all(self):
17 # Test constructors
18 u = UserDict.UserDict()
19 u0 = UserDict.UserDict(d0)
20 u1 = UserDict.UserDict(d1)
21 u2 = UserDict.IterableUserDict(d2)
23 uu = UserDict.UserDict(u)
24 uu0 = UserDict.UserDict(u0)
25 uu1 = UserDict.UserDict(u1)
26 uu2 = UserDict.UserDict(u2)
28 # keyword arg constructor
29 self.assertEqual(UserDict.UserDict(one=1, two=2), d2)
30 # item sequence constructor
31 self.assertEqual(UserDict.UserDict([('one',1), ('two',2)]), d2)
32 self.assertEqual(UserDict.UserDict(dict=[('one',1), ('two',2)]), d2)
33 # both together
34 self.assertEqual(UserDict.UserDict([('one',1), ('two',2)], two=3, three=5), d3)
36 # alternate constructor
37 self.assertEqual(UserDict.UserDict.fromkeys('one two'.split()), d4)
38 self.assertEqual(UserDict.UserDict().fromkeys('one two'.split()), d4)
39 self.assertEqual(UserDict.UserDict.fromkeys('one two'.split(), 1), d5)
40 self.assertEqual(UserDict.UserDict().fromkeys('one two'.split(), 1), d5)
41 self.assertTrue(u1.fromkeys('one two'.split()) is not u1)
42 self.assertIsInstance(u1.fromkeys('one two'.split()), UserDict.UserDict)
43 self.assertIsInstance(u2.fromkeys('one two'.split()), UserDict.IterableUserDict)
45 # Test __repr__
46 self.assertEqual(str(u0), str(d0))
47 self.assertEqual(repr(u1), repr(d1))
48 self.assertEqual(repr(u2), repr(d2))
50 # Test __cmp__ and __len__
51 all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2]
52 for a in all:
53 for b in all:
54 self.assertEqual(cmp(a, b), cmp(len(a), len(b)))
56 # Test __getitem__
57 self.assertEqual(u2["one"], 1)
58 self.assertRaises(KeyError, u1.__getitem__, "two")
60 # Test __setitem__
61 u3 = UserDict.UserDict(u2)
62 u3["two"] = 2
63 u3["three"] = 3
65 # Test __delitem__
66 del u3["three"]
67 self.assertRaises(KeyError, u3.__delitem__, "three")
69 # Test clear
70 u3.clear()
71 self.assertEqual(u3, {})
73 # Test copy()
74 u2a = u2.copy()
75 self.assertEqual(u2a, u2)
76 u2b = UserDict.UserDict(x=42, y=23)
77 u2c = u2b.copy() # making a copy of a UserDict is special cased
78 self.assertEqual(u2b, u2c)
80 class MyUserDict(UserDict.UserDict):
81 def display(self): print self
83 m2 = MyUserDict(u2)
84 m2a = m2.copy()
85 self.assertEqual(m2a, m2)
87 # SF bug #476616 -- copy() of UserDict subclass shared data
88 m2['foo'] = 'bar'
89 self.assertNotEqual(m2a, m2)
91 # Test keys, items, values
92 self.assertEqual(u2.keys(), d2.keys())
93 self.assertEqual(u2.items(), d2.items())
94 self.assertEqual(u2.values(), d2.values())
96 # Test has_key and "in".
97 for i in u2.keys():
98 self.assertIn(i, u2)
99 self.assertEqual(i in u1, i in d1)
100 self.assertEqual(i in u0, i in d0)
101 with test_support.check_py3k_warnings():
102 self.assertTrue(u2.has_key(i))
103 self.assertEqual(u1.has_key(i), d1.has_key(i))
104 self.assertEqual(u0.has_key(i), d0.has_key(i))
106 # Test update
107 t = UserDict.UserDict()
108 t.update(u2)
109 self.assertEqual(t, u2)
110 class Items:
111 def items(self):
112 return (("x", 42), ("y", 23))
113 t = UserDict.UserDict()
114 t.update(Items())
115 self.assertEqual(t, {"x": 42, "y": 23})
117 # Test get
118 for i in u2.keys():
119 self.assertEqual(u2.get(i), u2[i])
120 self.assertEqual(u1.get(i), d1.get(i))
121 self.assertEqual(u0.get(i), d0.get(i))
123 # Test "in" iteration.
124 for i in xrange(20):
125 u2[i] = str(i)
126 ikeys = []
127 for k in u2:
128 ikeys.append(k)
129 keys = u2.keys()
130 self.assertEqual(set(ikeys), set(keys))
132 # Test setdefault
133 t = UserDict.UserDict()
134 self.assertEqual(t.setdefault("x", 42), 42)
135 self.assertTrue(t.has_key("x"))
136 self.assertEqual(t.setdefault("x", 23), 42)
138 # Test pop
139 t = UserDict.UserDict(x=42)
140 self.assertEqual(t.pop("x"), 42)
141 self.assertRaises(KeyError, t.pop, "x")
142 self.assertEqual(t.pop("x", 1), 1)
143 t["x"] = 42
144 self.assertEqual(t.pop("x", 1), 42)
146 # Test popitem
147 t = UserDict.UserDict(x=42)
148 self.assertEqual(t.popitem(), ("x", 42))
149 self.assertRaises(KeyError, t.popitem)
151 def test_missing(self):
152 # Make sure UserDict doesn't have a __missing__ method
153 self.assertEqual(hasattr(UserDict, "__missing__"), False)
154 # Test several cases:
155 # (D) subclass defines __missing__ method returning a value
156 # (E) subclass defines __missing__ method raising RuntimeError
157 # (F) subclass sets __missing__ instance variable (no effect)
158 # (G) subclass doesn't define __missing__ at a all
159 class D(UserDict.UserDict):
160 def __missing__(self, key):
161 return 42
162 d = D({1: 2, 3: 4})
163 self.assertEqual(d[1], 2)
164 self.assertEqual(d[3], 4)
165 self.assertNotIn(2, d)
166 self.assertNotIn(2, d.keys())
167 self.assertEqual(d[2], 42)
168 class E(UserDict.UserDict):
169 def __missing__(self, key):
170 raise RuntimeError(key)
171 e = E()
172 try:
173 e[42]
174 except RuntimeError, err:
175 self.assertEqual(err.args, (42,))
176 else:
177 self.fail("e[42] didn't raise RuntimeError")
178 class F(UserDict.UserDict):
179 def __init__(self):
180 # An instance variable __missing__ should have no effect
181 self.__missing__ = lambda key: None
182 UserDict.UserDict.__init__(self)
183 f = F()
184 try:
185 f[42]
186 except KeyError, err:
187 self.assertEqual(err.args, (42,))
188 else:
189 self.fail("f[42] didn't raise KeyError")
190 class G(UserDict.UserDict):
191 pass
192 g = G()
193 try:
194 g[42]
195 except KeyError, err:
196 self.assertEqual(err.args, (42,))
197 else:
198 self.fail("g[42] didn't raise KeyError")
200 ##########################
201 # Test Dict Mixin
203 class SeqDict(UserDict.DictMixin):
204 """Dictionary lookalike implemented with lists.
206 Used to test and demonstrate DictMixin
208 def __init__(self, other=None, **kwargs):
209 self.keylist = []
210 self.valuelist = []
211 if other is not None:
212 for (key, value) in other:
213 self[key] = value
214 for (key, value) in kwargs.iteritems():
215 self[key] = value
216 def __getitem__(self, key):
217 try:
218 i = self.keylist.index(key)
219 except ValueError:
220 raise KeyError
221 return self.valuelist[i]
222 def __setitem__(self, key, value):
223 try:
224 i = self.keylist.index(key)
225 self.valuelist[i] = value
226 except ValueError:
227 self.keylist.append(key)
228 self.valuelist.append(value)
229 def __delitem__(self, key):
230 try:
231 i = self.keylist.index(key)
232 except ValueError:
233 raise KeyError
234 self.keylist.pop(i)
235 self.valuelist.pop(i)
236 def keys(self):
237 return list(self.keylist)
238 def copy(self):
239 d = self.__class__()
240 for key, value in self.iteritems():
241 d[key] = value
242 return d
243 @classmethod
244 def fromkeys(cls, keys, value=None):
245 d = cls()
246 for key in keys:
247 d[key] = value
248 return d
250 class UserDictMixinTest(mapping_tests.TestMappingProtocol):
251 type2test = SeqDict
253 def test_all(self):
254 ## Setup test and verify working of the test class
256 # check init
257 s = SeqDict()
259 # exercise setitem
260 s[10] = 'ten'
261 s[20] = 'twenty'
262 s[30] = 'thirty'
264 # exercise delitem
265 del s[20]
266 # check getitem and setitem
267 self.assertEqual(s[10], 'ten')
268 # check keys() and delitem
269 self.assertEqual(s.keys(), [10, 30])
271 ## Now, test the DictMixin methods one by one
272 # has_key
273 self.assertTrue(s.has_key(10))
274 self.assertTrue(not s.has_key(20))
276 # __contains__
277 self.assertIn(10, s)
278 self.assertNotIn(20, s)
280 # __iter__
281 self.assertEqual([k for k in s], [10, 30])
283 # __len__
284 self.assertEqual(len(s), 2)
286 # iteritems
287 self.assertEqual(list(s.iteritems()), [(10,'ten'), (30, 'thirty')])
289 # iterkeys
290 self.assertEqual(list(s.iterkeys()), [10, 30])
292 # itervalues
293 self.assertEqual(list(s.itervalues()), ['ten', 'thirty'])
295 # values
296 self.assertEqual(s.values(), ['ten', 'thirty'])
298 # items
299 self.assertEqual(s.items(), [(10,'ten'), (30, 'thirty')])
301 # get
302 self.assertEqual(s.get(10), 'ten')
303 self.assertEqual(s.get(15,'fifteen'), 'fifteen')
304 self.assertEqual(s.get(15), None)
306 # setdefault
307 self.assertEqual(s.setdefault(40, 'forty'), 'forty')
308 self.assertEqual(s.setdefault(10, 'null'), 'ten')
309 del s[40]
311 # pop
312 self.assertEqual(s.pop(10), 'ten')
313 self.assertNotIn(10, s)
314 s[10] = 'ten'
315 self.assertEqual(s.pop("x", 1), 1)
316 s["x"] = 42
317 self.assertEqual(s.pop("x", 1), 42)
319 # popitem
320 k, v = s.popitem()
321 self.assertNotIn(k, s)
322 s[k] = v
324 # clear
325 s.clear()
326 self.assertEqual(len(s), 0)
328 # empty popitem
329 self.assertRaises(KeyError, s.popitem)
331 # update
332 s.update({10: 'ten', 20:'twenty'})
333 self.assertEqual(s[10], 'ten')
334 self.assertEqual(s[20], 'twenty')
336 # cmp
337 self.assertEqual(s, {10: 'ten', 20:'twenty'})
338 t = SeqDict()
339 t[20] = 'twenty'
340 t[10] = 'ten'
341 self.assertEqual(s, t)
343 def test_main():
344 test_support.run_unittest(
345 UserDictTest,
346 UserDictMixinTest
349 if __name__ == "__main__":
350 test_main()