From 2753075180da63157a66de240991f24e2ac4e183 Mon Sep 17 00:00:00 2001 From: Hiroyasu Nishiyama Date: Fri, 26 Jan 2018 12:39:07 +0900 Subject: [PATCH] fix bugs in SWITCH updates --- nodes/core/logic/10-switch.js | 19 +- test/nodes/core/logic/10-switch_spec.js | 272 +++++++++++++++--------- 2 files changed, 185 insertions(+), 106 deletions(-) diff --git a/nodes/core/logic/10-switch.js b/nodes/core/logic/10-switch.js index 3acc9e3c5..1fa9fd02c 100644 --- a/nodes/core/logic/10-switch.js +++ b/nodes/core/logic/10-switch.js @@ -83,8 +83,8 @@ module.exports = function(RED) { this.previousValue = null; var node = this; var valid = true; - var needs_count = false; var repair = n.repair; + var needs_count = repair; for (var i=0; i 0); }); - }); - for(var i in data) { - n1.receive({payload: data[i], parts:{index:i,count:5,id:222}}); - } - }); + + it('should be able to use $I in JSONata expression', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"jsonata_exp","v":"$I % 2 = 1",vt:"jsonata"}],checkall:true,repair:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [1, 3], true, undefined, done); }); - it('should create message sequence for each port', function(done) { - var flow = [{id:"n1",type:"switch",name:"switchNode",property:"payload", - rules:[{"t":"gt","v":0},{"t":"lt","v":0},{"t":"else"}], - checkall:true,repair:false, - outputs:3,wires:[["n2"],["n3"],["n4"]]}, - {id:"n2", type:"helper", wires:[]}, // >0 - {id:"n3", type:"helper", wires:[]}, // <0 - {id:"n4", type:"helper", wires:[]} // ==0 - ]; + it('should be able to use $N in JSONata expression', function(done) { + var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"jsonata_exp","v":"payload >= $N-2",vt:"jsonata"}],checkall:true,repair:true,outputs:1,wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [3, 4], true, undefined, done); + }); + + + function customFlowSequenceMultiSwitchTest(flow, seq_in, outs, repair, done) { helper.load(switchNode, flow, function() { var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - var n3 = helper.getNode("n3"); - var n4 = helper.getNode("n4"); - var data = [ 1, -2, 2, 0, -1 ]; - var vals = [[1, 2], [-2, -1], [0]]; - var ids = [undefined, undefined, undefined]; - var counts = [0, 0, 0]; + var port_count = Object.keys(outs).length; + var sid; + var ids = new Array(port_count).fill(undefined); + var counts = new Array(port_count).fill(0); + var vals = new Array(port_count); + var recv_count = 0; + for (var id in outs) { + var out = outs[id]; + vals[out.port] = out.vals; + recv_count += out.vals.length; + } var count = 0; function check_msg(msg, ix, vf) { try { @@ -644,23 +645,35 @@ describe('switch Node', function() { vf(payload).should.be.ok; var parts = msg.parts; var evals = vals[ix]; - parts.should.have.property("count", evals.length); parts.should.have.property("id"); var id = parts.id; - if (ids[ix] === undefined) { - ids[ix] = id; + if (repair) { + if (ids[ix] === undefined) { + ids[ix] = id; + } + else { + ids[ix].should.equal(id); + } + parts.should.have.property("count", evals.length); + parts.should.have.property("index", counts[ix]); } else { - ids[ix].should.equal(id); + if (sid === undefined) { + sid = id; + } + else { + sid.should.equal(id); + } + parts.should.have.property("count", seq_in.length); + parts.should.have.property("index", msg.xindex); } - parts.should.have.property("index"); var index = parts.index; var eindex = counts[ix]; var eval = evals[eindex]; payload.should.equal(eval); counts[ix]++; count++; - if (count == 5) { + if (count === recv_count) { done(); } } @@ -668,19 +681,84 @@ describe('switch Node', function() { done(e); } } - n2.on("input", function(msg) { - check_msg(msg, 0, function(x) { return(x > 0); }); - }); - n3.on("input", function(msg) { - check_msg(msg, 1, function(x) { return(x < 0); }); - }); - n4.on("input", function(msg) { - check_msg(msg, 2, function(x) { return(x === 0); }); - }); - for(var i in data) { - n1.receive({payload: data[i], parts:{index:i,count:5,id:222}}); + for (var id in outs) { + (function() { + var node = helper.getNode(id); + var port = outs[id].port; + var vf = outs[id].vf; + node.on("input", function(msg) { + check_msg(msg, port, vf); + }); + })(); + } + for(var i in seq_in) { + n1.receive({payload:seq_in[i], xindex:i, + parts:{index:i, count:seq_in.length, id:222}}); } }); + } + + it('should not repair message sequence for each port', function(done) { + var flow = [{id:"n1",type:"switch",name:"switchNode",property:"payload", + rules:[{"t":"gt","v":0},{"t":"lt","v":0},{"t":"else"}], + checkall:true,repair:false, + outputs:3,wires:[["n2"],["n3"],["n4"]]}, + {id:"n2", type:"helper", wires:[]}, + {id:"n3", type:"helper", wires:[]}, + {id:"n4", type:"helper", wires:[]} + ]; + var data = [ 1, -2, 2, 0, -1 ]; + var outs = { + "n2" : { port:0, vals:[1, 2], + vf:function(x) { return(x > 0); } }, + "n3" : { port:1, vals:[-2, -1], + vf:function(x) { return(x < 0); } }, + "n4" : { port:2, vals:[0], + vf:function(x) { return(x == 0); } }, + }; + customFlowSequenceMultiSwitchTest(flow, data, outs, false, done); + }); + + it('should repair message sequence for each port', function(done) { + var flow = [{id:"n1",type:"switch",name:"switchNode",property:"payload", + rules:[{"t":"gt","v":0},{"t":"lt","v":0},{"t":"else"}], + checkall:true,repair:true, + outputs:3,wires:[["n2"],["n3"],["n4"]]}, + {id:"n2", type:"helper", wires:[]}, // >0 + {id:"n3", type:"helper", wires:[]}, // <0 + {id:"n4", type:"helper", wires:[]} // ==0 + ]; + var data = [ 1, -2, 2, 0, -1 ]; + var outs = { + "n2" : { port:0, vals:[1, 2], + vf:function(x) { return(x > 0); } }, + "n3" : { port:1, vals:[-2, -1], + vf:function(x) { return(x < 0); } }, + "n4" : { port:2, vals:[0], + vf:function(x) { return(x == 0); } }, + }; + customFlowSequenceMultiSwitchTest(flow, data, outs, true, done); + }); + + it('should repair message sequence for each port (overlap)', function(done) { + var flow = [{id:"n1",type:"switch",name:"switchNode",property:"payload", + rules:[{"t":"gte","v":0},{"t":"lte","v":0},{"t":"else"}], + checkall:true,repair:true, + outputs:3,wires:[["n2"],["n3"],["n4"]]}, + {id:"n2", type:"helper", wires:[]}, // >=0 + {id:"n3", type:"helper", wires:[]}, // <=0 + {id:"n4", type:"helper", wires:[]} // none + ]; + var data = [ 1, -2, 2, 0, -1 ]; + var outs = { + "n2" : { port:0, vals:[1, 2, 0], + vf:function(x) { return(x > 0); } }, + "n3" : { port:1, vals:[-2, 0, -1], + vf:function(x) { return(x < 0); } }, + "n4" : { port:2, vals:[], + vf:function(x) { return(false); } }, + }; + customFlowSequenceMultiSwitchTest(flow, data, outs, true, done); }); it('should handle too many pending messages', function(done) {