Ver Fonte

fix: Merge throws on keyless combine items, choose-first ignores empty branches

fszontagh há 1 mês atrás
pai
commit
cec4008fd8
3 ficheiros alterados com 48 adições e 3 exclusões
  1. 19 2
      nodes/core/merge.js
  2. 21 0
      tests/nodes/merge-errors.json
  3. 8 1
      tests/nodes/merge.json

+ 19 - 2
nodes/core/merge.js

@@ -68,14 +68,25 @@ function selectInput(value, path) {
     return smartbotic.utils.getFieldValue(value, path);
 }
 
+function producedSomething(value) {
+    if (value === undefined || value === null) {
+        return false;
+    }
+    if (Array.isArray(value) && value.length === 0) {
+        return false;
+    }
+    return true;
+}
+
 async function execute(config, input, context) {
     const mode = config.mode || 'append';
     const first = selectInput(input ? input.input1 : undefined, config.path1);
     const second = selectInput(input ? input.input2 : undefined, config.path2);
 
     if (mode === 'choose-first') {
-        const chosen = first !== undefined && first !== null ? first : second;
-        smartbotic.log.info('Merge: choose-first took ' + (first !== undefined && first !== null ? 'input1' : 'input2'));
+        const firstHasSomething = producedSomething(first);
+        const chosen = firstHasSomething ? first : (producedSomething(second) ? second : first);
+        smartbotic.log.info('Merge: choose-first took ' + (firstHasSomething ? 'input1' : 'input2'));
         return {
             merged: chosen === undefined ? null : chosen,
             count: Array.isArray(chosen) ? chosen.length : (chosen === undefined || chosen === null ? 0 : 1)
@@ -93,6 +104,9 @@ async function execute(config, input, context) {
 
         for (const item of asArray(first)) {
             if (item === null || typeof item !== 'object') continue;
+            if (item[key] === undefined || item[key] === null) {
+                throw new Error('Merge: an item in input1 has no "' + key + '" to combine on');
+            }
             const id = String(item[key]);
             byKey[id] = JSON.parse(JSON.stringify(item));
             order.push(id);
@@ -100,6 +114,9 @@ async function execute(config, input, context) {
 
         for (const item of asArray(second)) {
             if (item === null || typeof item !== 'object') continue;
+            if (item[key] === undefined || item[key] === null) {
+                throw new Error('Merge: an item in input2 has no "' + key + '" to combine on');
+            }
             const id = String(item[key]);
             if (byKey[id] === undefined) {
                 byKey[id] = JSON.parse(JSON.stringify(item));

+ 21 - 0
tests/nodes/merge-errors.json

@@ -0,0 +1,21 @@
+{
+  "name": "verify-merge-errors",
+  "nodes": [
+    {"id": "n1", "name": "Trigger", "type": "click-trigger", "position": {"x": 0, "y": 0}, "config": {}},
+    {"id": "a", "name": "BranchA", "type": "code", "position": {"x": -100, "y": 100},
+     "config": {"code": "return [{name: 'no-id-one'}, {name: 'no-id-two'}];"}},
+    {"id": "b", "name": "BranchB", "type": "code", "position": {"x": 100, "y": 100},
+     "config": {"code": "return [{id: 1, name: 'one'}];"}},
+    {"id": "m", "name": "Merge", "type": "merge", "position": {"x": 0, "y": 220},
+     "config": {"mode": "combine-by-key", "key": "id", "path1": "result", "path2": "result"}}
+  ],
+  "connections": [
+    {"sourceNodeId": "n1", "sourceOutput": "main", "targetNodeId": "a", "targetInput": "data"},
+    {"sourceNodeId": "n1", "sourceOutput": "main", "targetNodeId": "b", "targetInput": "data"},
+    {"sourceNodeId": "a", "sourceOutput": "main", "targetNodeId": "m", "targetInput": "input1"},
+    {"sourceNodeId": "b", "sourceOutput": "main", "targetNodeId": "m", "targetInput": "input2"}
+  ],
+  "expect": {
+    "m": {"status": "failed"}
+  }
+}

+ 8 - 1
tests/nodes/merge.json

@@ -16,6 +16,13 @@
     {"sourceNodeId": "b", "sourceOutput": "main", "targetNodeId": "m", "targetInput": "input2"}
   ],
   "expect": {
-    "m": {"status": "completed", "output": {"count": 3}}
+    "m": {"status": "completed", "output": {
+      "count": 3,
+      "merged": [
+        {"id": 1, "name": "one"},
+        {"id": 2, "name": "two", "extra": "from-b"},
+        {"id": 3, "name": "three"}
+      ]
+    }}
   }
 }