doc/.venv/Lib/site-packages/mergedeep/test_mergedeep.py

398 lines
13 KiB
Python
Raw Normal View History

"""mergedeep test module"""
import inspect
import unittest
from collections import Counter
from copy import deepcopy
from mergedeep import merge, Strategy
class test_mergedeep(unittest.TestCase):
"""mergedeep function tests."""
##############################################################################################################################
# REPLACE
##############################################################################################################################
def test_should_merge_3_dicts_into_new_dict_using_replace_strategy_and_only_mutate_target(self,):
expected = {
"a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
"d": 3,
"e": {1: 2, "a": {"f": 2}},
"f": [4, 5, 6],
"g": (100, 200),
"h": Counter({"a": 5, "b": 1, "c": 1}),
"i": 2,
"j": Counter({"z": 2}),
"z": Counter({"a": 2}),
}
a = {
"a": {"b": {"c": 5}},
"d": 1,
"e": {2: 3},
"f": [1, 2, 3],
"g": (2, 4, 6),
"h": Counter({"a": 1, "b": 1}),
"j": 1,
}
a_copy = deepcopy(a)
b = {
"a": {"B": {"C": 10}},
"d": 2,
"e": 2,
"f": [4, 5, 6],
"g": (100, 200),
"h": Counter({"a": 5, "c": 1}),
"i": Counter({"a": 1}),
"z": Counter({"a": 2}),
}
b_copy = deepcopy(b)
c = {
"a": {"b": {"_c": 15}},
"d": 3,
"e": {1: 2, "a": {"f": 2}},
"i": 2,
"j": Counter({"z": 2}),
"z": Counter({"a": 2}),
}
c_copy = deepcopy(c)
actual = merge({}, a, b, c, strategy=Strategy.REPLACE)
self.assertEqual(actual, expected)
self.assertEqual(a, a_copy)
self.assertEqual(b, b_copy)
self.assertEqual(c, c_copy)
def test_should_merge_2_dicts_into_existing_dict_using_replace_strategy_and_only_mutate_target(self,):
expected = {
"a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
"d": 3,
"e": {1: 2, "a": {"f": 2}},
"f": [4, 5, 6],
"g": (100, 200),
"h": Counter({"a": 1, "b": 1, "c": 1}),
"i": 2,
"j": Counter({"z": 2}),
}
a = {
"a": {"b": {"c": 5}},
"d": 1,
"e": {2: 3},
"f": [1, 2, 3],
"g": (2, 4, 6),
"h": Counter({"a": 1, "b": 1}),
"j": 1,
}
a_copy = deepcopy(a)
b = {
"a": {"B": {"C": 10}},
"d": 2,
"e": 2,
"f": [4, 5, 6],
"g": (100, 200),
"h": Counter({"a": 1, "c": 1}),
"i": Counter({"a": 1}),
}
b_copy = deepcopy(b)
c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}, "i": 2, "j": Counter({"z": 2})}
c_copy = deepcopy(c)
actual = merge(a, b, c, strategy=Strategy.REPLACE)
self.assertEqual(actual, expected)
self.assertEqual(actual, a)
self.assertNotEqual(a, a_copy)
self.assertEqual(b, b_copy)
self.assertEqual(c, c_copy)
def test_should_have_default_strategy_of_replace(self):
func_spec = inspect.getfullargspec(merge)
default_strategy = Strategy.REPLACE
self.assertEqual(func_spec.kwonlydefaults.get("strategy"), default_strategy)
# mock_merge.method.assert_called_with(target, source, strategy=Strategy.REPLACE)
##############################################################################################################################
# ADDITIVE
##############################################################################################################################
def test_should_merge_3_dicts_into_new_dict_using_additive_strategy_on_lists_and_only_mutate_target(self,):
expected = {
"a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
"d": 3,
"e": {1: 2, "a": {"f": 2}},
"f": [1, 2, 3, 4, 5, 6],
}
a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": [1, 2, 3]}
a_copy = deepcopy(a)
b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": [4, 5, 6]}
b_copy = deepcopy(b)
c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
c_copy = deepcopy(c)
actual = merge({}, a, b, c, strategy=Strategy.ADDITIVE)
self.assertEqual(actual, expected)
self.assertEqual(a, a_copy)
self.assertEqual(b, b_copy)
self.assertEqual(c, c_copy)
def test_should_merge_3_dicts_into_new_dict_using_additive_strategy_on_sets_and_only_mutate_target(self,):
expected = {
"a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
"d": 3,
"e": {1: 2, "a": {"f": 2}},
"f": {1, 2, 3, 4, 5, 6},
}
a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": {1, 2, 3}}
a_copy = deepcopy(a)
b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": {4, 5, 6}}
b_copy = deepcopy(b)
c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
c_copy = deepcopy(c)
actual = merge({}, a, b, c, strategy=Strategy.ADDITIVE)
self.assertEqual(actual, expected)
self.assertEqual(a, a_copy)
self.assertEqual(b, b_copy)
self.assertEqual(c, c_copy)
def test_should_merge_3_dicts_into_new_dict_using_additive_strategy_on_tuples_and_only_mutate_target(self,):
expected = {
"a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
"d": 3,
"e": {1: 2, "a": {"f": 2}},
"f": (1, 2, 3, 4, 5, 6),
}
a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": (1, 2, 3)}
a_copy = deepcopy(a)
b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": (4, 5, 6)}
b_copy = deepcopy(b)
c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
c_copy = deepcopy(c)
actual = merge({}, a, b, c, strategy=Strategy.ADDITIVE)
self.assertEqual(actual, expected)
self.assertEqual(a, a_copy)
self.assertEqual(b, b_copy)
self.assertEqual(c, c_copy)
def test_should_merge_3_dicts_into_new_dict_using_additive_strategy_on_counters_and_only_mutate_target(self,):
expected = {
"a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
"d": 3,
"e": {1: 2, "a": {"f": 2}},
"f": Counter({"a": 2, "c": 1, "b": 1}),
"i": 2,
"j": Counter({"z": 2}),
"z": Counter({"a": 4}),
}
a = {
"a": {"b": {"c": 5}},
"d": 1,
"e": {2: 3},
"f": Counter({"a": 1, "c": 1}),
"i": Counter({"f": 9}),
"j": Counter({"a": 1, "z": 4}),
}
a_copy = deepcopy(a)
b = {
"a": {"B": {"C": 10}},
"d": 2,
"e": 2,
"f": Counter({"a": 1, "b": 1}),
"j": [1, 2, 3],
"z": Counter({"a": 2}),
}
b_copy = deepcopy(b)
c = {
"a": {"b": {"_c": 15}},
"d": 3,
"e": {1: 2, "a": {"f": 2}},
"i": 2,
"j": Counter({"z": 2}),
"z": Counter({"a": 2}),
}
c_copy = deepcopy(c)
actual = merge({}, a, b, c, strategy=Strategy.ADDITIVE)
self.assertEqual(actual, expected)
self.assertEqual(a, a_copy)
self.assertEqual(b, b_copy)
self.assertEqual(c, c_copy)
def test_should_not_copy_references(self):
before = 1
after = 99
o1 = {"key1": before}
o2 = {"key2": before}
expected = {"list": deepcopy([o1, o2]), "tuple": deepcopy((o1, o2))}
a = {"list": [o1], "tuple": (o1,)}
b = {"list": [o2], "tuple": (o2,)}
actual = merge({}, a, b, strategy=Strategy.ADDITIVE)
o1["key1"] = after
o2["key2"] = after
self.assertEqual(actual, expected)
# Copied dicts should `not` mutate
self.assertEqual(actual["list"][0]["key1"], before)
self.assertEqual(actual["list"][1]["key2"], before)
self.assertEqual(actual["tuple"][0]["key1"], before)
self.assertEqual(actual["tuple"][1]["key2"], before)
# Non-copied dicts should mutate
self.assertEqual(a["list"][0]["key1"], after)
self.assertEqual(b["list"][0]["key2"], after)
self.assertEqual(a["tuple"][0]["key1"], after)
self.assertEqual(b["tuple"][0]["key2"], after)
##############################################################################################################################
# TYPESAFE
# TYPESAFE_REPLACE
##############################################################################################################################
def test_should_raise_TypeError_using_typesafe_strategy_if_types_differ(self):
a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": [1, 2, 3]}
b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": [4, 5, 6]}
c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
with self.assertRaises(TypeError):
merge({}, a, b, c, strategy=Strategy.TYPESAFE)
def test_should_raise_TypeError_using_typesafe_replace_strategy_if_types_differ(self,):
a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": [1, 2, 3]}
b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": [4, 5, 6]}
c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
with self.assertRaises(TypeError):
merge({}, a, b, c, strategy=Strategy.TYPESAFE_REPLACE)
def test_should_merge_3_dicts_into_new_dict_using_typesafe_strategy_and_only_mutate_target_if_types_are_compatible(
self,
):
expected = {
"a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
"d": 3,
"f": [4, 5, 6],
"g": {2, 3, 4},
"h": (1, 3),
"z": Counter({"a": 1, "b": 1, "c": 1}),
}
a = {"a": {"b": {"c": 5}}, "d": 1, "f": [1, 2, 3], "g": {1, 2, 3}, "z": Counter({"a": 1, "b": 1})}
a_copy = deepcopy(a)
b = {"a": {"B": {"C": 10}}, "d": 2, "f": [4, 5, 6], "g": {2, 3, 4}, "h": (1,)}
b_copy = deepcopy(b)
c = {"a": {"b": {"_c": 15}}, "d": 3, "h": (1, 3), "z": Counter({"a": 1, "c": 1})}
c_copy = deepcopy(c)
actual = merge({}, a, b, c, strategy=Strategy.TYPESAFE)
self.assertEqual(actual, expected)
self.assertEqual(a, a_copy)
self.assertEqual(b, b_copy)
self.assertEqual(c, c_copy)
def test_should_merge_3_dicts_into_new_dict_using_typesafe_replace_strategy_and_only_mutate_target_if_types_are_compatible(
self,
):
expected = {
"a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
"d": 3,
"f": [4, 5, 6],
"g": {2, 3, 4},
"h": (1, 3),
"z": Counter({"a": 1, "b": 1, "c": 1}),
}
a = {"a": {"b": {"c": 5}}, "d": 1, "f": [1, 2, 3], "g": {1, 2, 3}, "z": Counter({"a": 1, "b": 1})}
a_copy = deepcopy(a)
b = {"a": {"B": {"C": 10}}, "d": 2, "f": [4, 5, 6], "g": {2, 3, 4}, "h": (1,)}
b_copy = deepcopy(b)
c = {"a": {"b": {"_c": 15}}, "d": 3, "h": (1, 3), "z": Counter({"a": 1, "c": 1})}
c_copy = deepcopy(c)
actual = merge({}, a, b, c, strategy=Strategy.TYPESAFE_REPLACE)
self.assertEqual(actual, expected)
self.assertEqual(a, a_copy)
self.assertEqual(b, b_copy)
self.assertEqual(c, c_copy)
##############################################################################################################################
# TYPESAFE_ADDITIVE
##############################################################################################################################
def test_should_raise_TypeError_using_typesafe_additive_strategy_if_types_differ(self,):
a = {"a": {"b": {"c": 5}}, "d": 1, "e": {2: 3}, "f": [1, 2, 3]}
b = {"a": {"B": {"C": 10}}, "d": 2, "e": 2, "f": [4, 5, 6]}
c = {"a": {"b": {"_c": 15}}, "d": 3, "e": {1: 2, "a": {"f": 2}}}
with self.assertRaises(TypeError):
merge({}, a, b, c, strategy=Strategy.TYPESAFE_ADDITIVE)
def test_should_merge_3_dicts_into_new_dict_using_typesafe_additive_strategy_and_only_mutate_target_if_types_are_compatible(
self,
):
expected = {
"a": {"b": {"c": 5, "_c": 15}, "B": {"C": 10}},
"d": 3,
"f": [1, 2, 3, 4, 5, 6],
"g": {1, 2, 3, 4},
"h": (1, 1, 3),
"z": Counter({"a": 2, "b": 1, "c": 1}),
}
a = {"a": {"b": {"c": 5}}, "d": 1, "f": [1, 2, 3], "g": {1, 2, 3}, "z": Counter({"a": 1, "b": 1})}
a_copy = deepcopy(a)
b = {"a": {"B": {"C": 10}}, "d": 2, "f": [4, 5, 6], "g": {2, 3, 4}, "h": (1,)}
b_copy = deepcopy(b)
c = {"a": {"b": {"_c": 15}}, "d": 3, "h": (1, 3), "z": Counter({"a": 1, "c": 1})}
c_copy = deepcopy(c)
actual = merge({}, a, b, c, strategy=Strategy.TYPESAFE_ADDITIVE)
self.assertEqual(actual, expected)
self.assertEqual(a, a_copy)
self.assertEqual(b, b_copy)
self.assertEqual(c, c_copy)
if __name__ == "__main__":
unittest.main()