diff options
author | Raymond Hettinger <python@rcn.com> | 2011-02-23 08:28:06 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2011-02-23 08:28:06 (GMT) |
commit | dcb29c93d23112eef7f37b284a04db5f4b223787 (patch) | |
tree | 792d2db9729477fdcf7fd1dd1b8df20daef8f018 /Lib/test/test_collections.py | |
parent | 48e5cd3df387209d29a8caae0c7a45e1cbbdbc62 (diff) | |
download | cpython-dcb29c93d23112eef7f37b284a04db5f4b223787.zip cpython-dcb29c93d23112eef7f37b284a04db5f4b223787.tar.gz cpython-dcb29c93d23112eef7f37b284a04db5f4b223787.tar.bz2 |
Add tests for the collections helper class and sync-up with py3k branch.
Diffstat (limited to 'Lib/test/test_collections.py')
-rw-r--r-- | Lib/test/test_collections.py | 114 |
1 files changed, 112 insertions, 2 deletions
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index d785fcb..b3e0907 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -10,6 +10,7 @@ from random import randrange, shuffle import keyword import re import sys +from collections import _ChainMap as ChainMap from collections import Hashable, Iterable, Iterator from collections import Sized, Container, Callable from collections import Set, MutableSet @@ -17,6 +18,97 @@ from collections import Mapping, MutableMapping, KeysView, ItemsView, UserDict from collections import Sequence, MutableSequence from collections import ByteString + +################################################################################ +### _ChainMap (helper class for configparser) +################################################################################ + +class TestChainMap(unittest.TestCase): + + def test_basics(self): + c = ChainMap() + c['a'] = 1 + c['b'] = 2 + d = c.new_child() + d['b'] = 20 + d['c'] = 30 + self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state + self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem + self.assertEqual(len(d), 3) # check len + for key in 'abc': # check contains + self.assertIn(key, d) + for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get + self.assertEqual(d.get(k, 100), v) + + del d['b'] # unmask a value + self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state + self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem + self.assertEqual(len(d), 3) # check len + for key in 'abc': # check contains + self.assertIn(key, d) + for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get + self.assertEqual(d.get(k, 100), v) + self.assertIn(repr(d), [ # check repr + type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})", + type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})" + ]) + + for e in d.copy(), copy.copy(d): # check shallow copies + self.assertEqual(d, e) + self.assertEqual(d.maps, e.maps) + self.assertIsNot(d, e) + self.assertIsNot(d.maps[0], e.maps[0]) + for m1, m2 in zip(d.maps[1:], e.maps[1:]): + self.assertIs(m1, m2) + + for e in [pickle.loads(pickle.dumps(d)), + copy.deepcopy(d), + eval(repr(d)) + ]: # check deep copies + self.assertEqual(d, e) + self.assertEqual(d.maps, e.maps) + self.assertIsNot(d, e) + for m1, m2 in zip(d.maps, e.maps): + self.assertIsNot(m1, m2, e) + + d.new_child() + d['b'] = 5 + self.assertEqual(d.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}]) + self.assertEqual(d.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents + self.assertEqual(d['b'], 5) # find first in chain + self.assertEqual(d.parents['b'], 2) # look beyond maps[0] + + def test_contructor(self): + self.assertEqual(ChainedContext().maps, [{}]) # no-args --> one new dict + self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list + + def test_missing(self): + class DefaultChainMap(ChainMap): + def __missing__(self, key): + return 999 + d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30)) + for k, v in dict(a=1, b=2, c=30, d=999).items(): + self.assertEqual(d[k], v) # check __getitem__ w/missing + for k, v in dict(a=1, b=2, c=30, d=77).items(): + self.assertEqual(d.get(k, 77), v) # check get() w/ missing + for k, v in dict(a=True, b=True, c=True, d=False).items(): + self.assertEqual(k in d, v) # check __contains__ w/missing + self.assertEqual(d.pop('a', 1001), 1, d) + self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing + self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing + with self.assertRaises(KeyError): + d.popitem() + + def test_dict_coercion(self): + d = ChainMap(dict(a=1, b=2), dict(b=20, c=30)) + self.assertEqual(dict(d), dict(a=1, b=2, c=30)) + self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30)) + + +################################################################################ +### Named Tuples +################################################################################ + TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests class TestNamedTuple(unittest.TestCase): @@ -228,6 +320,10 @@ class TestNamedTuple(unittest.TestCase): self.assertEqual(repr(B(1)), 'B(x=1)') +################################################################################ +### Abstract Base Classes +################################################################################ + class ABCTestCase(unittest.TestCase): def validate_abstract_methods(self, abc, *names): @@ -507,7 +603,7 @@ class TestCollectionABCs(ABCTestCase): def test_issue_4920(self): # MutableSet.pop() method did not work - class MySet(collections.MutableSet): + class MySet(MutableSet): __slots__=['__s'] def __init__(self,items=None): if items is None: @@ -553,7 +649,7 @@ class TestCollectionABCs(ABCTestCase): self.assertTrue(issubclass(sample, Mapping)) self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', '__getitem__') - class MyMapping(collections.Mapping): + class MyMapping(Mapping): def __len__(self): return 0 def __getitem__(self, i): @@ -625,6 +721,11 @@ class TestCollectionABCs(ABCTestCase): self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') + +################################################################################ +### Counter +################################################################################ + class TestCounter(unittest.TestCase): def test_basics(self): @@ -788,6 +889,11 @@ class TestCounter(unittest.TestCase): self.assertEqual(m, OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])) + +################################################################################ +### OrderedDict +################################################################################ + class TestOrderedDict(unittest.TestCase): def test_init(self): @@ -1066,6 +1172,10 @@ class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol): self.assertRaises(KeyError, d.popitem) +################################################################################ +### Run tests +################################################################################ + import doctest, collections def test_main(verbose=None): |