Home | History | Annotate | Download | only in test
      1 # Check every path through every method of UserDict
      2 
      3 from test import test_support, mapping_tests
      4 import UserDict
      5 
      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}
     12 
     13 class UserDictTest(mapping_tests.TestHashMappingProtocol):
     14     type2test = UserDict.IterableUserDict
     15 
     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)
     22 
     23         uu = UserDict.UserDict(u)
     24         uu0 = UserDict.UserDict(u0)
     25         uu1 = UserDict.UserDict(u1)
     26         uu2 = UserDict.UserDict(u2)
     27 
     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)
     35 
     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)
     44 
     45         # Test __repr__
     46         self.assertEqual(str(u0), str(d0))
     47         self.assertEqual(repr(u1), repr(d1))
     48         self.assertEqual(repr(u2), repr(d2))
     49 
     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)))
     55 
     56         # Test __getitem__
     57         self.assertEqual(u2["one"], 1)
     58         self.assertRaises(KeyError, u1.__getitem__, "two")
     59 
     60         # Test __setitem__
     61         u3 = UserDict.UserDict(u2)
     62         u3["two"] = 2
     63         u3["three"] = 3
     64 
     65         # Test __delitem__
     66         del u3["three"]
     67         self.assertRaises(KeyError, u3.__delitem__, "three")
     68 
     69         # Test clear
     70         u3.clear()
     71         self.assertEqual(u3, {})
     72 
     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)
     79 
     80         class MyUserDict(UserDict.UserDict):
     81             def display(self): print self
     82 
     83         m2 = MyUserDict(u2)
     84         m2a = m2.copy()
     85         self.assertEqual(m2a, m2)
     86 
     87         # SF bug #476616 -- copy() of UserDict subclass shared data
     88         m2['foo'] = 'bar'
     89         self.assertNotEqual(m2a, m2)
     90 
     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())
     95 
     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))
    105 
    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})
    116 
    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))
    122 
    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))
    131 
    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)
    137 
    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)
    145 
    146         # Test popitem
    147         t = UserDict.UserDict(x=42)
    148         self.assertEqual(t.popitem(), ("x", 42))
    149         self.assertRaises(KeyError, t.popitem)
    150 
    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")
    199 
    200 ##########################
    201 # Test Dict Mixin
    202 
    203 class SeqDict(UserDict.DictMixin):
    204     """Dictionary lookalike implemented with lists.
    205 
    206     Used to test and demonstrate DictMixin
    207     """
    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
    249 
    250 class UserDictMixinTest(mapping_tests.TestMappingProtocol):
    251     type2test = SeqDict
    252 
    253     def test_all(self):
    254         ## Setup test and verify working of the test class
    255 
    256         # check init
    257         s = SeqDict()
    258 
    259         # exercise setitem
    260         s[10] = 'ten'
    261         s[20] = 'twenty'
    262         s[30] = 'thirty'
    263 
    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])
    270 
    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))
    275 
    276         # __contains__
    277         self.assertIn(10, s)
    278         self.assertNotIn(20, s)
    279 
    280         # __iter__
    281         self.assertEqual([k for k in s], [10, 30])
    282 
    283         # __len__
    284         self.assertEqual(len(s), 2)
    285 
    286         # iteritems
    287         self.assertEqual(list(s.iteritems()), [(10,'ten'), (30, 'thirty')])
    288 
    289         # iterkeys
    290         self.assertEqual(list(s.iterkeys()), [10, 30])
    291 
    292         # itervalues
    293         self.assertEqual(list(s.itervalues()), ['ten', 'thirty'])
    294 
    295         # values
    296         self.assertEqual(s.values(), ['ten', 'thirty'])
    297 
    298         # items
    299         self.assertEqual(s.items(), [(10,'ten'), (30, 'thirty')])
    300 
    301         # get
    302         self.assertEqual(s.get(10), 'ten')
    303         self.assertEqual(s.get(15,'fifteen'), 'fifteen')
    304         self.assertEqual(s.get(15), None)
    305 
    306         # setdefault
    307         self.assertEqual(s.setdefault(40, 'forty'), 'forty')
    308         self.assertEqual(s.setdefault(10, 'null'), 'ten')
    309         del s[40]
    310 
    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)
    318 
    319         # popitem
    320         k, v = s.popitem()
    321         self.assertNotIn(k, s)
    322         s[k] = v
    323 
    324         # clear
    325         s.clear()
    326         self.assertEqual(len(s), 0)
    327 
    328         # empty popitem
    329         self.assertRaises(KeyError, s.popitem)
    330 
    331         # update
    332         s.update({10: 'ten', 20:'twenty'})
    333         self.assertEqual(s[10], 'ten')
    334         self.assertEqual(s[20], 'twenty')
    335 
    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)
    342 
    343 def test_main():
    344     test_support.run_unittest(
    345         UserDictTest,
    346         UserDictMixinTest
    347     )
    348 
    349 if __name__ == "__main__":
    350     test_main()
    351