From 40200c5372d0e004b1f5c76dd43e785b210e87cd Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 3 Jan 2025 02:16:40 -0500 Subject: [PATCH] Add initial unit tests --- pgmon.py | 21 +++++++--- test_pgmon.py | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 test_pgmon.py diff --git a/pgmon.py b/pgmon.py index 407c24a..76f4627 100755 --- a/pgmon.py +++ b/pgmon.py @@ -104,13 +104,22 @@ def update_deep(d1, d2): Returns: The new d1 """ - for k, v in d2.items(): - if isinstance(v, dict): - d1[k] = update_deep(d1.get(k, {}), v) - elif isinstance(v, list): - d1[k] = d1.get(k, []) + v + if not isinstance(d1, dict) or not isinstance(d2, dict): + raise TypeError('Both arguments to update_deep need to be dictionaries') + + for k, v2 in d2.items(): + if isinstance(v2, dict): + v1 = d1.get(k, {}) + if not isinstance(v1, dict): + raise TypeError('Type mismatch between dictionaries: {} is not a dict'.format(type(v1).__name__)) + d1[k] = update_deep(v1, v2) + elif isinstance(v2, list): + v1 = d1.get(k, []) + if not isinstance(v1, list): + raise TypeError('Type mismatch between dictionaries: {} is not a list'.format(type(v1).__name__)) + d1[k] = v1 + v2 else: - d1[k] = v + d1[k] = v2 return d1 def read_config(path, included = False): diff --git a/test_pgmon.py b/test_pgmon.py new file mode 100644 index 0000000..2579dc1 --- /dev/null +++ b/test_pgmon.py @@ -0,0 +1,112 @@ +import unittest + +import pgmon + +class TestPgmonMethods(unittest.TestCase): + ## + # update_deep + ## + def test_update_deep__empty_cases(self): + # Test empty dict cases + d1 = {} + d2 = {} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {}) + self.assertEqual(d2, {}) + + d1 = {'a': 1} + d2 = {} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, { 'a': 1 }) + self.assertEqual(d2, {}) + + d1 = {} + d2 = {'a': 1} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, { 'a': 1 }) + self.assertEqual(d2, d1) + + def test_update_deep__scalars(self): + # Test adding/updating scalar values + d1 = {'foo': 1, 'bar': "text", 'hello': "world"} + d2 = {'foo': 2, 'baz': "blah"} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'foo': 2, 'bar': "text", 'baz': "blah", 'hello': "world"}) + self.assertEqual(d2, {'foo': 2, 'baz': "blah"}) + + def test_update_deep__lists(self): + # Test adding to lists + d1 = {'lst1': []} + d2 = {'lst1': [1, 2]} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'lst1': [1, 2]}) + self.assertEqual(d2, d1) + + d1 = {'lst1': [1, 2]} + d2 = {'lst1': []} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'lst1': [1, 2]}) + self.assertEqual(d2, {'lst1': []}) + + d1 = {'lst1': [1, 2, 3]} + d2 = {'lst1': [3, 4]} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'lst1': [1, 2, 3, 3, 4]}) + self.assertEqual(d2, {'lst1': [3, 4]}) + + # Lists of objects + d1 = {'lst1': [{'id': 1}, {'id': 2}, {'id': 3}]} + d2 = {'lst1': [{'id': 3}, {'id': 4}]} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'lst1': [{'id': 1}, {'id': 2}, {'id': 3}, {'id': 3}, {'id': 4}]}) + self.assertEqual(d2, {'lst1': [{'id': 3}, {'id': 4}]}) + + # Nested lists + d1 = {'obj1': {'l1': [1, 2]}} + d2 = {'obj1': {'l1': [3, 4]}} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'obj1': {'l1': [1, 2, 3, 4]}}) + self.assertEqual(d2, {'obj1': {'l1': [3, 4]}}) + + def test_update_deep__dicts(self): + # Test adding to lists + d1 = {'obj1': {}} + d2 = {'obj1': {'a': 1, 'b': 2}} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'obj1': {'a': 1, 'b': 2}}) + self.assertEqual(d2, d1) + + d1 = {'obj1': {'a': 1, 'b': 2}} + d2 = {'obj1': {}} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'obj1': {'a': 1, 'b': 2}}) + self.assertEqual(d2, {'obj1': {}}) + + d1 = {'obj1': {'a': 1, 'b': 2}} + d2 = {'obj1': {'a': 5, 'c': 12}} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'obj1': {'a': 5, 'b': 2, 'c': 12}}) + self.assertEqual(d2, {'obj1': {'a': 5, 'c': 12}}) + + # Nested dicts + d1 = {'obj1': {'d1': {'a': 1, 'b': 2}}} + d2 = {'obj1': {'d1': {'a': 5, 'c': 12}}} + pgmon.update_deep(d1, d2) + self.assertEqual(d1, {'obj1': {'d1': {'a': 5, 'b': 2, 'c': 12}}}) + self.assertEqual(d2, {'obj1': {'d1': {'a': 5, 'c': 12}}}) + + def test_update_deep__types(self): + # Test mismatched types + d1 = {'foo': 5} + d2 = None + self.assertRaises(TypeError, pgmon.update_deep, d1, d2) + + d1 = None + d2 = {'foo': 5} + self.assertRaises(TypeError, pgmon.update_deep, d1, d2) + + # Nested mismatched types + d1 = {'foo': [1, 2]} + d2 = {'foo': {'a': 7}} + self.assertRaises(TypeError, pgmon.update_deep, d1, d2) +