diff --git a/tests/utils/test_utils.py b/tests/utils/test_utils.py index 5bbe3be3..054c010c 100644 --- a/tests/utils/test_utils.py +++ b/tests/utils/test_utils.py @@ -31,21 +31,48 @@ class TestHelpers(unittest.TestCase): dict2 = {"b": {"d": 3}, "e": 4} merged = helpers.merge_dicts(dict1, dict2, deep=True) self.assertEqual(merged, {"a": 1, "b": {"c": 2, "d": 3}, "e": 4}) + def test_flatten_dict(self): - data = {"a": {"b": 1, "c": 2}} + """Basic nested flattening with multiple sibling keys.""" + data = {"a": {"b": 1, "c": 2}, "d": 3} result = helpers.flatten_dict(data) - self.assertEqual(result, {"a.b": 1, "a.c": 2}) + self.assertEqual(result, {"a.b": 1, "a.c": 2, "d": 3}) + + def test_flatten_dict_deeply_nested(self): + """Deeply nested structure is fully flattened.""" + self.assertEqual( + helpers.flatten_dict({"a": {"b": {"c": 1}}}), + {"a.b.c": 1}, + ) + + def test_flatten_dict_custom_separator(self): + """Custom separator is used in generated keys.""" + self.assertEqual( + helpers.flatten_dict({"a": {"b": 1}}, sep="__"), + {"a__b": 1}, + ) + + def test_flatten_dict_empty(self): + """Empty input returns empty output.""" + self.assertEqual(helpers.flatten_dict({}), {}) def test_flatten_dict_key_collision(self): - data = { - "a.b": 1, - "a": { - "b": 2 - } - } + """#1010 regression: a top-level key containing the separator must not + silently overwrite a value produced from a nested dict when both resolve + to the same flattened key. Before the fix, {'a.b': 1, 'a': {'b': 2}} + silently dropped one value; now it raises ValueError.""" + with self.assertRaises(ValueError) as ctx: + helpers.flatten_dict({"a.b": 1, "a": {"b": 2}}) + self.assertIn("Key collision", str(ctx.exception)) + self.assertIn("a.b", str(ctx.exception)) - with self.assertRaises(ValueError): - helpers.flatten_dict(data) + def test_flatten_dict_no_false_positive(self): + """Similar-looking keys that produce distinct flattened keys must not + trigger the collision guard.""" + self.assertEqual( + helpers.flatten_dict({"a.b": 1, "a": {"c": 2}}), + {"a.b": 1, "a.c": 2}, + ) def test_safe_import_returns_module_and_flag(self): module, available = helpers.safe_import("json")