# -*- coding: utf-8 -*- from benedict.utils import dict_util as u from decimal import Decimal import datetime as dt import unittest class dict_util_test_case(unittest.TestCase): def test_clean(self): i = { 'a': {}, 'b': { 'x': 1 }, 'c': [], 'd': [0, 1], 'e': 0.0, 'f': '', 'g': None, 'h': '0' } o = i.copy() u.clean(o) r = { 'b': { 'x': 1 }, 'd': [0, 1], 'e': 0.0, 'h': '0', } self.assertEqual(o, r) o = i.copy() u.clean(o, dicts=False) r = { 'a': {}, 'b': { 'x': 1 }, 'd': [0, 1], 'e': 0.0, 'h': '0' } self.assertEqual(o, r) o = i.copy() u.clean(o, lists=False) r = { 'b': { 'x': 1 }, 'c': [], 'd': [0, 1], 'e': 0.0, 'h': '0' } self.assertEqual(o, r) o = i.copy() u.clean(o, strings=False) r = { 'b': { 'x': 1 }, 'd': [0, 1], 'e': 0.0, 'f': '', 'h': '0', } self.assertEqual(o, r) def test_clone(self): i = { 'a': { 'b': { 'c': 1 } } } o = u.clone(i) self.assertEqual(type(i), type(o)) self.assertEqual(i, o) self.assertFalse(i is o) o['a']['b']['c'] = 2 self.assertEqual(i['a']['b']['c'], 1) self.assertEqual(o['a']['b']['c'], 2) def test_dump(self): d = { 'a': { 'b': { 'c': 1 } } } r = """{ "a": { "b": { "c": 1 } } }""" o = u.dump(d) self.assertEqual(o, r) def test_dump_with_datetime(self): d = { 'datetime': dt.datetime(2019, 6, 11), } r = """{ "datetime": "2019-06-11 00:00:00" }""" o = u.dump(d) self.assertEqual(o, r) def test_dump_with_decimal(self): d = { 'decimal': Decimal('1.75'), } r = """{ "decimal": "1.75" }""" o = u.dump(d) self.assertEqual(o, r) def test_filter(self): i = { 'a': 1, 'b': 2, 'c': '4', 'e': '5', 'f': 6, 'g': 7, } with self.assertRaises(ValueError): f = u.filter(i, True) o = u.filter(i, lambda key, val: isinstance(val, int)) r = { 'a': 1, 'b': 2, 'f': 6, 'g': 7, } self.assertFalse(i is o) self.assertEqual(o, r) def test_flatten(self): i = { 'a': 1, 'b': 2, 'c': { 'd': { 'e': 3, 'f': 4, 'g': { 'h': 5, } } }, } o = u.flatten(i) r = { 'a': 1, 'b': 2, 'c_d_e': 3, 'c_d_f': 4, 'c_d_g_h': 5, } self.assertEqual(o, r) def test_flatten_with_custom_separator(self): i = { 'a': 1, 'b': 2, 'c': { 'd': { 'e': 3, 'f': 4, 'g': { 'h': 5, } } }, } o = u.flatten(i, separator='/') r = { 'a': 1, 'b': 2, 'c/d/e': 3, 'c/d/f': 4, 'c/d/g/h': 5, } self.assertEqual(o, r) def test_flatten_with_key_conflict(self): i = { 'a': 1, 'b': 2, 'c': { 'd': 3, }, 'c_d': 4, 'd_e': 5, 'd': { 'e': 6, } } o = u.flatten(i) r = { 'a': 1, 'b': 2, 'c_d': 4, 'd_e': 5, } self.assertEqual(o, r) def test_invert_with_unique_values(self): i = { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, } o = u.invert(i) r = { 1: ['a'], 2: ['b'], 3: ['c'], 4: ['d'], 5: ['e'], } self.assertEqual(o, r) def test_invert_with_flat_unique_values(self): i = { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, } o = u.invert(i, flat=True) r = { 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', } self.assertEqual(o, r) def test_invert_with_multiple_values(self): i = { 'a': 1, 'b': 2, 'c': 3, 'd': 1, 'e': 2, 'f': 3, } o = u.invert(i) self.assertTrue('a' and 'd' in o[1]) self.assertTrue('b' and 'e' in o[2]) self.assertTrue('c' and 'f' in o[3]) def test_items_sorted_by_keys(self): i = { 'y': 3, 'a': 6, 'f': 9, 'z': 4, 'x': 1, } o = u.items_sorted_by_keys(i) r = [ ('a', 6,), ('f', 9,), ('x', 1,), ('y', 3,), ('z', 4,), ] self.assertEqual(o, r) def test_items_sorted_by_keys_reverse(self): i = { 'y': 3, 'a': 6, 'f': 9, 'z': 4, 'x': 1, } o = u.items_sorted_by_keys(i, reverse=True) r = [ ('z', 4,), ('y', 3,), ('x', 1,), ('f', 9,), ('a', 6,), ] self.assertEqual(o, r) def test_items_sorted_by_values(self): i = { 'a': 3, 'b': 6, 'c': 9, 'e': 4, 'd': 1, } o = u.items_sorted_by_values(i) r = [ ('d', 1,), ('a', 3,), ('e', 4,), ('b', 6,), ('c', 9,), ] self.assertEqual(o, r) def test_items_sorted_by_values_reverse(self): i = { 'a': 3, 'b': 6, 'c': 9, 'e': 4, 'd': 1, } o = u.items_sorted_by_values(i, reverse=True) r = [ ('c', 9,), ('b', 6,), ('e', 4,), ('a', 3,), ('d', 1,), ] self.assertEqual(o, r) def test_keypaths(self): i = { 'a': 1, 'b': { 'c': { 'x': 2, 'y': 3, }, 'd': { 'x': 4, 'y': 5, }, }, } o = u.keypaths(i) r = [ 'a', 'b', 'b.c', 'b.c.x', 'b.c.y', 'b.d', 'b.d.x', 'b.d.y', ] self.assertEqual(o, r) def test_keypaths_with_custom_separator(self): i = { 'a': 1, 'b': { 'c': { 'x': 2, 'y': 3, }, 'd': { 'x': 4, 'y': 5, }, }, } o = u.keypaths(i, separator='/') r = [ 'a', 'b', 'b/c', 'b/c/x', 'b/c/y', 'b/d', 'b/d/x', 'b/d/y', ] self.assertEqual(o, r) def test_keypaths_without_separator(self): i = { 'a': 1, 'b': { 'c': { 'x': 2, 'y': 3, }, 'd': { 'x': 4, 'y': 5, }, }, } with self.assertRaises(ValueError): o = u.keypaths(i, separator=None) def test_keypaths_with_non_string_keys(self): i = { True: { True: 1, }, False: { False: 1, }, None: { None: 1, }, } o = u.keypaths(i) r = [ 'False', 'False.False', 'None', 'None.None', 'True', 'True.True', ] self.assertEqual(o, r) def test_merge_with_flatten_dict(self): d = { 'a': 1, 'b': 1, } m = { 'b': 2, 'c': 3, } u.merge(d, m) r = { 'a': 1, 'b': 2, 'c': 3, } self.assertEqual(d, r) def test_merge_with_multiple_dicts(self): d = { 'a': 1, 'b': 1, } a = { 'b': 2, 'c': 3, 'd': 3, } b = { 'd': 5, 'e': 5, } c = { 'd': 4, 'f': 6, } u.merge(d, a, b, c) r = { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, } self.assertEqual(d, r) def test_merge_with_nested_dict(self): d = { 'a': 1, 'b': { 'c': { 'x': 2, 'y': 3, }, 'd': { 'x': 4, 'y': 5, }, 'e': { 'x': 6, 'y': 7, }, }, } m = { 'a': 0, 'b': { 'c': 1, 'd': { 'y': 1, 'z': 2, }, 'e': { 'f': { 'x': 2, 'y': 3, }, 'g': { 'x': 4, 'y': 5, }, }, }, } u.merge(d, m) r = { 'a': 0, 'b': { 'c': 1, 'd': { 'x': 4, 'y': 1, 'z': 2, }, 'e': { 'f': { 'x': 2, 'y': 3, }, 'g': { 'x': 4, 'y': 5, }, 'x': 6, 'y': 7, }, }, } self.assertEqual(d, r) def test_move(self): d = { 'a': { 'x': 1, 'y': 1, }, 'b': { 'x': 2, 'y': 2, }, 'c': { 'x': 3, 'y': 3, }, } u.move(d, 'a', 'd') r = { 'b': { 'x': 2, 'y': 2, }, 'c': { 'x': 3, 'y': 3, }, 'd': { 'x': 1, 'y': 1, }, } self.assertEqual(d, r) def test_move_with_same_key(self): d = { 'a': 1, 'b': 2, } u.move(d, 'a', 'a') r = { 'a': 1, 'b': 2, } self.assertEqual(d, r) def test_remove_with_single_key(self): d = { 'a': 1, 'b': 2, 'c': 3, } u.remove(d, 'c') r = { 'a': 1, 'b': 2, } self.assertEqual(d, r) def test_remove_with_multiple_keys_as_args(self): d = { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, } u.remove(d, 'c', 'd', 'e') r = { 'a': 1, 'b': 2, } self.assertEqual(d, r) def test_remove_with_multiple_keys_as_list(self): d = { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, } u.remove(d, ['c', 'd', 'e']) r = { 'a': 1, 'b': 2, } self.assertEqual(d, r) def test_standardize(self): d = { 'CamelCase': 1, 'CamelCamelCase': 1, 'Camel2Camel2Case': 1, 'getHTTPResponseCode': 1, 'get2HTTPResponseCode': 1, 'HTTPResponseCode': 1, 'HTTPResponseCodeXYZ': 1, ' LocationCoordinates ': { 'Lat. ': 0.0, 'Lng. ': 0.0, }, } u.standardize(d) r = { 'camel_case': 1, 'camel_camel_case': 1, 'camel2_camel2_case': 1, 'get_http_response_code': 1, 'get2_http_response_code': 1, 'http_response_code': 1, 'http_response_code_xyz': 1, 'location_coordinates': { 'lat': 0.0, 'lng': 0.0, }, } # print(u.dump(d)) # print(u.dump(r)) self.assertEqual(d, r) def test_subset_with_keys_as_args(self): i = { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, } o = u.subset(i, 'c', 'f', 'x') r = { 'c': 3, 'f': 6, 'x': None, } self.assertFalse(i is o) self.assertEqual(o, r) def test_subset_with_keys_as_list(self): i = { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, } o = u.subset(i, ['c', 'f', 'x']) r = { 'c': 3, 'f': 6, 'x': None, } self.assertFalse(i is o) self.assertEqual(o, r) def test_swap(self): d = { 'a': 1, 'b': 2, 'c': 3, } u.swap(d, 'a', 'b') r = { 'a': 2, 'b': 1, 'c': 3, } self.assertEqual(d, r) def test_swap_with_same_key(self): d = { 'a': 1, 'b': 2, } u.swap(d, 'a', 'a') r = { 'a': 1, 'b': 2, } self.assertEqual(d, r) def test_swap_with_invalid_key(self): d = { 'a': 1, 'b': 2, 'c': 3, } with self.assertRaises(KeyError): u.swap(d, 'a', 'd') def test_traverse(self): i = { 'a': { 'x': 2, 'y': 3, 'z': { 'ok': 5, } }, 'b': { 'x': 7, 'y': 11, 'z': { 'ok': 13, } }, 'c': { 'x': 17, 'y': 19, 'z': { 'ok': 23, } }, } o = u.clone(i) with self.assertRaises(ValueError): u.traverse(o, True) def f(parent, key, value): if not isinstance(value, dict): parent[key] = (value + 1) u.traverse(o, f) r = { 'a': { 'x': 3, 'y': 4, 'z': { 'ok': 6, } }, 'b': { 'x': 8, 'y': 12, 'z': { 'ok': 14, } }, 'c': { 'x': 18, 'y': 20, 'z': { 'ok': 24, } }, } self.assertEqual(o, r) def test_unique(self): d = { 'a': { 'x': 1, 'y': 1, }, 'b': { 'x': 2, 'y': 2, }, 'c': { 'x': 1, 'y': 1, }, 'd': { 'x': 1, }, 'e': { 'x': 1, 'y': 1, 'z': 1, }, 'f': { 'x': 2, 'y': 2, }, } u.unique(d) rv = [ { 'x': 1, 'y': 1, }, { 'x': 2, 'y': 2, }, { 'x': 1, }, { 'x': 1, 'y': 1, 'z': 1, }, ] self.assertEqual(len(d.keys()), len(rv)) self.assertTrue(all([value in rv for value in d.values()]))