From 6a11c8b701c37671f65545e5520330dd939f0eb4 Mon Sep 17 00:00:00 2001 From: Francis Dong Date: Mon, 12 Apr 2021 11:15:49 +0800 Subject: [PATCH] Fixed override problem when expecting merge #117 --- .../src/main/java/we/util/MapUtil.java | 25 ++++ .../src/test/java/we/util/MapUtilTests.java | 119 ++++++++++++++++++ .../main/java/we/fizz/input/PathMapping.java | 5 +- 3 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 fizz-common/src/test/java/we/util/MapUtilTests.java diff --git a/fizz-common/src/main/java/we/util/MapUtil.java b/fizz-common/src/main/java/we/util/MapUtil.java index 3b2d77a..ef88445 100644 --- a/fizz-common/src/main/java/we/util/MapUtil.java +++ b/fizz-common/src/main/java/we/util/MapUtil.java @@ -211,4 +211,29 @@ public class MapUtil { return null; } + /** + * Merge maps, merge src to target + * @param target + * @param src + * @return + */ + @SuppressWarnings("unchecked") + public static Map merge(Map target, Map src) { + if(src == null || src.isEmpty()) { + return target; + } + src.forEach((key, value) -> { + if(value != null) { + target.merge(key, value, (oldValue, newValue) -> { + if (oldValue instanceof Map && newValue instanceof Map) { + oldValue = merge((Map) oldValue, (Map) newValue); + return oldValue; + } + return newValue; + }); + } + }); + return target; + } + } diff --git a/fizz-common/src/test/java/we/util/MapUtilTests.java b/fizz-common/src/test/java/we/util/MapUtilTests.java new file mode 100644 index 0000000..d0bf844 --- /dev/null +++ b/fizz-common/src/test/java/we/util/MapUtilTests.java @@ -0,0 +1,119 @@ +package we.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +public class MapUtilTests { + + + @Test + public void TestMerge() { + /** + * target = { + a: 1, + c: 3, + b: { + b1: "b1", + b2: { + c1: "c1" + c2: "c2" + }, + b3: [1, 2, 3], + b4: "b4" + } + }; + */ + Map target = new HashMap<>(); + target.put("a", 1); + target.put("c", 3); + + Map b = new HashMap<>(); + target.put("b", b); + b.put("b1", "b1"); + + Map c = new HashMap<>(); + c.put("c1", "c1"); + c.put("c2", "c2"); + b.put("b2", c); + + List list1 = new ArrayList<>(); + list1.add(1); + list1.add(2); + list1.add(3); + b.put("b3", list1); + b.put("b4", "b4"); + + + + /** + * src = { + b: { + b1: "b1-src", + b2: { + c1: "c1-src" + }, + b3: [1, 4] + }, + d: "d1" + }; + */ + Map src = new HashMap<>(); + Map srcb = new HashMap<>(); + srcb.put("b1", "b1-src"); + + Map srcc = new HashMap<>(); + srcc.put("c1", "c1-src"); + srcb.put("b2", srcc); + + List list2 = new ArrayList<>(); + list2.add(1); + list2.add(4); + srcb.put("b3", list2); + + src.put("b", srcb); + src.put("d", "d1"); + + + MapUtil.merge(target, src); + + /** + * expected output: + * { + "a": 1, + "b": { + "b1": "b1-src", + "b2": { + "c1": "c1-src", + "c2": "c2" + }, + "b3": [1, 4], + "b4": "b4" + }, + "c": 3, + "d": "d1" + } + */ + assertEquals(1, Integer.valueOf(target.get("a").toString())); + assertEquals(3, Integer.valueOf(target.get("c").toString())); + assertEquals("d1", target.get("d")); + + Map mapb = (Map) target.get("b"); + assertEquals("b1-src", mapb.get("b1")); + assertEquals("b4", mapb.get("b4")); + List list = (List) mapb.get("b3"); + assertEquals(2, list.size()); + assertEquals(1, list.get(0)); + assertEquals(4, list.get(1)); + + Map mapc = (Map) mapb.get("b2"); + assertEquals("c1-src", mapc.get("c1")); + assertEquals("c2", mapc.get("c2")); + } + +} diff --git a/fizz-core/src/main/java/we/fizz/input/PathMapping.java b/fizz-core/src/main/java/we/fizz/input/PathMapping.java index 07af7d2..5db153d 100644 --- a/fizz-core/src/main/java/we/fizz/input/PathMapping.java +++ b/fizz-core/src/main/java/we/fizz/input/PathMapping.java @@ -29,6 +29,7 @@ import org.noear.snack.ONode; import we.constants.CommonConstants; import we.fizz.StepContext; +import we.util.MapUtil; /** * @@ -380,12 +381,12 @@ public class PathMapping { Map scriptRules = PathMapping.getScriptRules(mappingRules); Map scriptResult = ScriptHelper.executeScripts(target, scriptRules, ctxNode, stepContext, supportMultiLevels); if (scriptResult != null && !scriptResult.isEmpty()) { - result.putAll(scriptResult); + result = MapUtil.merge(result, scriptResult); } } return result; } - + public static Map convertPath(Map fixed, boolean supportMultiLevels) { ONode target = ONode.load(new HashMap()); if (fixed.isEmpty()) {