_make_boundary(): Fix for SF bug #745478, broken boundary calculation
[python/dscho.git] / Lib / test / test_userdict.py
blob399ddda00ae2878158a652704e361a7b45d1cfee
1 # Check every path through every method of UserDict
3 import test.test_support, unittest
4 from sets import Set
6 import UserDict
8 class TestMappingProtocol(unittest.TestCase):
9 # This base class can be used to check that an object conforms to the
10 # mapping protocol
12 # Functions that can be useful to override to adapt to dictionary
13 # semantics
14 _tested_class = dict # which class is being tested
16 def _reference(self):
17 """Return a dictionary of values which are invariant by storage
18 in the object under test."""
19 return {1:2, "key1":"value1", "key2":(1,2,3)}
20 def _empty_mapping(self):
21 """Return an empty mapping object"""
22 return self._tested_class()
23 def _full_mapping(self, data):
24 """Return a mapping object with the value contained in data
25 dictionary"""
26 x = self._empty_mapping()
27 for key, value in data.items():
28 x[key] = value
29 return x
31 def __init__(self, *args, **kw):
32 unittest.TestCase.__init__(self, *args, **kw)
33 self.reference = self._reference().copy()
34 key, value = self.reference.popitem()
35 self.other = {key:value}
37 def test_read(self):
38 # Test for read only operations on mapping
39 p = self._empty_mapping()
40 p1 = dict(p) #workaround for singleton objects
41 d = self._full_mapping(self.reference)
42 if d is p:
43 p = p1
44 #Indexing
45 for key, value in self.reference.items():
46 self.assertEqual(d[key], value)
47 knownkey = self.other.keys()[0]
48 self.failUnlessRaises(KeyError, lambda:d[knownkey])
49 #len
50 self.assertEqual(len(p), 0)
51 self.assertEqual(len(d), len(self.reference))
52 #has_key
53 for k in self.reference:
54 self.assert_(d.has_key(k))
55 self.assert_(k in d)
56 for k in self.other:
57 self.failIf(d.has_key(k))
58 self.failIf(k in d)
59 #cmp
60 self.assertEqual(cmp(p,p), 0)
61 self.assertEqual(cmp(d,d), 0)
62 self.assertEqual(cmp(p,d), -1)
63 self.assertEqual(cmp(d,p), 1)
64 #__non__zero__
65 if p: self.fail("Empty mapping must compare to False")
66 if not d: self.fail("Full mapping must compare to True")
67 # keys(), items(), iterkeys() ...
68 def check_iterandlist(iter, lst, ref):
69 self.assert_(hasattr(iter, 'next'))
70 self.assert_(hasattr(iter, '__iter__'))
71 x = list(iter)
72 self.assert_(Set(x)==Set(lst)==Set(ref))
73 check_iterandlist(d.iterkeys(), d.keys(), self.reference.keys())
74 check_iterandlist(iter(d), d.keys(), self.reference.keys())
75 check_iterandlist(d.itervalues(), d.values(), self.reference.values())
76 check_iterandlist(d.iteritems(), d.items(), self.reference.items())
77 #get
78 key, value = d.iteritems().next()
79 knownkey, knownvalue = self.other.iteritems().next()
80 self.assertEqual(d.get(key, knownvalue), value)
81 self.assertEqual(d.get(knownkey, knownvalue), knownvalue)
82 self.failIf(knownkey in d)
84 def test_write(self):
85 # Test for write operations on mapping
86 p = self._empty_mapping()
87 #Indexing
88 for key, value in self.reference.items():
89 p[key] = value
90 self.assertEqual(p[key], value)
91 for key in self.reference.keys():
92 del p[key]
93 self.failUnlessRaises(KeyError, lambda:p[key])
94 p = self._empty_mapping()
95 #update
96 p.update(self.reference)
97 self.assertEqual(dict(p), self.reference)
98 d = self._full_mapping(self.reference)
99 #setdefaullt
100 key, value = d.iteritems().next()
101 knownkey, knownvalue = self.other.iteritems().next()
102 self.assertEqual(d.setdefault(key, knownvalue), value)
103 self.assertEqual(d[key], value)
104 self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue)
105 self.assertEqual(d[knownkey], knownvalue)
106 #pop
107 self.assertEqual(d.pop(knownkey), knownvalue)
108 self.failIf(knownkey in d)
109 self.assertRaises(KeyError, d.pop, knownkey)
110 default = 909
111 d[knownkey] = knownvalue
112 self.assertEqual(d.pop(knownkey, default), knownvalue)
113 self.failIf(knownkey in d)
114 self.assertEqual(d.pop(knownkey, default), default)
115 #popitem
116 key, value = d.popitem()
117 self.failIf(key in d)
118 self.assertEqual(value, self.reference[key])
119 p=self._empty_mapping()
120 self.assertRaises(KeyError, p.popitem)
122 d0 = {}
123 d1 = {"one": 1}
124 d2 = {"one": 1, "two": 2}
125 d3 = {"one": 1, "two": 3, "three": 5}
126 d4 = {"one": None, "two": None}
127 d5 = {"one": 1, "two": 1}
129 class UserDictTest(TestMappingProtocol):
130 _tested_class = UserDict.IterableUserDict
132 def test_all(self):
133 # Test constructors
134 u = UserDict.UserDict()
135 u0 = UserDict.UserDict(d0)
136 u1 = UserDict.UserDict(d1)
137 u2 = UserDict.IterableUserDict(d2)
139 uu = UserDict.UserDict(u)
140 uu0 = UserDict.UserDict(u0)
141 uu1 = UserDict.UserDict(u1)
142 uu2 = UserDict.UserDict(u2)
144 # keyword arg constructor
145 self.assertEqual(UserDict.UserDict(one=1, two=2), d2)
146 # item sequence constructor
147 self.assertEqual(UserDict.UserDict([('one',1), ('two',2)]), d2)
148 self.assertEqual(UserDict.UserDict(dict=[('one',1), ('two',2)]), d2)
149 # both together
150 self.assertEqual(UserDict.UserDict([('one',1), ('two',2)], two=3, three=5), d3)
152 # alternate constructor
153 self.assertEqual(UserDict.UserDict.fromkeys('one two'.split()), d4)
154 self.assertEqual(UserDict.UserDict().fromkeys('one two'.split()), d4)
155 self.assertEqual(UserDict.UserDict.fromkeys('one two'.split(), 1), d5)
156 self.assertEqual(UserDict.UserDict().fromkeys('one two'.split(), 1), d5)
157 self.assert_(u1.fromkeys('one two'.split()) is not u1)
158 self.assert_(isinstance(u1.fromkeys('one two'.split()), UserDict.UserDict))
159 self.assert_(isinstance(u2.fromkeys('one two'.split()), UserDict.IterableUserDict))
161 # Test __repr__
162 self.assertEqual(str(u0), str(d0))
163 self.assertEqual(repr(u1), repr(d1))
164 self.assertEqual(`u2`, `d2`)
166 # Test __cmp__ and __len__
167 all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2]
168 for a in all:
169 for b in all:
170 self.assertEqual(cmp(a, b), cmp(len(a), len(b)))
172 # Test __getitem__
173 self.assertEqual(u2["one"], 1)
174 self.assertRaises(KeyError, u1.__getitem__, "two")
176 # Test __setitem__
177 u3 = UserDict.UserDict(u2)
178 u3["two"] = 2
179 u3["three"] = 3
181 # Test __delitem__
182 del u3["three"]
183 self.assertRaises(KeyError, u3.__delitem__, "three")
185 # Test clear
186 u3.clear()
187 self.assertEqual(u3, {})
189 # Test copy()
190 u2a = u2.copy()
191 self.assertEqual(u2a, u2)
192 u2b = UserDict.UserDict(x=42, y=23)
193 u2c = u2b.copy() # making a copy of a UserDict is special cased
194 self.assertEqual(u2b, u2c)
196 class MyUserDict(UserDict.UserDict):
197 def display(self): print self
199 m2 = MyUserDict(u2)
200 m2a = m2.copy()
201 self.assertEqual(m2a, m2)
203 # SF bug #476616 -- copy() of UserDict subclass shared data
204 m2['foo'] = 'bar'
205 self.assertNotEqual(m2a, m2)
207 # Test keys, items, values
208 self.assertEqual(u2.keys(), d2.keys())
209 self.assertEqual(u2.items(), d2.items())
210 self.assertEqual(u2.values(), d2.values())
212 # Test has_key and "in".
213 for i in u2.keys():
214 self.assert_(u2.has_key(i))
215 self.assert_(i in u2)
216 self.assertEqual(u1.has_key(i), d1.has_key(i))
217 self.assertEqual(i in u1, i in d1)
218 self.assertEqual(u0.has_key(i), d0.has_key(i))
219 self.assertEqual(i in u0, i in d0)
221 # Test update
222 t = UserDict.UserDict()
223 t.update(u2)
224 self.assertEqual(t, u2)
225 class Items:
226 def items(self):
227 return (("x", 42), ("y", 23))
228 t = UserDict.UserDict()
229 t.update(Items())
230 self.assertEqual(t, {"x": 42, "y": 23})
232 # Test get
233 for i in u2.keys():
234 self.assertEqual(u2.get(i), u2[i])
235 self.assertEqual(u1.get(i), d1.get(i))
236 self.assertEqual(u0.get(i), d0.get(i))
238 # Test "in" iteration.
239 for i in xrange(20):
240 u2[i] = str(i)
241 ikeys = []
242 for k in u2:
243 ikeys.append(k)
244 keys = u2.keys()
245 self.assertEqual(Set(ikeys), Set(keys))
247 # Test setdefault
248 t = UserDict.UserDict()
249 self.assertEqual(t.setdefault("x", 42), 42)
250 self.assert_(t.has_key("x"))
251 self.assertEqual(t.setdefault("x", 23), 42)
253 # Test pop
254 t = UserDict.UserDict(x=42)
255 self.assertEqual(t.pop("x"), 42)
256 self.assertRaises(KeyError, t.pop, "x")
257 self.assertEqual(t.pop("x", 1), 1)
258 t["x"] = 42
259 self.assertEqual(t.pop("x", 1), 42)
261 # Test popitem
262 t = UserDict.UserDict(x=42)
263 self.assertEqual(t.popitem(), ("x", 42))
264 self.assertRaises(KeyError, t.popitem)
266 ##########################
267 # Test Dict Mixin
269 class SeqDict(UserDict.DictMixin):
270 """Dictionary lookalike implemented with lists.
272 Used to test and demonstrate DictMixin
274 def __init__(self):
275 self.keylist = []
276 self.valuelist = []
277 def __getitem__(self, key):
278 try:
279 i = self.keylist.index(key)
280 except ValueError:
281 raise KeyError
282 return self.valuelist[i]
283 def __setitem__(self, key, value):
284 try:
285 i = self.keylist.index(key)
286 self.valuelist[i] = value
287 except ValueError:
288 self.keylist.append(key)
289 self.valuelist.append(value)
290 def __delitem__(self, key):
291 try:
292 i = self.keylist.index(key)
293 except ValueError:
294 raise KeyError
295 self.keylist.pop(i)
296 self.valuelist.pop(i)
297 def keys(self):
298 return list(self.keylist)
300 class UserDictMixinTest(TestMappingProtocol):
301 _tested_class = SeqDict
303 def test_all(self):
304 ## Setup test and verify working of the test class
306 # check init
307 s = SeqDict()
309 # exercise setitem
310 s[10] = 'ten'
311 s[20] = 'twenty'
312 s[30] = 'thirty'
314 # exercise delitem
315 del s[20]
316 # check getitem and setitem
317 self.assertEqual(s[10], 'ten')
318 # check keys() and delitem
319 self.assertEqual(s.keys(), [10, 30])
321 ## Now, test the DictMixin methods one by one
322 # has_key
323 self.assert_(s.has_key(10))
324 self.assert_(not s.has_key(20))
326 # __contains__
327 self.assert_(10 in s)
328 self.assert_(20 not in s)
330 # __iter__
331 self.assertEqual([k for k in s], [10, 30])
333 # __len__
334 self.assertEqual(len(s), 2)
336 # iteritems
337 self.assertEqual(list(s.iteritems()), [(10,'ten'), (30, 'thirty')])
339 # iterkeys
340 self.assertEqual(list(s.iterkeys()), [10, 30])
342 # itervalues
343 self.assertEqual(list(s.itervalues()), ['ten', 'thirty'])
345 # values
346 self.assertEqual(s.values(), ['ten', 'thirty'])
348 # items
349 self.assertEqual(s.items(), [(10,'ten'), (30, 'thirty')])
351 # get
352 self.assertEqual(s.get(10), 'ten')
353 self.assertEqual(s.get(15,'fifteen'), 'fifteen')
354 self.assertEqual(s.get(15), None)
356 # setdefault
357 self.assertEqual(s.setdefault(40, 'forty'), 'forty')
358 self.assertEqual(s.setdefault(10, 'null'), 'ten')
359 del s[40]
361 # pop
362 self.assertEqual(s.pop(10), 'ten')
363 self.assert_(10 not in s)
364 s[10] = 'ten'
365 self.assertEqual(s.pop("x", 1), 1)
366 s["x"] = 42
367 self.assertEqual(s.pop("x", 1), 42)
369 # popitem
370 k, v = s.popitem()
371 self.assert_(k not in s)
372 s[k] = v
374 # clear
375 s.clear()
376 self.assertEqual(len(s), 0)
378 # empty popitem
379 self.assertRaises(KeyError, s.popitem)
381 # update
382 s.update({10: 'ten', 20:'twenty'})
383 self.assertEqual(s[10], 'ten')
384 self.assertEqual(s[20], 'twenty')
386 # cmp
387 self.assertEqual(s, {10: 'ten', 20:'twenty'})
388 t = SeqDict()
389 t[20] = 'twenty'
390 t[10] = 'ten'
391 self.assertEqual(s, t)
393 def test_main():
394 test.test_support.run_unittest(
395 TestMappingProtocol,
396 UserDictTest,
397 UserDictMixinTest
400 if __name__ == "__main__":
401 test_main()