def moat_test(self): '''test examples from the pdf''' dct = {} rdd = RecursiveDefaultDict() incr_dict(dct, ('a', 'b', 'c')) rdd['a']['b']['c'] += 1 r = {'a': {'b': {'c': 1}}} self.assertEquals(dct, r) self.assertEquals(rdd, r) incr_dict(dct, ('a', 'b', 'c')) rdd['a']['b']['c'] += 1 r = {'a': {'b': {'c': 2}}} self.assertEquals(dct, r) self.assertEquals(rdd, r) incr_dict(dct, ('a', 'b', 'f')) rdd['a']['b']['f'] += 1 r = {'a': {'b': {'c': 2, 'f': 1}}} self.assertEquals(dct, r) self.assertEquals(rdd, r) incr_dict(dct, ('a', 'r', 'f')) rdd['a']['r']['f'] += 1 r = {'a': {'r': {'f': 1}, 'b': {'c': 2, 'f': 1}}} self.assertEquals(dct, r) self.assertEquals(rdd, r) incr_dict(dct, ('a', 'z')) rdd['a']['z'] += 1 r = {'a': {'r': {'f': 1}, 'b': {'c': 2,'f': 1}, 'z': 1}} self.assertEquals(dct, r) self.assertEquals(rdd, r)
def test_bad_input(self): # invalid data types entered with self.assertRaises(Exception) as cm: data = [] tup = {'a','b'} incr_dict(data, tup) data = {} tup = '5' incr_dict(data, tup) data = 'a' tup = 'a', 'b', 'c' incr_dict(data, tup) exception = cm.exception self.assertEqual( exception.message, "Invalid data types. Must be dict and tuple.") # Empty tuple passed in with self.assertRaises(Exception) as cm: data = {} tup = () incr_dict(data, tup) exception = cm.exception self.assertEqual( exception.message, "Invalid tuple, must have at least 1 value")
def test_bad_input(self): # invalid data types entered with self.assertRaises(Exception) as cm: data = [] tup = {'a', 'b'} incr_dict(data, tup) data = {} tup = '5' incr_dict(data, tup) data = 'a' tup = 'a', 'b', 'c' incr_dict(data, tup) exception = cm.exception self.assertEqual(exception.message, "Invalid data types. Must be dict and tuple.") # Empty tuple passed in with self.assertRaises(Exception) as cm: data = {} tup = () incr_dict(data, tup) exception = cm.exception self.assertEqual(exception.message, "Invalid tuple, must have at least 1 value")
def test_incr_dict(self): dct = {} incr_dict(dct, ('a', 'b', 'c')) self.assertEquals(dct, {'a': {'b': {'c': 1}}}) incr_dict(dct, ('a', 'b', 'c')) self.assertEquals(dct, {'a': {'b': {'c': 2}}}) incr_dict(dct, ('a', 'b', 'f')) self.assertEquals(dct, {'a': {'b': {'c': 2, 'f': 1}}}) incr_dict(dct, ('a', 'r', 'f')) self.assertEquals(dct, {'a': {'r': {'f': 1}, 'b': {'c': 2, 'f': 1}}}) incr_dict(dct, ('a', 'z')) self.assertEquals(dct, {'a': {'r': {'f': 1}, 'b': {'c': 2,'f': 1}, 'z': 1}})
def increment_node_with_children_test(self): '''test behavior of incrementing a node that has children''' #behavior for this case is unspecified; the implementations handle it differently d = {} rdd = RecursiveDefaultDict() # incr_dict raises a TypeError when you try to add an int to a dict incr_dict(d, ('a', 'b')) with self.assertRaises(TypeError): incr_dict(d, ('a',)) # this operation is supported because of our __add__ hack in rdd, but # all children of the node you're incrementing are lost rdd ['a']['b'] += 1 self.assertEquals(rdd, {'a': {'b': 1}}) rdd ['a'] += 1 self.assertEquals(rdd, {'a': 1})
def empty_tuple_test(self): '''test behavior with an empty tuple argument''' dct = {} incr_dict(dct, ()) self.assertEquals(dct, {}) incr_dict(dct, ('a',)) self.assertEquals(dct,{'a': 1}) incr_dict(dct, ()) self.assertEquals(dct, {'a': 1})
def large_tuple_test(self): '''test performance for a large tuple argument''' dct = {} big_tuple = [random.choice(string.ascii_letters) for i in range(1000000)] #totally a tuple t = timeit.Timer(lambda: incr_dict(dct, big_tuple), 'gc.enable()') runtime = t.timeit(number=1) assert runtime < 10 # fail if it takes >= 10s to insert 1m items # crazy hack to check performance of the rdd implementation # due to maximum recursion depth there's a limit to how deep we can go here rdd_test_tuple = [random.choice(string.ascii_letters) for i in range(1000)] test_string = 'from incr_dict import RecursiveDefaultDict;' test_string += 'rdd = RecursiveDefaultDict(); rdd' test_string += ''.join(('["{}"]'.format(key) for key in rdd_test_tuple)) + ' += 1' t = timeit.Timer(test_string, 'gc.enable()') assert t.timeit(number=100) < 10 # fail if it takes >= 10s to insert 1k items 100 times
def test_valid_input(self): data = {} # Test case where root is leaf self.assertEqual( incr_dict(data, tuple('a')), {'a': 1} ) # Test case where root is leaf and incremenation self.assertEqual( incr_dict(data, tuple('a')), {'a': 2} ) # Test basic example where old root is no longer leaf self.assertEqual( incr_dict(data, ('a', 'b', 'c')), {'a': {'b': {'c': 1}}} ) # Check to see that leaf node gets incremented self.assertEqual( incr_dict(data, ('a', 'b', 'c')), {'a': {'b': {'c': 2}}} ) # Check to see that a new leaf node gets created self.assertEqual( incr_dict(data, ('a', 'b', 'f')), {'a': {'b': {'c': 2, 'f': 1}}} ) # Check to see that a new intermediate node is created # and a leaf node for that new node is created self.assertEqual( incr_dict(data, ('a', 'r', 'f')), {'a': {'r': {'f': 1}, 'b': {'c': 2, 'f': 1}}} ) # Check for a new leaf node to be created at the same level as # the intermediate nodes self.assertEqual( incr_dict(data, ('a', 'z')), {'a': {'r': {'f': 1}, 'b': {'c': 2,'f': 1}, 'z': 1}} ) # Test case where unsetting terminal leaf value and setting it # to have a dict child self.assertEqual( incr_dict(data, ('a', 'z', 'h')), {'a': {'r': {'f': 1}, 'b': {'c': 2, 'f': 1}, 'z': {'h': 1}}} ) # starting over with a new dict self.assertEqual( incr_dict(data, ('b', 'c', 'd')), {'b': {'c': {'d': 1}}} ) # Testing for large input import random import string data.clear() tup = [random.choice(string.lowercase) for i in range(1000)] # function returns a dict on success self.assertIsInstance(incr_dict(data, tuple(tup)), dict)
def test_valid_input(self): data = {} # Test case where root is leaf self.assertEqual(incr_dict(data, tuple('a')), {'a': 1}) # Test case where root is leaf and incremenation self.assertEqual(incr_dict(data, tuple('a')), {'a': 2}) # Test basic example where old root is no longer leaf self.assertEqual(incr_dict(data, ('a', 'b', 'c')), {'a': { 'b': { 'c': 1 } }}) # Check to see that leaf node gets incremented self.assertEqual(incr_dict(data, ('a', 'b', 'c')), {'a': { 'b': { 'c': 2 } }}) # Check to see that a new leaf node gets created self.assertEqual(incr_dict(data, ('a', 'b', 'f')), {'a': { 'b': { 'c': 2, 'f': 1 } }}) # Check to see that a new intermediate node is created # and a leaf node for that new node is created self.assertEqual(incr_dict(data, ('a', 'r', 'f')), {'a': { 'r': { 'f': 1 }, 'b': { 'c': 2, 'f': 1 } }}) # Check for a new leaf node to be created at the same level as # the intermediate nodes self.assertEqual(incr_dict(data, ('a', 'z')), {'a': { 'r': { 'f': 1 }, 'b': { 'c': 2, 'f': 1 }, 'z': 1 }}) # Test case where unsetting terminal leaf value and setting it # to have a dict child self.assertEqual( incr_dict(data, ('a', 'z', 'h')), {'a': { 'r': { 'f': 1 }, 'b': { 'c': 2, 'f': 1 }, 'z': { 'h': 1 } }}) # starting over with a new dict self.assertEqual(incr_dict(data, ('b', 'c', 'd')), {'b': { 'c': { 'd': 1 } }}) # Testing for large input import random import string data.clear() tup = [random.choice(string.lowercase) for i in range(1000)] # function returns a dict on success self.assertIsInstance(incr_dict(data, tuple(tup)), dict)