1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Add second output to trigger node

and add tests
This commit is contained in:
Dave Conway-Jones 2020-01-24 18:20:14 +00:00
parent 9d4238e5cc
commit bb12ec702a
No known key found for this signature in database
GPG Key ID: 302A6725C594817F
4 changed files with 91 additions and 38 deletions

View File

@ -14,7 +14,7 @@
limitations under the License. limitations under the License.
--> -->
<script type="text/x-red" data-template-name="trigger"> <script type="text/html" data-template-name="trigger">
<div class="form-row"> <div class="form-row">
<label data-i18n="trigger.send" for="node-input-op1"></label> <label data-i18n="trigger.send" for="node-input-op1"></label>
<input type="hidden" id="node-input-op1type"> <input type="hidden" id="node-input-op1type">
@ -47,6 +47,10 @@
<input type="hidden" id="node-input-op2type"> <input type="hidden" id="node-input-op2type">
<input style="width: 70%" type="text" id="node-input-op2" placeholder="0"> <input style="width: 70%" type="text" id="node-input-op2" placeholder="0">
</div> </div>
<div class="form-row">
<label></label>
<input type="checkbox" id="node-input-second" style="margin-left: 0px; vertical-align: top; width: auto !important;"> <label style="width:auto !important;" for="node-input-second" data-i18n="trigger.second"></label>
</div>
<div class="form-row"> <div class="form-row">
<label data-i18n="trigger.label.reset" style="width:auto"></label> <label data-i18n="trigger.label.reset" style="width:auto"></label>
<div style="display:inline-block; width:70%;vertical-align:top"> <div style="display:inline-block; width:70%;vertical-align:top">
@ -80,9 +84,11 @@
op2type: {value:"val"}, op2type: {value:"val"},
duration: {value:"250",required:true,validate:RED.validators.number()}, duration: {value:"250",required:true,validate:RED.validators.number()},
extend: {value:"false"}, extend: {value:"false"},
second: {value:false},
units: {value:"ms"}, units: {value:"ms"},
reset: {value:""}, reset: {value:""},
bytopic: {value: "all"}, bytopic: {value:"all"},
outputs: {value:1},
name: {value:""} name: {value:""}
}, },
inputs:1, inputs:1,
@ -103,6 +109,15 @@
return this.name?"node_label_italic":""; return this.name?"node_label_italic":"";
}, },
oneditprepare: function() { oneditprepare: function() {
var that = this;
$("#node-input-second").change(function() {
if ($("#node-input-second").is(":checked")) {
that.outputs = 2;
}
else {
that.outputs = 1;
}
});
$("#node-then-type").on("change", function() { $("#node-then-type").on("change", function() {
if ($(this).val() == "block") { if ($(this).val() == "block") {
$(".node-type-wait").hide(); $(".node-type-wait").hide();

View File

@ -24,6 +24,7 @@ module.exports = function(RED) {
this.op2 = n.op2 || "0"; this.op2 = n.op2 || "0";
this.op1type = n.op1type || "str"; this.op1type = n.op1type || "str";
this.op2type = n.op2type || "str"; this.op2type = n.op2type || "str";
this.second = n.second || false;
if (this.op1type === 'val') { if (this.op1type === 'val') {
if (this.op1 === 'true' || this.op1 === 'false') { if (this.op1 === 'true' || this.op1 === 'false') {
@ -188,7 +189,8 @@ module.exports = function(RED) {
promise.then(() => { promise.then(() => {
msg2.payload = node.topics[topic].m2; msg2.payload = node.topics[topic].m2;
delete node.topics[topic]; delete node.topics[topic];
node.send(msg2); if (node.second === true) { node.send([null,msg2]); }
else { node.send(msg2); }
node.status({}); node.status({});
}).catch(err => { }).catch(err => {
node.error(err); node.error(err);
@ -238,7 +240,8 @@ module.exports = function(RED) {
} }
delete node.topics[topic]; delete node.topics[topic];
node.status({}); node.status({});
node.send(msg2); if (node.second === true) { node.send([null,msg2]); }
else { node.send(msg2); }
}).catch(err => { }).catch(err => {
node.error(err); node.error(err);
}); });

View File

@ -311,6 +311,7 @@
"h": "Hours" "h": "Hours"
}, },
"extend": " extend delay if new message arrives", "extend": " extend delay if new message arrives",
"second": " send second message to separate output",
"label": { "label": {
"trigger": "trigger", "trigger": "trigger",
"trigger-block": "trigger & block", "trigger-block": "trigger & block",

View File

@ -102,20 +102,20 @@ describe('trigger node', function() {
function basicTest(type, val, rval) { function basicTest(type, val, rval) {
it('should output 1st value when triggered ('+type+')', function(done) { it('should output 1st value when triggered ('+type+')', function(done) {
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:val, op1type:type, op2:"", op2type:"null", duration:"20", wires:[["n2"]] }, var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:val, op1type:type, op2:"", op2type:"null", duration:"20", wires:[["n2"]] },
{id:"n2", type:"helper"} ]; {id:"n2", type:"helper"} ];
process.env[val] = rval; process.env[val] = rval;
helper.load(triggerNode, flow, function() { helper.load(triggerNode, flow, function() {
var n1 = helper.getNode("n1"); var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2"); var n2 = helper.getNode("n2");
n2.on("input", function(msg) { n2.on("input", function(msg) {
try { try {
if (rval) { if (rval) {
msg.should.have.property("payload"); msg.should.have.property("payload");
should.deepEqual(msg.payload, rval); should.deepEqual(msg.payload, rval);
} }
else { else {
msg.should.have.property("payload", val); msg.should.have.property("payload", val);
} }
delete process.env[val]; delete process.env[val];
done(); done();
} }
@ -127,7 +127,7 @@ describe('trigger node', function() {
it('should output 2st value when triggered ('+type+')', function(done) { it('should output 2st value when triggered ('+type+')', function(done) {
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"foo", op1type:"str", op2:val, op2type:type, duration:"20", wires:[["n2"]] }, var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"foo", op1type:"str", op2:val, op2type:type, duration:"20", wires:[["n2"]] },
{id:"n2", type:"helper"} ]; {id:"n2", type:"helper"} ];
process.env[val] = rval; process.env[val] = rval;
helper.load(triggerNode, flow, function() { helper.load(triggerNode, flow, function() {
var n1 = helper.getNode("n1"); var n1 = helper.getNode("n1");
@ -136,17 +136,17 @@ describe('trigger node', function() {
n2.on("input", function(msg) { n2.on("input", function(msg) {
try { try {
if (c === 0) { if (c === 0) {
msg.should.have.property("payload", "foo"); msg.should.have.property("payload", "foo");
c++; c++;
} }
else { else {
if (rval) { if (rval) {
msg.should.have.property("payload"); msg.should.have.property("payload");
should.deepEqual(msg.payload, rval); should.deepEqual(msg.payload, rval);
} }
else { else {
msg.should.have.property("payload", val); msg.should.have.property("payload", val);
} }
delete process.env[val]; delete process.env[val];
done(); done();
} }
@ -408,8 +408,8 @@ describe('trigger node', function() {
it('should be able to return things from persistable flow and global context variables', function (done) { it('should be able to return things from persistable flow and global context variables', function (done) {
var flow = [{"id": "n1", "type": "trigger", "name": "triggerNode", "op1": "#:(memory1)::foo", "op1type": "flow", var flow = [{"id": "n1", "type": "trigger", "name": "triggerNode", "op1": "#:(memory1)::foo", "op1type": "flow",
"op2": "#:(memory1)::bar", "op2type": "global", "duration": "20", "wires": [["n2"]], "z": "flow" }, "op2": "#:(memory1)::bar", "op2type": "global", "duration": "20", "wires": [["n2"]], "z": "flow" },
{"id": "n2", "type": "helper"}]; {"id": "n2", "type": "helper"}];
helper.load(triggerNode, flow, function () { helper.load(triggerNode, flow, function () {
initContext(function () { initContext(function () {
var n1 = helper.getNode("n1"); var n1 = helper.getNode("n1");
@ -442,11 +442,11 @@ describe('trigger node', function() {
it('should be able to return things from multiple persistable global context variables', function (done) { it('should be able to return things from multiple persistable global context variables', function (done) {
var flow = [{"id": "n1", "z": "flow", "type": "trigger", var flow = [{"id": "n1", "z": "flow", "type": "trigger",
"duration": "20", "wires": [["n2"]], "duration": "20", "wires": [["n2"]],
"op1": "#:(memory1)::val", "op1type": "global", "op1": "#:(memory1)::val", "op1type": "global",
"op2": "#:(memory2)::val", "op2type": "global" "op2": "#:(memory2)::val", "op2type": "global"
}, },
{"id": "n2", "type": "helper"}]; {"id": "n2", "type": "helper"}];
helper.load(triggerNode, flow, function () { helper.load(triggerNode, flow, function () {
initContext(function () { initContext(function () {
var n1 = helper.getNode("n1"); var n1 = helper.getNode("n1");
@ -481,11 +481,11 @@ describe('trigger node', function() {
it('should be able to return things from multiple persistable flow context variables', function (done) { it('should be able to return things from multiple persistable flow context variables', function (done) {
var flow = [{"id": "n1", "z": "flow", "type": "trigger", var flow = [{"id": "n1", "z": "flow", "type": "trigger",
"duration": "20", "wires": [["n2"]], "duration": "20", "wires": [["n2"]],
"op1": "#:(memory1)::val", "op1type": "flow", "op1": "#:(memory1)::val", "op1type": "flow",
"op2": "#:(memory2)::val", "op2type": "flow" "op2": "#:(memory2)::val", "op2type": "flow"
}, },
{"id": "n2", "type": "helper"}]; {"id": "n2", "type": "helper"}];
helper.load(triggerNode, flow, function () { helper.load(triggerNode, flow, function () {
initContext(function () { initContext(function () {
var n1 = helper.getNode("n1"); var n1 = helper.getNode("n1");
@ -520,11 +520,11 @@ describe('trigger node', function() {
it('should be able to return things from multiple persistable flow & global context variables', function (done) { it('should be able to return things from multiple persistable flow & global context variables', function (done) {
var flow = [{"id": "n1", "z": "flow", "type": "trigger", var flow = [{"id": "n1", "z": "flow", "type": "trigger",
"duration": "20", "wires": [["n2"]], "duration": "20", "wires": [["n2"]],
"op1": "#:(memory1)::val", "op1type": "flow", "op1": "#:(memory1)::val", "op1type": "flow",
"op2": "#:(memory2)::val", "op2type": "global" "op2": "#:(memory2)::val", "op2type": "global"
}, },
{"id": "n2", "type": "helper"}]; {"id": "n2", "type": "helper"}];
helper.load(triggerNode, flow, function () { helper.load(triggerNode, flow, function () {
initContext(function () { initContext(function () {
var n1 = helper.getNode("n1"); var n1 = helper.getNode("n1");
@ -781,6 +781,40 @@ describe('trigger node', function() {
}); });
}); });
it('should be able to send 2nd message to a 2nd output', function(done) {
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"val", op1:"hello", op2:"world", duration:"50", second:true, wires:[["n2"],["n3"]] },
{id:"n2", type:"helper"}, {id:"n3", type:"helper"} ];
helper.load(triggerNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var n3 = helper.getNode("n3");
var c = 0;
n2.on("input", function(msg) {
try {
if (c === 0) {
msg.should.have.a.property("payload", "hello");
msg.should.have.a.property("topic", "test");
c+=1;
}
else { done(err); }
}
catch(err) { done(err); }
});
n3.on("input", function(msg) {
try {
if (c === 1) {
msg.should.have.a.property("payload", "world");
msg.should.have.a.property("topic", "test");
done();
}
else { done(err); }
}
catch(err) { done(err); }
});
n1.emit("input", {payload:"go",topic:"test"});
});
});
it('should handle string null as null', function(done) { it('should handle string null as null', function(done) {
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"pay", op1:"null", op2:"null", duration:"40", wires:[["n2"]] }, var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"pay", op1:"null", op2:"null", duration:"40", wires:[["n2"]] },
{id:"n2", type:"helper"} ]; {id:"n2", type:"helper"} ];