diff --git a/nodes/core/locales/en-US/messages.json b/nodes/core/locales/en-US/messages.json index 4640ac012..9f1829203 100644 --- a/nodes/core/locales/en-US/messages.json +++ b/nodes/core/locales/en-US/messages.json @@ -577,6 +577,8 @@ "null":"is null", "nnull":"is not null", "istype":"is of type", + "empty":"is empty", + "nempty":"is not empty", "head":"head", "tail":"tail", "index":"index between", diff --git a/nodes/core/logic/10-switch.html b/nodes/core/logic/10-switch.html index a57ce2187..de1acbae3 100644 --- a/nodes/core/logic/10-switch.html +++ b/nodes/core/logic/10-switch.html @@ -60,6 +60,12 @@
  • An Otherwise rule can be used to match if none of the preceeding rules have matched.
  • +

    Notes

    +

    The is true/false and is null rules perform strict + comparisons against those types. They do not convert between types.

    +

    The is empty rule passes for Strings, Arrays and Buffers that have + a length of 0, or Objects that have no properties. It does not pass for null + or undefined values.

    Handling message sequences

    By default, the node does not modify the msg.parts property of messages that are part of a sequence.

    @@ -86,6 +92,8 @@ {v:"null",t:"switch.rules.null",kind:'V'}, {v:"nnull",t:"switch.rules.nnull",kind:'V'}, {v:"istype",t:"switch.rules.istype",kind:'V'}, + {v:"empty",t:"switch.rules.empty",kind:'V'}, + {v:"nempty",t:"switch.rules.nempty",kind:'V'}, {v:"head",t:"switch.rules.head",kind:'S'}, {v:"index",t:"switch.rules.index",kind:'S'}, {v:"tail",t:"switch.rules.tail",kind:'S'}, diff --git a/nodes/core/logic/10-switch.js b/nodes/core/logic/10-switch.js index df5a52023..e7f5cc841 100644 --- a/nodes/core/logic/10-switch.js +++ b/nodes/core/logic/10-switch.js @@ -31,6 +31,23 @@ module.exports = function(RED) { 'false': function(a) { return a === false; }, 'null': function(a) { return (typeof a == "undefined" || a === null); }, 'nnull': function(a) { return (typeof a != "undefined" && a !== null); }, + 'empty': function(a) { + if (typeof a === 'string' || Array.isArray(a) || Buffer.isBuffer(a)) { + return a.length === 0; + } else if (typeof a === 'object') { + return Object.keys(a).length === 0; + } + return false; + }, + 'nempty': function(a) { + if (typeof a === 'string' || Array.isArray(a) || Buffer.isBuffer(a)) { + return a.length !== 0; + } else if (typeof a === 'object') { + return Object.keys(a).length !== 0; + } + return false; + }, + 'istype': function(a, b) { if (b === "array") { return Array.isArray(a); } else if (b === "buffer") { return Buffer.isBuffer(a); } diff --git a/test/nodes/core/logic/10-switch_spec.js b/test/nodes/core/logic/10-switch_spec.js index 5159bf42e..b8e703d31 100644 --- a/test/nodes/core/logic/10-switch_spec.js +++ b/test/nodes/core/logic/10-switch_spec.js @@ -125,7 +125,7 @@ describe('switch Node', function() { helper.load(switchNode, flow, function() { var switchNode1 = helper.getNode("switchNode1"); var helperNode1 = helper.getNode("helperNode1"); - var sid = undefined; + var sid; var count = 0; if (modifier !== undefined) { modifier(switchNode1); @@ -333,6 +333,75 @@ describe('switch Node', function() { singularSwitchTest(false, true, false, true, done); }); + it('should check if payload is empty (string)', function(done) { + singularSwitchTest("empty", true, true, "", done); + }); + it('should check if payload is empty (array)', function(done) { + singularSwitchTest("empty", true, true, [], done); + }); + it('should check if payload is empty (buffer)', function(done) { + singularSwitchTest("empty", true, true, Buffer.alloc(0), done); + }); + it('should check if payload is empty (object)', function(done) { + singularSwitchTest("empty", true, true, {}, done); + }); + it('should check if payload is empty (non-empty string)', function(done) { + singularSwitchTest("empty", true, false, "1", done); + }); + it('should check if payload is empty (non-empty array)', function(done) { + singularSwitchTest("empty", true, false, [1], done); + }); + it('should check if payload is empty (non-empty buffer)', function(done) { + singularSwitchTest("empty", true, false, Buffer.alloc(1), done); + }); + it('should check if payload is empty (non-empty object)', function(done) { + singularSwitchTest("empty", true, false, {a:1}, done); + }); + it('should check if payload is empty (null)', function(done) { + singularSwitchTest("empty", true, false, null, done); + }); + it('should check if payload is empty (undefined)', function(done) { + singularSwitchTest("empty", true, false, undefined, done); + }); + it('should check if payload is empty (0)', function(done) { + singularSwitchTest("empty", true, false, null, done); + }); + + it('should check if payload is not empty (string)', function(done) { + singularSwitchTest("nempty", true, !true, "", done); + }); + it('should check if payload is not empty (array)', function(done) { + singularSwitchTest("nempty", true, !true, [], done); + }); + it('should check if payload is not empty (buffer)', function(done) { + singularSwitchTest("nempty", true, !true, Buffer.alloc(0), done); + }); + it('should check if payload is not empty (object)', function(done) { + singularSwitchTest("nempty", true, !true, {}, done); + }); + it('should check if payload is not empty (non-empty string)', function(done) { + singularSwitchTest("nempty", true, !false, "1", done); + }); + it('should check if payload is not empty (non-empty array)', function(done) { + singularSwitchTest("nempty", true, !false, [1], done); + }); + it('should check if payload is not empty (non-empty buffer)', function(done) { + singularSwitchTest("nempty", true, !false, Buffer.alloc(1), done); + }); + it('should check if payload is not empty (non-empty object)', function(done) { + singularSwitchTest("nempty", true, !false, {a:1}, done); + }); + it('should check if payload is not empty (null)', function(done) { + singularSwitchTest("nempty", true, false, null, done); + }); + it('should check if payload is not empty (undefined)', function(done) { + singularSwitchTest("nempty", true, false, undefined, done); + }); + it('should check if payload is not empty (0)', function(done) { + singularSwitchTest("nempty", true, false, null, done); + }); + + it('should check input against a previous value', function(done) { var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{ "t": "gt", "v": "", "vt": "prev" }],checkall:true,outputs:1,wires:[["helperNode1"]]}, {id:"helperNode1", type:"helper", wires:[]}]; @@ -666,9 +735,11 @@ describe('switch Node', function() { 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; + if (outs.hasOwnProperty(id)) { + var out = outs[id]; + vals[out.port] = out.vals; + recv_count += out.vals.length; + } } var count = 0; function check_msg(msg, ix, vf) { @@ -703,8 +774,8 @@ describe('switch Node', function() { } var index = parts.index; var eindex = counts[ix]; - var eval = evals[eindex]; - payload.should.equal(eval); + var value = evals[eindex]; + payload.should.equal(value); counts[ix]++; count++; if (count === recv_count) { @@ -716,18 +787,22 @@ describe('switch Node', function() { } } 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); - }); - })(); + if (outs.hasOwnProperty(id)) { + (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}}); + if (seq_in.hasOwnProperty(i)) { + n1.receive({payload:seq_in[i], xindex:i, + parts:{index:i, count:seq_in.length, id:222}}); + } } }); }