# tests common to dict and UserDict
class BasicTestMappingProtocol(unittest
.TestCase
):
# This base class can be used to check that an object conforms to the
# Functions that can be useful to override to adapt to dictionary
type2test
= None # which class is being tested (overwrite in subclasses)
"""Return a dictionary of values which are invariant by storage
in the object under test."""
return {1:2, "key1":"value1", "key2":(1,2,3)}
def _empty_mapping(self
):
"""Return an empty mapping object"""
def _full_mapping(self
, data
):
"""Return a mapping object with the value contained in data
x
= self
._empty
_mapping
()
for key
, value
in data
.items():
def __init__(self
, *args
, **kw
):
unittest
.TestCase
.__init
__(self
, *args
, **kw
)
self
.reference
= self
._reference
().copy()
# A (key, value) pair not in the mapping
key
, value
= self
.reference
.popitem()
# A (key, value) pair in the mapping
key
, value
= self
.reference
.popitem()
self
.inmapping
= {key
:value
}
self
.reference
[key
] = value
# Test for read only operations on mapping
p
= self
._empty
_mapping
()
p1
= dict(p
) #workaround for singleton objects
d
= self
._full
_mapping
(self
.reference
)
for key
, value
in self
.reference
.items():
self
.assertEqual(d
[key
], value
)
knownkey
= self
.other
.keys()[0]
self
.failUnlessRaises(KeyError, lambda:d
[knownkey
])
self
.assertEqual(len(p
), 0)
self
.assertEqual(len(d
), len(self
.reference
))
self
.assert_(d
.has_key(k
))
self
.failIf(d
.has_key(k
))
self
.assertEqual(cmp(p
,p
), 0)
self
.assertEqual(cmp(d
,d
), 0)
self
.assertEqual(cmp(p
,d
), -1)
self
.assertEqual(cmp(d
,p
), 1)
if p
: self
.fail("Empty mapping must compare to False")
if not d
: self
.fail("Full mapping must compare to True")
# keys(), items(), iterkeys() ...
def check_iterandlist(iter, lst
, ref
):
self
.assert_(hasattr(iter, 'next'))
self
.assert_(hasattr(iter, '__iter__'))
self
.assert_(set(x
)==set(lst
)==set(ref
))
check_iterandlist(d
.iterkeys(), d
.keys(), self
.reference
.keys())
check_iterandlist(iter(d
), d
.keys(), self
.reference
.keys())
check_iterandlist(d
.itervalues(), d
.values(), self
.reference
.values())
check_iterandlist(d
.iteritems(), d
.items(), self
.reference
.items())
key
, value
= d
.iteritems().next()
knownkey
, knownvalue
= self
.other
.iteritems().next()
self
.assertEqual(d
.get(key
, knownvalue
), value
)
self
.assertEqual(d
.get(knownkey
, knownvalue
), knownvalue
)
self
.failIf(knownkey
in d
)
# Test for write operations on mapping
p
= self
._empty
_mapping
()
for key
, value
in self
.reference
.items():
self
.assertEqual(p
[key
], value
)
for key
in self
.reference
.keys():
self
.failUnlessRaises(KeyError, lambda:p
[key
])
p
= self
._empty
_mapping
()
self
.assertEqual(dict(p
), self
.reference
)
p
= self
._empty
_mapping
()
self
.assertEqual(dict(p
), self
.reference
)
d
= self
._full
_mapping
(self
.reference
)
key
, value
= d
.iteritems().next()
knownkey
, knownvalue
= self
.other
.iteritems().next()
self
.assertEqual(d
.setdefault(key
, knownvalue
), value
)
self
.assertEqual(d
[key
], value
)
self
.assertEqual(d
.setdefault(knownkey
, knownvalue
), knownvalue
)
self
.assertEqual(d
[knownkey
], knownvalue
)
self
.assertEqual(d
.pop(knownkey
), knownvalue
)
self
.failIf(knownkey
in d
)
self
.assertRaises(KeyError, d
.pop
, knownkey
)
self
.assertEqual(d
.pop(knownkey
, default
), knownvalue
)
self
.failIf(knownkey
in d
)
self
.assertEqual(d
.pop(knownkey
, default
), default
)
self
.assertEqual(value
, self
.reference
[key
])
self
.assertRaises(KeyError, p
.popitem
)
def test_constructor(self
):
self
.assertEqual(self
._empty
_mapping
(), self
._empty
_mapping
())
self
.assert_(not self
._empty
_mapping
())
self
.assert_(self
.reference
)
self
.assert_(bool(self
._empty
_mapping
()) is False)
self
.assert_(bool(self
.reference
) is True)
d
= self
._empty
_mapping
()
self
.assertEqual(d
.keys(), [])
self
.assert_(self
.inmapping
.keys()[0] in d
.keys())
self
.assert_(self
.other
.keys()[0] not in d
.keys())
self
.assertRaises(TypeError, d
.keys
, None)
d
= self
._empty
_mapping
()
self
.assertEqual(d
.values(), [])
self
.assertRaises(TypeError, d
.values
, None)
d
= self
._empty
_mapping
()
self
.assertEqual(d
.items(), [])
self
.assertRaises(TypeError, d
.items
, None)
d
= self
._empty
_mapping
()
self
.assertEqual(len(d
), 0)
self
.assertEqual(d
[self
.inmapping
.keys()[0]], self
.inmapping
.values()[0])
self
.assertRaises(TypeError, d
.__getitem
__)
d
= self
._empty
_mapping
()
self
.assertEqual(d
.items(), self
.other
.items())
d
= self
._empty
_mapping
()
self
.assertEqual(d
, self
._empty
_mapping
())
d
= self
._empty
_mapping
()
d
.update(self
.other
.items())
self
.assertEqual(d
.items(), self
.other
.items())
d
= self
._empty
_mapping
()
d
.update(self
.other
.iteritems())
self
.assertEqual(d
.items(), self
.other
.items())
# FIXME: Doesn't work with UserDict
# self.assertRaises((TypeError, AttributeError), d.update, None)
self
.assertRaises((TypeError, AttributeError), d
.update
, 42)
self
.d
= outerself
.reference
def __getitem__(self
, i
):
d
.update(SimpleUserDict())
i2
= self
.reference
.items()
class Exc(Exception): pass
d
= self
._empty
_mapping
()
self
.assertRaises(Exc
, d
.update
, FailingUserDict())
def __getitem__(self
, key
):
self
.assertRaises(Exc
, d
.update
, FailingUserDict())
def __getitem__(self
, key
):
self
.assertRaises(Exc
, d
.update
, FailingUserDict())
d
= self
._empty
_mapping
()
self
.assertRaises(Exc
, d
.update
, badseq())
self
.assertRaises(ValueError, d
.update
, [(1, 2, 3)])
# no test_fromkeys or test_copy as both os.environ and selves don't support it
d
= self
._empty
_mapping
()
self
.assert_(d
.get(self
.other
.keys()[0]) is None)
self
.assertEqual(d
.get(self
.other
.keys()[0], 3), 3)
self
.assert_(d
.get(self
.other
.keys()[0]) is None)
self
.assertEqual(d
.get(self
.other
.keys()[0], 3), 3)
self
.assertEqual(d
.get(self
.inmapping
.keys()[0]), self
.inmapping
.values()[0])
self
.assertEqual(d
.get(self
.inmapping
.keys()[0], 3), self
.inmapping
.values()[0])
self
.assertRaises(TypeError, d
.get
)
self
.assertRaises(TypeError, d
.get
, None, None, None)
def test_setdefault(self
):
d
= self
._empty
_mapping
()
self
.assertRaises(TypeError, d
.setdefault
)
d
= self
._empty
_mapping
()
self
.assertRaises(KeyError, d
.popitem
)
self
.assertRaises(TypeError, d
.popitem
, 42)
d
= self
._empty
_mapping
()
k
, v
= self
.inmapping
.items()[0]
self
.assertRaises(KeyError, d
.pop
, self
.other
.keys()[0])
self
.assertEqual(d
.pop(k
), v
)
self
.assertEqual(len(d
), 0)
self
.assertRaises(KeyError, d
.pop
, k
)
class TestMappingProtocol(BasicTestMappingProtocol
):
def test_constructor(self
):
BasicTestMappingProtocol
.test_constructor(self
)
self
.assert_(self
._empty
_mapping
() is not self
._empty
_mapping
())
self
.assertEqual(self
.type2test(x
=1, y
=2), {"x": 1, "y": 2})
BasicTestMappingProtocol
.test_bool(self
)
self
.assert_(not self
._empty
_mapping
())
self
.assert_(self
._full
_mapping
({"x": "y"}))
self
.assert_(bool(self
._empty
_mapping
()) is False)
self
.assert_(bool(self
._full
_mapping
({"x": "y"})) is True)
BasicTestMappingProtocol
.test_keys(self
)
d
= self
._empty
_mapping
()
self
.assertEqual(d
.keys(), [])
d
= self
._full
_mapping
({'a': 1, 'b': 2})
self
.assert_('c' not in k
)
BasicTestMappingProtocol
.test_values(self
)
d
= self
._full
_mapping
({1:2})
self
.assertEqual(d
.values(), [2])
BasicTestMappingProtocol
.test_items(self
)
d
= self
._full
_mapping
({1:2})
self
.assertEqual(d
.items(), [(1, 2)])
d
= self
._empty
_mapping
()
self
.assert_(not d
.has_key('a'))
d
= self
._full
_mapping
({'a': 1, 'b': 2})
self
.assertEqual(k
, ['a', 'b'])
self
.assertRaises(TypeError, d
.has_key
)
d
= self
._empty
_mapping
()
self
.assert_(not ('a' in d
))
self
.assert_('a' not in d
)
d
= self
._full
_mapping
({'a': 1, 'b': 2})
self
.assert_('c' not in d
)
self
.assertRaises(TypeError, d
.__contains
__)
BasicTestMappingProtocol
.test_len(self
)
d
= self
._full
_mapping
({'a': 1, 'b': 2})
self
.assertEqual(len(d
), 2)
BasicTestMappingProtocol
.test_getitem(self
)
d
= self
._full
_mapping
({'a': 1, 'b': 2})
self
.assertEqual(d
['a'], 1)
self
.assertEqual(d
['b'], 2)
self
.assertEqual(d
['c'], 3)
self
.assertEqual(d
['a'], 4)
self
.assertEqual(d
, {'a': 4, 'c': 3})
self
.assertRaises(TypeError, d
.__getitem
__)
d
= self
._full
_mapping
({1:1, 2:2, 3:3})
self
.assertRaises(TypeError, d
.clear
, None)
BasicTestMappingProtocol
.test_update(self
)
d
= self
._empty
_mapping
()
d
.update({1:1, 2:2, 3:3})
self
.assertEqual(d
, {1:1, 2:2, 3:3})
self
.assertEqual(d
, {1:1, 2:2, 3:3})
d
= self
._empty
_mapping
()
self
.assertEqual(d
, {"x":1, "y":2, "z":3})
d
= self
._empty
_mapping
()
d
.update([("x", 100), ("y", 20)])
self
.assertEqual(d
, {"x":100, "y":20})
# Both item sequence and keyword arguments
d
= self
._empty
_mapping
()
d
.update([("x", 100), ("y", 20)], x
=1, y
=2)
self
.assertEqual(d
, {"x":1, "y":2})
d
= self
._full
_mapping
({1:3, 2:4})
d
.update(self
._full
_mapping
({1:2, 3:4, 5:6}).iteritems())
self
.assertEqual(d
, {1:2, 2:4, 3:4, 5:6})
def __getitem__(self
, i
):
d
.update(SimpleUserDict())
self
.assertEqual(d
, {1:1, 2:2, 3:3})
self
.assertEqual(self
.type2test
.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
d
= self
._empty
_mapping
()
self
.assert_(not(d
.fromkeys('abc') is d
))
self
.assertEqual(d
.fromkeys('abc'), {'a':None, 'b':None, 'c':None})
self
.assertEqual(d
.fromkeys((4,5),0), {4:0, 5:0})
self
.assertEqual(d
.fromkeys([]), {})
self
.assertEqual(d
.fromkeys(g()), {1:None})
self
.assertRaises(TypeError, {}.fromkeys
, 3)
class dictlike(self
.type2test
): pass
self
.assertEqual(dictlike
.fromkeys('a'), {'a':None})
self
.assertEqual(dictlike().fromkeys('a'), {'a':None})
self
.assert_(dictlike
.fromkeys('a').__class
__ is dictlike
)
self
.assert_(dictlike().fromkeys('a').__class
__ is dictlike
)
# FIXME: the following won't work with UserDict, because it's an old style class
# self.assert_(type(dictlike.fromkeys('a')) is dictlike)
class mydict(self
.type2test
):
return UserDict
.UserDict()
ud
= mydict
.fromkeys('ab')
self
.assertEqual(ud
, {'a':None, 'b':None})
# FIXME: the following won't work with UserDict, because it's an old style class
# self.assert_(isinstance(ud, UserDict.UserDict))
self
.assertRaises(TypeError, dict.fromkeys
)
class Exc(Exception): pass
class baddict1(self
.type2test
):
self
.assertRaises(Exc
, baddict1
.fromkeys
, [1])
self
.assertRaises(Exc
, self
.type2test
.fromkeys
, BadSeq())
class baddict2(self
.type2test
):
def __setitem__(self
, key
, value
):
self
.assertRaises(Exc
, baddict2
.fromkeys
, [1])
d
= self
._full
_mapping
({1:1, 2:2, 3:3})
self
.assertEqual(d
.copy(), {1:1, 2:2, 3:3})
d
= self
._empty
_mapping
()
self
.assertEqual(d
.copy(), d
)
self
.assert_(isinstance(d
.copy(), d
.__class
__))
self
.assertRaises(TypeError, d
.copy
, None)
BasicTestMappingProtocol
.test_get(self
)
d
= self
._empty
_mapping
()
self
.assert_(d
.get('c') is None)
self
.assertEqual(d
.get('c', 3), 3)
d
= self
._full
_mapping
({'a' : 1, 'b' : 2})
self
.assert_(d
.get('c') is None)
self
.assertEqual(d
.get('c', 3), 3)
self
.assertEqual(d
.get('a'), 1)
self
.assertEqual(d
.get('a', 3), 1)
def test_setdefault(self
):
BasicTestMappingProtocol
.test_setdefault(self
)
d
= self
._empty
_mapping
()
self
.assert_(d
.setdefault('key0') is None)
self
.assert_(d
.setdefault('key0') is None)
d
.setdefault('key', []).append(3)
self
.assertEqual(d
['key'][0], 3)
d
.setdefault('key', []).append(4)
self
.assertEqual(len(d
['key']), 2)
BasicTestMappingProtocol
.test_popitem(self
)
# -1: b has same structure as a
for log2size
in range(12):
a
= self
._empty
_mapping
()
b
= self
._empty
_mapping
()
ka
, va
= ta
= a
.popitem()
self
.assertEqual(va
, int(ka
))
kb
, vb
= tb
= b
.popitem()
self
.assertEqual(vb
, int(kb
))
self
.assert_(not(copymode
< 0 and ta
!= tb
))
BasicTestMappingProtocol
.test_pop(self
)
# Tests for pop with specified key
d
= self
._empty
_mapping
()
# verify longs/ints get same value when key > 32 bits (for 64-bit archs)
h
= self
._full
_mapping
({x
: 'anything', y
: 'something else'})
self
.assertEqual(h
[x
], h
[y
])
self
.assertEqual(d
.pop(k
, v
), v
)
self
.assertEqual(d
.pop(k
, 1), v
)
class TestHashMappingProtocol(TestMappingProtocol
):
TestMappingProtocol
.test_getitem(self
)
class Exc(Exception): pass
d
= self
._empty
_mapping
()
self
.assertRaises(KeyError, d
.__getitem
__, 23)
d
= self
._empty
_mapping
()
self
.assertRaises(Exc
, d
.__getitem
__, x
)
TestMappingProtocol
.test_fromkeys(self
)
class mydict(self
.type2test
):
return UserDict
.UserDict()
ud
= mydict
.fromkeys('ab')
self
.assertEqual(ud
, {'a':None, 'b':None})
self
.assert_(isinstance(ud
, UserDict
.UserDict
))
TestMappingProtocol
.test_pop(self
)
class Exc(Exception): pass
d
= self
._empty
_mapping
()
self
.assertRaises(Exc
, d
.pop
, x
)
def test_mutatingiteration(self
):
d
= self
._empty
_mapping
()
self
.fail("changing dict size during iteration doesn't raise Error")
d
= self
._empty
_mapping
()
self
.assertEqual(repr(d
), '{}')
self
.assertEqual(repr(d
), '{1: 2}')
d
= self
._empty
_mapping
()
self
.assertEqual(repr(d
), '{1: {...}}')
class Exc(Exception): pass
d
= self
._full
_mapping
({1: BadRepr()})
self
.assertRaises(Exc
, repr, d
)
self
.assert_(not (self
._empty
_mapping
() < self
._empty
_mapping
()))
self
.assert_(not (self
._full
_mapping
({1: 2}) < self
._full
_mapping
({1L: 2L})))
class Exc(Exception): pass
d1
= self
._full
_mapping
({BadCmp(): 1})
d2
= self
._full
_mapping
({1: 1})
self
.fail("< didn't raise Exc")
def test_setdefault(self
):
TestMappingProtocol
.test_setdefault(self
)
class Exc(Exception): pass
d
= self
._empty
_mapping
()
self
.assertRaises(Exc
, d
.setdefault
, x
, [])