From 3610a21a4214091ff7ed988e94ecde2a8982a23a Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Tue, 28 Sep 2010 08:18:39 +0000 Subject: [PATCH] Migrated regressiontest/datastructures doctest, and moved it into the existing utils datastructures package. Thanks to Stephan Jaekel. git-svn-id: http://code.djangoproject.com/svn/django/trunk@13936 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- .../datastructures/__init__.py | 0 .../regressiontests/datastructures/models.py | 0 tests/regressiontests/datastructures/tests.py | 173 ---------------- tests/regressiontests/utils/datastructures.py | 192 +++++++++++++++++- 4 files changed, 190 insertions(+), 175 deletions(-) delete mode 100644 tests/regressiontests/datastructures/__init__.py delete mode 100644 tests/regressiontests/datastructures/models.py delete mode 100644 tests/regressiontests/datastructures/tests.py diff --git a/tests/regressiontests/datastructures/__init__.py b/tests/regressiontests/datastructures/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/regressiontests/datastructures/models.py b/tests/regressiontests/datastructures/models.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/regressiontests/datastructures/tests.py b/tests/regressiontests/datastructures/tests.py deleted file mode 100644 index a858e2469f..0000000000 --- a/tests/regressiontests/datastructures/tests.py +++ /dev/null @@ -1,173 +0,0 @@ -""" -# Tests for stuff in django.utils.datastructures. - ->>> import pickle ->>> from django.utils.datastructures import * - -### MergeDict ################################################################# - ->>> d1 = {'chris':'cool','camri':'cute','cotton':'adorable','tulip':'snuggable', 'twoofme':'firstone'} ->>> d2 = {'chris2':'cool2','camri2':'cute2','cotton2':'adorable2','tulip2':'snuggable2'} ->>> d3 = {'chris3':'cool3','camri3':'cute3','cotton3':'adorable3','tulip3':'snuggable3'} ->>> d4 = {'twoofme':'secondone'} ->>> md = MergeDict( d1,d2,d3 ) ->>> md['chris'] -'cool' ->>> md['camri'] -'cute' ->>> md['twoofme'] -'firstone' ->>> md2 = md.copy() ->>> md2['chris'] -'cool' - -MergeDict can merge MultiValueDicts ->>> multi1 = MultiValueDict({'key1': ['value1'], 'key2': ['value2', 'value3']}) ->>> multi2 = MultiValueDict({'key2': ['value4'], 'key4': ['value5', 'value6']}) ->>> mm = MergeDict(multi1, multi2) - -# Although 'key2' appears in both dictionaries, only the first value is used. ->>> mm.getlist('key2') -['value2', 'value3'] ->>> mm.getlist('key4') -['value5', 'value6'] ->>> mm.getlist('undefined') -[] - ->>> sorted(mm.keys()) -['key1', 'key2', 'key4'] ->>> len(mm.values()) -3 ->>> "value1" in mm.values() -True ->>> sorted(mm.items(), key=lambda k: k[0]) -[('key1', 'value1'), ('key2', 'value3'), ('key4', 'value6')] ->>> [(k,mm.getlist(k)) for k in sorted(mm)] -[('key1', ['value1']), ('key2', ['value2', 'value3']), ('key4', ['value5', 'value6'])] - -### MultiValueDict ########################################################## - ->>> d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']}) ->>> d['name'] -'Simon' ->>> d.get('name') -'Simon' ->>> d.getlist('name') -['Adrian', 'Simon'] ->>> list(d.iteritems()) -[('position', 'Developer'), ('name', 'Simon')] ->>> list(d.iterlists()) -[('position', ['Developer']), ('name', ['Adrian', 'Simon'])] ->>> d['lastname'] -Traceback (most recent call last): -... -MultiValueDictKeyError: "Key 'lastname' not found in " ->>> d.get('lastname') - ->>> d.get('lastname', 'nonexistent') -'nonexistent' ->>> d.getlist('lastname') -[] ->>> d.setlist('lastname', ['Holovaty', 'Willison']) ->>> d.getlist('lastname') -['Holovaty', 'Willison'] ->>> d.values() -['Developer', 'Simon', 'Willison'] ->>> list(d.itervalues()) -['Developer', 'Simon', 'Willison'] - -### SortedDict ################################################################# - ->>> d = SortedDict() ->>> d['one'] = 'one' ->>> d['two'] = 'two' ->>> d['three'] = 'three' ->>> d['one'] -'one' ->>> d['two'] -'two' ->>> d['three'] -'three' ->>> d.keys() -['one', 'two', 'three'] ->>> d.values() -['one', 'two', 'three'] ->>> d['one'] = 'not one' ->>> d['one'] -'not one' ->>> d.keys() == d.copy().keys() -True ->>> d2 = d.copy() ->>> d2['four'] = 'four' ->>> print repr(d) -{'one': 'not one', 'two': 'two', 'three': 'three'} ->>> d.pop('one', 'missing') -'not one' ->>> d.pop('one', 'missing') -'missing' - ->>> SortedDict((i, i) for i in xrange(3)) -{0: 0, 1: 1, 2: 2} - -We don't know which item will be popped in popitem(), so we'll just check that -the number of keys has decreased. ->>> l = len(d) ->>> _ = d.popitem() ->>> l - len(d) -1 - -Init from sequence of tuples ->>> d = SortedDict(( -... (1, "one"), -... (0, "zero"), -... (2, "two"))) ->>> print repr(d) -{1: 'one', 0: 'zero', 2: 'two'} - ->>> pickle.loads(pickle.dumps(d, 2)) -{1: 'one', 0: 'zero', 2: 'two'} - ->>> d.clear() ->>> d -{} ->>> d.keyOrder -[] - -### DotExpandedDict ########################################################## - ->>> d = DotExpandedDict({'person.1.firstname': ['Simon'], 'person.1.lastname': ['Willison'], 'person.2.firstname': ['Adrian'], 'person.2.lastname': ['Holovaty']}) ->>> d['person']['1']['lastname'] -['Willison'] ->>> d['person']['2']['lastname'] -['Holovaty'] ->>> d['person']['2']['firstname'] -['Adrian'] - -### ImmutableList ############################################################ ->>> d = ImmutableList(range(10)) ->>> d.sort() -Traceback (most recent call last): - File "", line 1, in - File "/var/lib/python-support/python2.5/django/utils/datastructures.py", line 359, in complain - raise AttributeError, self.warning -AttributeError: ImmutableList object is immutable. ->>> repr(d) -'(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)' ->>> d = ImmutableList(range(10), warning="Object is immutable!") ->>> d[1] -1 ->>> d[1] = 'test' -Traceback (most recent call last): - File "", line 1, in - File "/var/lib/python-support/python2.5/django/utils/datastructures.py", line 359, in complain - raise AttributeError, self.warning -AttributeError: Object is immutable! - -### DictWrapper ############################################################# - ->>> f = lambda x: "*%s" % x ->>> d = DictWrapper({'a': 'a'}, f, 'xx_') ->>> "Normal: %(a)s. Modified: %(xx_a)s" % d -'Normal: a. Modified: *a' - -""" diff --git a/tests/regressiontests/utils/datastructures.py b/tests/regressiontests/utils/datastructures.py index e684694d7c..a41281cd37 100644 --- a/tests/regressiontests/utils/datastructures.py +++ b/tests/regressiontests/utils/datastructures.py @@ -1,8 +1,23 @@ +""" +Tests for stuff in django.utils.datastructures. +""" +import pickle import unittest -from django.utils.datastructures import SortedDict +from django.utils.datastructures import * -class DatastructuresTests(unittest.TestCase): + +class DatastructuresTestCase(unittest.TestCase): + def assertRaisesErrorWithMessage(self, error, message, callable, + *args, **kwargs): + self.assertRaises(error, callable, *args, **kwargs) + try: + callable(*args, **kwargs) + except error, e: + self.assertEqual(message, str(e)) + + +class SortedDictTests(DatastructuresTestCase): def setUp(self): self.d1 = SortedDict() self.d1[7] = 'seven' @@ -66,3 +81,176 @@ class DatastructuresTests(unittest.TestCase): # Here the order of SortedDict values *is* what we are testing self.assertEquals(d.values(), ['second-two', 'one']) + + def test_overwrite(self): + self.d1[1] = 'not one' + self.assertEqual(self.d1[1], 'not one') + self.assertEqual(self.d1.keys(), self.d1.copy().keys()) + + def test_append(self): + self.d1[13] = 'thirteen' + self.assertEquals( + repr(self.d1), + "{7: 'seven', 1: 'one', 9: 'nine', 13: 'thirteen'}" + ) + + def test_pop(self): + self.assertEquals(self.d1.pop(1, 'missing'), 'one') + self.assertEquals(self.d1.pop(1, 'missing'), 'missing') + + # We don't know which item will be popped in popitem(), so we'll + # just check that the number of keys has decreased. + l = len(self.d1) + self.d1.popitem() + self.assertEquals(l - len(self.d1), 1) + + def test_dict_equality(self): + d = SortedDict((i, i) for i in xrange(3)) + self.assertEquals(d, {0: 0, 1: 1, 2: 2}) + + def test_tuple_init(self): + d = SortedDict(((1, "one"), (0, "zero"), (2, "two"))) + self.assertEquals(repr(d), "{1: 'one', 0: 'zero', 2: 'two'}") + + def test_pickle(self): + self.assertEquals( + pickle.loads(pickle.dumps(self.d1, 2)), + {7: 'seven', 1: 'one', 9: 'nine'} + ) + + def test_clear(self): + self.d1.clear() + self.assertEquals(self.d1, {}) + self.assertEquals(self.d1.keyOrder, []) + +class MergeDictTests(DatastructuresTestCase): + + def test_simple_mergedict(self): + d1 = {'chris':'cool', 'camri':'cute', 'cotton':'adorable', + 'tulip':'snuggable', 'twoofme':'firstone'} + + d2 = {'chris2':'cool2', 'camri2':'cute2', 'cotton2':'adorable2', + 'tulip2':'snuggable2'} + + d3 = {'chris3':'cool3', 'camri3':'cute3', 'cotton3':'adorable3', + 'tulip3':'snuggable3'} + + d4 = {'twoofme': 'secondone'} + + md = MergeDict(d1, d2, d3) + + self.assertEquals(md['chris'], 'cool') + self.assertEquals(md['camri'], 'cute') + self.assertEquals(md['twoofme'], 'firstone') + + md2 = md.copy() + self.assertEquals(md2['chris'], 'cool') + + def test_mergedict_merges_multivaluedict(self): + """ MergeDict can merge MultiValueDicts """ + + multi1 = MultiValueDict({'key1': ['value1'], + 'key2': ['value2', 'value3']}) + + multi2 = MultiValueDict({'key2': ['value4'], + 'key4': ['value5', 'value6']}) + + mm = MergeDict(multi1, multi2) + + # Although 'key2' appears in both dictionaries, + # only the first value is used. + self.assertEquals(mm.getlist('key2'), ['value2', 'value3']) + self.assertEquals(mm.getlist('key4'), ['value5', 'value6']) + self.assertEquals(mm.getlist('undefined'), []) + + self.assertEquals(sorted(mm.keys()), ['key1', 'key2', 'key4']) + self.assertEquals(len(mm.values()), 3) + + self.assertTrue('value1' in mm.values()) + + self.assertEquals(sorted(mm.items(), key=lambda k: k[0]), + [('key1', 'value1'), ('key2', 'value3'), + ('key4', 'value6')]) + + self.assertEquals([(k,mm.getlist(k)) for k in sorted(mm)], + [('key1', ['value1']), + ('key2', ['value2', 'value3']), + ('key4', ['value5', 'value6'])]) + +class MultiValueDictTests(DatastructuresTestCase): + + def test_multivaluedict(self): + d = MultiValueDict({'name': ['Adrian', 'Simon'], + 'position': ['Developer']}) + + self.assertEquals(d['name'], 'Simon') + self.assertEquals(d.get('name'), 'Simon') + self.assertEquals(d.getlist('name'), ['Adrian', 'Simon']) + self.assertEquals(list(d.iteritems()), + [('position', 'Developer'), ('name', 'Simon')]) + + self.assertEquals(list(d.iterlists()), + [('position', ['Developer']), + ('name', ['Adrian', 'Simon'])]) + + # MultiValueDictKeyError: "Key 'lastname' not found in + # " + self.assertRaisesErrorWithMessage(MultiValueDictKeyError, + '"Key \'lastname\' not found in "', + d.__getitem__, 'lastname') + + self.assertEquals(d.get('lastname'), None) + self.assertEquals(d.get('lastname', 'nonexistent'), 'nonexistent') + self.assertEquals(d.getlist('lastname'), []) + + d.setlist('lastname', ['Holovaty', 'Willison']) + self.assertEquals(d.getlist('lastname'), ['Holovaty', 'Willison']) + self.assertEquals(d.values(), ['Developer', 'Simon', 'Willison']) + self.assertEquals(list(d.itervalues()), + ['Developer', 'Simon', 'Willison']) + + +class DotExpandedDictTests(DatastructuresTestCase): + + def test_dotexpandeddict(self): + + d = DotExpandedDict({'person.1.firstname': ['Simon'], + 'person.1.lastname': ['Willison'], + 'person.2.firstname': ['Adrian'], + 'person.2.lastname': ['Holovaty']}) + + self.assertEquals(d['person']['1']['lastname'], ['Willison']) + self.assertEquals(d['person']['2']['lastname'], ['Holovaty']) + self.assertEquals(d['person']['2']['firstname'], ['Adrian']) + + +class ImmutableListTests(DatastructuresTestCase): + + def test_sort(self): + d = ImmutableList(range(10)) + + # AttributeError: ImmutableList object is immutable. + self.assertRaisesErrorWithMessage(AttributeError, + 'ImmutableList object is immutable.', d.sort) + + self.assertEquals(repr(d), '(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)') + + def test_custom_warning(self): + d = ImmutableList(range(10), warning="Object is immutable!") + + self.assertEquals(d[1], 1) + + # AttributeError: Object is immutable! + self.assertRaisesErrorWithMessage(AttributeError, + 'Object is immutable!', d.__setitem__, 1, 'test') + + +class DictWrapperTests(DatastructuresTestCase): + + def test_dictwrapper(self): + f = lambda x: "*%s" % x + d = DictWrapper({'a': 'a'}, f, 'xx_') + self.assertEquals("Normal: %(a)s. Modified: %(xx_a)s" % d, + 'Normal: a. Modified: *a')