From fd5a998e2af681ccfdc952b32f2ac3361e109bdb Mon Sep 17 00:00:00 2001 From: spicy-sauce Date: Sun, 5 Jan 2025 14:05:24 +0200 Subject: [PATCH] map_record() handling of None in nested paths --- core/src/datayoga_core/write_utils.py | 13 +++++- core/tests/test_write_utils.py | 67 +++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/core/src/datayoga_core/write_utils.py b/core/src/datayoga_core/write_utils.py index 341724d0..c8d7f3b8 100644 --- a/core/src/datayoga_core/write_utils.py +++ b/core/src/datayoga_core/write_utils.py @@ -58,11 +58,20 @@ def map_record( source_path = utils.split_field(source) obj = record + found = True for key in source_path: key = utils.unescape_field(key) - if key in obj: + + if obj is None: + found = False + break + + if isinstance(obj, dict) and key in obj: obj = obj[key] + else: + found = False + break - mapped_record[target] = obj if obj != record else None + mapped_record[target] = obj if found else None return mapped_record diff --git a/core/tests/test_write_utils.py b/core/tests/test_write_utils.py index d7e7a664..00911aac 100644 --- a/core/tests/test_write_utils.py +++ b/core/tests/test_write_utils.py @@ -1,3 +1,4 @@ +import pytest from datayoga_core import write_utils from datayoga_core.result import Status @@ -32,3 +33,69 @@ def test_group_by_opcode_invalid_opcode(): groups = write_utils.group_records_by_opcode(change_records, opcode_field="opcode") assert groups["r"] == change_records[0:1] assert groups["x"] == change_records[1:2] + + +@pytest.mark.parametrize("record, source, expected", [ + # Existing simple nested key + ( + {"value": {"id": 123}}, + "value.id", + {"target": 123} + ), + # Existing deeply nested key + ( + {"user": {"profile": {"email": "john@example.com"}}}, + "user.profile.email", + {"target": "john@example.com"} + ), + # Missing simple nested key + ( + {"value": {"x": 2}}, + "value.id", + {"target": None} + ), + # Missing deeply nested key + ( + {"user": {"profile": {"name": "John"}}}, + "user.profile.email", + {"target": None} + ), + # Partially nested key + ( + {"user": {"profile": {"name": "John"}}}, + "user.address.street", + {"target": None} + ), + # Mixed case with existing and non-existing keys + ( + {"data": {"info": {"id": 123, "active": True}}}, + "data.info.status", + {"target": None} + ), + # Empty nested structure + ( + {"user": {}}, + "user.profile", + {"target": None} + ), + # Null value in nested structure + ( + {"user": {"profile": None}}, + "user.profile.name", + {"target": None} + ), + # Boolean value + ( + {"settings": {"active": True}}, + "settings.active", + {"target": True} + ) +]) +def test_map_record_nested_key(record, source, expected): + """Tests map_record function's handling of nested keys, including existing and missing scenarios.""" + mapped = write_utils.map_record( + record, + keys=[{"target": source}] + ) + + assert mapped == expected, f"Failed for record {record} with source {source}"