Merge pull request #2227 from node-red/node-done

Adds Done callback to Input event handler
This commit is contained in:
Nick O'Leary
2019-08-21 11:15:00 +01:00
committed by GitHub
25 changed files with 1333 additions and 565 deletions

View File

@@ -268,45 +268,50 @@ describe('function node', function() {
helper.load(functionNode, flow, function() {
var n1 = helper.getNode("n1");
n1.receive({payload:"foo",topic: "bar"});
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().ERROR);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'ReferenceError: retunr is not defined (line 2, col 1)');
done();
} catch(err) {
done(err);
}
setTimeout(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().ERROR);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'ReferenceError: retunr is not defined (line 2, col 1)');
done();
} catch(err) {
done(err);
}
},50);
});
});
it('should handle node.on()', function(done) {
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.on('close',function(){node.log('closed')});"}];
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.on('close',function(){ node.log('closed')});"}];
helper.load(functionNode, flow, function() {
var n1 = helper.getNode("n1");
n1.receive({payload:"foo",topic: "bar"});
helper.getNode("n1").close();
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "function";
setTimeout(function() {
n1.close().then(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().INFO);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'closed');
done();
} catch(err) {
done(err);
}
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().INFO);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'closed');
done();
} catch(err) {
done(err);
}
},1500);
});
});
@@ -532,22 +537,24 @@ describe('function node', function() {
});
function checkCallbackError(name, done) {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().ERROR);
msg.should.have.property('id', name);
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'Error: Callback must be a function');
done();
}
catch (e) {
done(e);
}
setTimeout(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().ERROR);
msg.should.have.property('id', name);
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'Error: Callback must be a function');
done();
}
catch (e) {
done(e);
}
},50);
}
it('should get persistable node context (w/o callback)', function(done) {
@@ -1267,12 +1274,12 @@ describe('function node', function() {
n1.receive({payload:"foo",topic: "bar"});
} else {
msg.should.have.property('payload', "hello");
delete process.env._TEST_FOO_;
done();
}
} catch(err) {
done(err);
} finally {
delete process.env._TEST_FOO_;
done(err);
}
});
n1.receive({payload:"foo",topic: "bar"});
@@ -1285,21 +1292,23 @@ describe('function node', function() {
helper.load(functionNode, flow, function () {
var n1 = helper.getNode("n1");
n1.receive({payload: "foo", topic: "bar"});
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().INFO);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
setTimeout(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().INFO);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
},50);
});
});
it('should log a Debug Message', function (done) {
@@ -1307,21 +1316,23 @@ describe('function node', function() {
helper.load(functionNode, flow, function () {
var n1 = helper.getNode("n1");
n1.receive({payload: "foo", topic: "bar"});
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().DEBUG);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
setTimeout(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().DEBUG);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
},50);
});
});
it('should log a Trace Message', function (done) {
@@ -1329,21 +1340,23 @@ describe('function node', function() {
helper.load(functionNode, flow, function () {
var n1 = helper.getNode("n1");
n1.receive({payload: "foo", topic: "bar"});
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().TRACE);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
setTimeout(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().TRACE);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
},50);
});
});
it('should log a Warning Message', function (done) {
@@ -1351,21 +1364,23 @@ describe('function node', function() {
helper.load(functionNode, flow, function () {
var n1 = helper.getNode("n1");
n1.receive({payload: "foo", topic: "bar"});
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().WARN);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
setTimeout(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().WARN);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
},50);
});
});
it('should log an Error Message', function (done) {
@@ -1373,21 +1388,23 @@ describe('function node', function() {
helper.load(functionNode, flow, function () {
var n1 = helper.getNode("n1");
n1.receive({payload: "foo", topic: "bar"});
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().ERROR);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
setTimeout(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "function";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().ERROR);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'test');
done();
} catch (err) {
done(err);
}
},50);
});
});
it('should catch thrown string', function (done) {

View File

@@ -475,20 +475,21 @@ describe('SORT node', function() {
{id:"n2", type:"helper"}];
helper.load(sortNode, flow, function() {
var n1 = helper.getNode("n1");
setTimeout(function() {
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "sort";
});
var evt = logEvents[0][0];
evt.should.have.property('id', "n1");
evt.should.have.property('type', "sort");
evt.should.have.property('msg', "sort.clear");
done();
}, 150);
var msg = { payload: 0,
parts: { id: "X", index: 0, count: 2} };
n1.receive(msg);
n1.close();
setTimeout(function() {
n1.close().then(function() {
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "sort";
});
var evt = logEvents[0][0];
evt.should.have.property('id', "n1");
evt.should.have.property('type', "sort");
evt.should.have.property('msg', "sort.clear");
done();
});
}, 150);
});
});

View File

@@ -21,7 +21,7 @@ var fs = require('fs-extra');
var htmlNode = require("nr-test-utils").require("@node-red/nodes/core/parsers/70-HTML.js");
var helper = require("node-red-node-test-helper");
describe('html node', function() {
describe('HTML node', function() {
var resourcesDir = __dirname+ path.sep + ".." + path.sep + ".." + path.sep + ".." + path.sep + "resources" + path.sep;
var file = path.join(resourcesDir, "70-HTML-test-file.html");
@@ -228,16 +228,20 @@ describe('html node', function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n1.receive({payload:null,topic: "bar"});
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "html";
});
logEvents.should.have.length(1);
// Each logEvent is the array of args passed to the function.
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
setTimeout(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "html";
});
logEvents.should.have.length(1);
// Each logEvent is the array of args passed to the function.
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
done();
} catch(err) { done(err) }
},50);
} catch(err) {
done(err);
}

View File

@@ -148,14 +148,18 @@ describe('JSON node', function() {
var jn1 = helper.getNode("jn1");
var jn2 = helper.getNode("jn2");
jn1.receive({payload:'foo',topic: "bar"});
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.startWith("Unexpected token o");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
setTimeout(function() {
try {
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.startWith("Unexpected token o");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
} catch(err) { done(err) }
},20);
} catch(err) {
done(err);
}
@@ -378,14 +382,18 @@ describe('JSON node', function() {
var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}};
var obj = {"number": "foo", "string": 3};
jn1.receive({payload:obj, schema:schema});
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
setTimeout(function() {
try {
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
} catch(err) { done(err) }
},50);
} catch(err) {
done(err);
}
@@ -402,14 +410,18 @@ describe('JSON node', function() {
var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}};
var obj = {"number": "foo", "string": 3};
jn1.receive({payload:obj, schema:schema});
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
setTimeout(function() {
try {
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
} catch(err) { done(err) }
},50);
} catch(err) {
done(err);
}
@@ -426,14 +438,18 @@ describe('JSON node', function() {
var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}};
var jsonString = '{"number":"Hello","string":3}';
jn1.receive({payload:jsonString, schema:schema});
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
setTimeout(function() {
try {
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
} catch(err) { done(err) }
},50);
} catch(err) {
done(err);
}
@@ -450,14 +466,18 @@ describe('JSON node', function() {
var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}};
var jsonString = '{"number":"Hello","string":3}';
jn1.receive({payload:jsonString, schema:schema});
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
setTimeout(function() {
try {
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
} catch(err) { done(err) }
},50);
} catch(err) {
done(err);
}
@@ -474,14 +494,18 @@ describe('JSON node', function() {
var schema = "garbage";
var obj = {"number": "foo", "string": 3};
jn1.receive({payload:obj, schema:schema});
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error-compile");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
setTimeout(function() {
try {
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "json";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.equal("json.errors.schema-error-compile");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
} catch(err) { done(err) }
},50);
} catch(err) {
done(err);
}

View File

@@ -130,14 +130,18 @@ describe('YAML node', function() {
var yn1 = helper.getNode("yn1");
var yn2 = helper.getNode("yn2");
yn1.receive({payload:'employees:\n-firstName: John\n- lastName: Smith\n',topic: "bar"});
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "yaml";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.startWith("end of the stream");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
setTimeout(function() {
try {
var logEvents = helper.log().args.filter(function(evt) {
return evt[0].type == "yaml";
});
logEvents.should.have.length(1);
logEvents[0][0].should.have.a.property('msg');
logEvents[0][0].msg.should.startWith("end of the stream");
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
done();
} catch(err) { done(err) }
},50);
} catch(err) {
done(err);
}

View File

@@ -156,10 +156,50 @@ describe('Node', function() {
throw new Error("test error");
});
n.receive(message);
n.error.called.should.be.true();
n.error.firstCall.args[1].should.equal(message);
done();
setTimeout(function() {
n.error.called.should.be.true();
n.error.firstCall.args[1].should.equal(message);
done();
},50);
});
it('calls parent flow handleComplete when callback provided', function(done) {
var n = new RedNode({id:'123',type:'abc', _flow: {
handleComplete: function(node,msg) {
try {
msg.should.deepEqual(message);
done();
} catch(err) {
done(err);
}
}
}});
var message = {payload:"hello world"};
n.on('input',function(msg, nodeSend, nodeDone) {
nodeDone();
});
n.receive(message);
});
it('logs error if callback provides error', function(done) {
var n = new RedNode({id:'123',type:'abc'});
sinon.stub(n,"error",function(err,msg) {});
var message = {payload:"hello world"};
n.on('input',function(msg, nodeSend, nodeDone) {
nodeDone(new Error("test error"));
setTimeout(function() {
try {
n.error.called.should.be.true();
n.error.firstCall.args[0].toString().should.equal("Error: test error");
n.error.firstCall.args[1].should.equal(message);
done();
} catch(err) {
done(err);
}
},50);
});
n.receive(message);
});
});
@@ -172,15 +212,69 @@ describe('Node', function() {
var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n2']]});
var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'});
var message = {payload:"hello world"};
var messageReceived = false;
n2.on('input',function(msg) {
// msg equals message, and is not a new copy
messageReceived = true;
should.deepEqual(msg,message);
should.strictEqual(msg,message);
done();
});
n1.send(message);
messageReceived.should.be.false();
});
it('emits a single message - synchronous mode', function(done) {
var flow = {
getNode: (id) => { return {'n1':n1,'n2':n2}[id]},
asyncMessageDelivery: false
};
var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n2']]});
var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'});
var message = {payload:"hello world"};
var messageReceived = false;
var notSyncErr;
n2.on('input',function(msg) {
try {
// msg equals message, and is not a new copy
messageReceived = true;
should.deepEqual(msg,message);
should.strictEqual(msg,message);
done(notSyncErr);
} catch(err) {
done(err);
}
});
n1.send(message);
try {
messageReceived.should.be.true();
} catch(err) {
notSyncErr = err;
}
});
it('emits a message with callback provided send', function(done) {
var flow = {
getNode: (id) => { return {'n1':n1,'n2':n2}[id]},
handleComplete: (node,msg) => {}
};
var n1 = new RedNode({_flow:flow,id:'n1',type:'abc',wires:[['n2']]});
var n2 = new RedNode({_flow:flow,id:'n2',type:'abc'});
var message = {payload:"hello world"};
var messageReceived = false;
n1.on('input',function(msg,nodeSend,nodeDone) {
nodeSend(msg);
nodeDone();
});
n2.on('input',function(msg) {
// msg equals message, and is not a new copy
messageReceived = true;
should.deepEqual(msg,message);
should.strictEqual(msg,message);
done();
});
n1.receive(message);
messageReceived.should.be.false();
});
it('emits multiple messages on a single output', function(done) {
@@ -356,12 +450,13 @@ describe('Node', function() {
it("logs the uuid for all messages sent", function(done) {
var logHandler = {
msgIds:[],
messagesSent: 0,
emit: function(event, msg) {
if (msg.event == "node.abc.send" && msg.level == Log.METRIC) {
this.messagesSent++;
this.msgIds.push(msg.msgid);
(typeof msg.msgid).should.not.be.equal("undefined");
done();
}
}
};
@@ -375,6 +470,17 @@ describe('Node', function() {
var receiver1 = new RedNode({_flow:flow,id:'n2',type:'abc'});
var receiver2 = new RedNode({_flow:flow,id:'n3',type:'abc'});
sender.send({"some": "message"});
setTimeout(function() {
try {
logHandler.messagesSent.should.equal(1);
should.exist(logHandler.msgIds[0])
Log.removeHandler(logHandler);
done();
} catch(err) {
Log.removeHandler(logHandler);
done(err);
}
},50)
})
});

View File

@@ -122,6 +122,7 @@ describe('Flow', function() {
currentNodes[node.id] = node;
this.on('input',function(msg) {
node.handled++;
msg.handled = node.handled;
node.messages.push(msg);
node.send(msg);
});
@@ -136,12 +137,42 @@ describe('Flow', function() {
}
util.inherits(TestAsyncNode,Node);
var TestDoneNode = function(n) {
Node.call(this,n);
var node = this;
this.scope = n.scope;
this.uncaught = n.uncaught;
this.foo = n.foo;
this.handled = 0;
this.messages = [];
this.stopped = false;
this.closeDelay = n.closeDelay || 50;
currentNodes[node.id] = node;
this.on('input',function(msg, send, done) {
node.handled++;
node.messages.push(msg);
send(msg);
done();
});
this.on('close',function(done) {
setTimeout(function() {
node.stopped = true;
stoppedNodes[node.id] = node;
delete currentNodes[node.id];
done();
},node.closeDelay);
});
}
util.inherits(TestDoneNode,Node);
before(function() {
getType = sinon.stub(typeRegistry,"get",function(type) {
if (type=="test") {
return TestNode;
} else if (type=="testError"){
return TestErrorNode;
} else if (type=="testDone"){
return TestDoneNode;
} else {
return TestAsyncNode;
}
@@ -189,28 +220,28 @@ describe('Flow', function() {
currentNodes["2"].should.have.a.property("handled",0);
currentNodes["3"].should.have.a.property("handled",0);
currentNodes["3"].on("input", function() {
currentNodes["1"].should.have.a.property("handled",1);
currentNodes["2"].should.have.a.property("handled",1);
currentNodes["3"].should.have.a.property("handled",1);
currentNodes["1"].receive({payload:"test"});
currentNodes["1"].should.have.a.property("handled",1);
currentNodes["2"].should.have.a.property("handled",1);
currentNodes["3"].should.have.a.property("handled",1);
flow.stop().then(function() {
try {
currentNodes.should.not.have.a.property("1");
currentNodes.should.not.have.a.property("2");
currentNodes.should.not.have.a.property("3");
currentNodes.should.not.have.a.property("4");
stoppedNodes.should.have.a.property("1");
stoppedNodes.should.have.a.property("2");
stoppedNodes.should.have.a.property("3");
stoppedNodes.should.have.a.property("4");
done();
} catch(err) {
done(err);
}
flow.stop().then(function() {
try {
currentNodes.should.not.have.a.property("1");
currentNodes.should.not.have.a.property("2");
currentNodes.should.not.have.a.property("3");
currentNodes.should.not.have.a.property("4");
stoppedNodes.should.have.a.property("1");
stoppedNodes.should.have.a.property("2");
stoppedNodes.should.have.a.property("3");
stoppedNodes.should.have.a.property("4");
done();
} catch(err) {
done(err);
}
});
});
currentNodes["1"].receive({payload:"test"});
});
it("instantiates config nodes in the right order",function(done) {
@@ -350,25 +381,27 @@ describe('Flow', function() {
currentNodes["1"].receive({payload:"test"});
currentNodes["1"].should.have.a.property("handled",1);
// Message doesn't reach 3 as 2 is disabled
currentNodes["3"].should.have.a.property("handled",0);
setTimeout(function() {
currentNodes["1"].should.have.a.property("handled",1);
// Message doesn't reach 3 as 2 is disabled
currentNodes["3"].should.have.a.property("handled",0);
flow.stop().then(function() {
try {
currentNodes.should.not.have.a.property("1");
currentNodes.should.not.have.a.property("2");
currentNodes.should.not.have.a.property("3");
currentNodes.should.not.have.a.property("4");
stoppedNodes.should.have.a.property("1");
stoppedNodes.should.not.have.a.property("2");
stoppedNodes.should.have.a.property("3");
stoppedNodes.should.have.a.property("4");
done();
} catch(err) {
done(err);
}
});
flow.stop().then(function() {
try {
currentNodes.should.not.have.a.property("1");
currentNodes.should.not.have.a.property("2");
currentNodes.should.not.have.a.property("3");
currentNodes.should.not.have.a.property("4");
stoppedNodes.should.have.a.property("1");
stoppedNodes.should.not.have.a.property("2");
stoppedNodes.should.have.a.property("3");
stoppedNodes.should.have.a.property("4");
done();
} catch(err) {
done(err);
}
});
},50);
});
});
@@ -551,31 +584,34 @@ describe('Flow', function() {
flow.handleStatus(config.flows["t1"].nodes["1"],{text:"my-status",random:"otherProperty"});
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
setTimeout(function() {
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","my-status");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","1");
statusMessage.status.source.should.have.a.property("type","test");
statusMessage.status.source.should.have.a.property("name","a");
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
currentNodes["sn2"].should.have.a.property("handled",1);
statusMessage = currentNodes["sn2"].messages[0];
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","my-status");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","1");
statusMessage.status.source.should.have.a.property("type","test");
statusMessage.status.source.should.have.a.property("name","a");
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","my-status");
statusMessage.status.should.have.a.property("random","otherProperty");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","1");
statusMessage.status.source.should.have.a.property("type","test");
statusMessage.status.source.should.have.a.property("name","a");
currentNodes["sn2"].should.have.a.property("handled",1);
statusMessage = currentNodes["sn2"].messages[0];
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","my-status");
statusMessage.status.should.have.a.property("random","otherProperty");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","1");
statusMessage.status.source.should.have.a.property("type","test");
statusMessage.status.source.should.have.a.property("name","a");
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50)
});
it("passes a status event to the adjacent scoped status node ",function(done) {
var config = flowUtils.parseConfig([
@@ -596,21 +632,23 @@ describe('Flow', function() {
flow.handleStatus(config.flows["t1"].nodes["1"],{text:"my-status"});
currentNodes["sn"].should.have.a.property("handled",0);
currentNodes["sn2"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn2"].messages[0];
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",0);
currentNodes["sn2"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn2"].messages[0];
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","my-status");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","1");
statusMessage.status.source.should.have.a.property("type","test");
statusMessage.status.source.should.have.a.property("name","a");
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","my-status");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","1");
statusMessage.status.source.should.have.a.property("type","test");
statusMessage.status.source.should.have.a.property("name","a");
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50);
});
});
@@ -636,33 +674,35 @@ describe('Flow', function() {
flow.handleError(config.flows["t1"].nodes["1"],"my-error",{a:"foo"});
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","1");
statusMessage.error.source.should.have.a.property("type","test");
statusMessage.error.source.should.have.a.property("name","a");
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","1");
statusMessage.error.source.should.have.a.property("type","test");
statusMessage.error.source.should.have.a.property("name","a");
currentNodes["sn2"].should.have.a.property("handled",1);
statusMessage = currentNodes["sn2"].messages[0];
currentNodes["sn2"].should.have.a.property("handled",1);
statusMessage = currentNodes["sn2"].messages[0];
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","1");
statusMessage.error.source.should.have.a.property("type","test");
statusMessage.error.source.should.have.a.property("name","a");
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","1");
statusMessage.error.source.should.have.a.property("type","test");
statusMessage.error.source.should.have.a.property("name","a");
// Node sn3 has uncaught:true - so should not get called
currentNodes["sn3"].should.have.a.property("handled",0);
// Node sn3 has uncaught:true - so should not get called
currentNodes["sn3"].should.have.a.property("handled",0);
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50);
});
it("passes an error event to the adjacent scoped catch node ",function(done) {
var config = flowUtils.parseConfig([
@@ -684,39 +724,42 @@ describe('Flow', function() {
flow.handleError(config.flows["t1"].nodes["1"],"my-error",{a:"foo"});
currentNodes["sn"].should.have.a.property("handled",0);
currentNodes["sn2"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn2"].messages[0];
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",0);
currentNodes["sn2"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn2"].messages[0];
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","1");
statusMessage.error.source.should.have.a.property("type","test");
statusMessage.error.source.should.have.a.property("name","a");
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","1");
statusMessage.error.source.should.have.a.property("type","test");
statusMessage.error.source.should.have.a.property("name","a");
// Node sn3/4 have uncaught:true - so should not get called
currentNodes["sn3"].should.have.a.property("handled",0);
currentNodes["sn4"].should.have.a.property("handled",0);
// Node sn3/4 have uncaught:true - so should not get called
currentNodes["sn3"].should.have.a.property("handled",0);
currentNodes["sn4"].should.have.a.property("handled",0);
// Inject error that sn1/2 will ignore - so should get picked up by sn3
flow.handleError(config.flows["t1"].nodes["3"],"my-error-2",{a:"foo-2"});
// Inject error that sn1/2 will ignore - so should get picked up by sn3
flow.handleError(config.flows["t1"].nodes["3"],"my-error-2",{a:"foo-2"});
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",0);
currentNodes["sn2"].should.have.a.property("handled",1);
currentNodes["sn3"].should.have.a.property("handled",1);
currentNodes["sn4"].should.have.a.property("handled",1);
currentNodes["sn"].should.have.a.property("handled",0);
currentNodes["sn2"].should.have.a.property("handled",1);
currentNodes["sn3"].should.have.a.property("handled",1);
currentNodes["sn4"].should.have.a.property("handled",1);
statusMessage = currentNodes["sn3"].messages[0];
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error-2");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","3");
statusMessage.error.source.should.have.a.property("type","test");
statusMessage = currentNodes["sn3"].messages[0];
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error-2");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","3");
statusMessage.error.source.should.have.a.property("type","test");
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50);
},50);
});
it("moves any existing error object sideways",function(done){
var config = flowUtils.parseConfig([
@@ -733,22 +776,54 @@ describe('Flow', function() {
var activeNodes = flow.getActiveNodes();
flow.handleError(config.flows["t1"].nodes["1"],"my-error",{a:"foo",error:"existing"});
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
statusMessage.should.have.a.property("_error","existing");
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","1");
statusMessage.error.source.should.have.a.property("type","test");
statusMessage.error.source.should.have.a.property("name","a");
statusMessage.should.have.a.property("_error","existing");
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","my-error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("id","1");
statusMessage.error.source.should.have.a.property("type","test");
statusMessage.error.source.should.have.a.property("name","a");
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50);
});
it("prevents an error looping more than 10 times",function(){});
});
describe("#handleComplete",function() {
it("passes a complete event to the adjacent Complete node",function(done) {
var config = flowUtils.parseConfig([
{id:"t1",type:"tab"},
{id:"1",x:10,y:10,z:"t1",type:"testDone",name:"a",wires:["2"]},
{id:"2",x:10,y:10,z:"t1",type:"test",wires:["3"]},
{id:"3",x:10,y:10,z:"t1",type:"testDone",foo:"a",wires:[]},
{id:"cn",x:10,y:10,z:"t1",type:"complete",scope:["1","3"],foo:"a",wires:[]}
]);
var flow = Flow.create({},config,config.flows["t1"]);
flow.start();
var activeNodes = flow.getActiveNodes();
Object.keys(activeNodes).should.have.length(4);
var msg = {payload: "hello world"}
var n1 = currentNodes["1"].receive(msg);
setTimeout(function() {
currentNodes["cn"].should.have.a.property("handled",2);
currentNodes["cn"].messages[0].should.have.a.property("handled",1);
currentNodes["cn"].messages[1].should.have.a.property("handled",2);
flow.stop().then(function() {
done();
});
},50);
});
});
});

View File

@@ -271,32 +271,34 @@ describe('Subflow', function() {
currentNodes["1"].receive({payload:"test"});
currentNodes["1"].should.have.a.property("handled",1);
// currentNodes[sfInstanceId].should.have.a.property("handled",1);
// currentNodes[sfInstanceId2].should.have.a.property("handled",1);
currentNodes["3"].should.have.a.property("handled",1);
currentNodes["4"].should.have.a.property("handled",1);
setTimeout(function() {
currentNodes["1"].should.have.a.property("handled",1);
// currentNodes[sfInstanceId].should.have.a.property("handled",1);
// currentNodes[sfInstanceId2].should.have.a.property("handled",1);
currentNodes["3"].should.have.a.property("handled",1);
currentNodes["4"].should.have.a.property("handled",1);
flow.stop().then(function() {
Object.keys(currentNodes).should.have.length(0);
Object.keys(stoppedNodes).should.have.length(6);
flow.stop().then(function() {
Object.keys(currentNodes).should.have.length(0);
Object.keys(stoppedNodes).should.have.length(6);
// currentNodes.should.not.have.a.property("1");
// currentNodes.should.not.have.a.property("3");
// currentNodes.should.not.have.a.property("4");
// // currentNodes.should.not.have.a.property(sfInstanceId);
// // currentNodes.should.not.have.a.property(sfInstanceId2);
// // currentNodes.should.not.have.a.property(sfConfigId);
// stoppedNodes.should.have.a.property("1");
// stoppedNodes.should.have.a.property("3");
// stoppedNodes.should.have.a.property("4");
// // stoppedNodes.should.have.a.property(sfInstanceId);
// // stoppedNodes.should.have.a.property(sfInstanceId2);
// // stoppedNodes.should.have.a.property(sfConfigId);
done();
});
// currentNodes.should.not.have.a.property("1");
// currentNodes.should.not.have.a.property("3");
// currentNodes.should.not.have.a.property("4");
// // currentNodes.should.not.have.a.property(sfInstanceId);
// // currentNodes.should.not.have.a.property(sfInstanceId2);
// // currentNodes.should.not.have.a.property(sfConfigId);
// stoppedNodes.should.have.a.property("1");
// stoppedNodes.should.have.a.property("3");
// stoppedNodes.should.have.a.property("4");
// // stoppedNodes.should.have.a.property(sfInstanceId);
// // stoppedNodes.should.have.a.property(sfInstanceId2);
// // stoppedNodes.should.have.a.property(sfConfigId);
done();
});
},50);
});
it("instantiates a subflow inside a subflow and stops it",function(done) {
var config = flowUtils.parseConfig([
@@ -322,17 +324,14 @@ describe('Subflow', function() {
currentNodes["1"].receive({payload:"test"});
currentNodes["1"].should.have.a.property("handled",1);
currentNodes["3"].should.have.a.property("handled",1);
flow.stop().then(function() {
Object.keys(currentNodes).should.have.length(0);
done();
});
setTimeout(function() {
currentNodes["1"].should.have.a.property("handled",1);
currentNodes["3"].should.have.a.property("handled",1);
flow.stop().then(function() {
Object.keys(currentNodes).should.have.length(0);
done();
});
},50);
});
it("rewires a subflow node on update/start",function(done){
@@ -369,27 +368,31 @@ describe('Subflow', function() {
currentNodes["1"].receive({payload:"test"});
currentNodes["1"].should.have.a.property("handled",1);
// currentNodes[sfInstanceId].should.have.a.property("handled",1);
// currentNodes[sfInstanceId2].should.have.a.property("handled",1);
currentNodes["3"].should.have.a.property("handled",1);
currentNodes["4"].should.have.a.property("handled",0);
setTimeout(function() {
currentNodes["1"].should.have.a.property("handled",1);
// currentNodes[sfInstanceId].should.have.a.property("handled",1);
// currentNodes[sfInstanceId2].should.have.a.property("handled",1);
currentNodes["3"].should.have.a.property("handled",1);
currentNodes["4"].should.have.a.property("handled",0);
flow.update(newConfig,newConfig.flows["t1"]);
flow.start(diff)
flow.update(newConfig,newConfig.flows["t1"]);
flow.start(diff)
currentNodes["1"].receive({payload:"test2"});
currentNodes["1"].receive({payload:"test2"});
setTimeout(function() {
currentNodes["1"].should.have.a.property("handled",2);
// currentNodes[sfInstanceId].should.have.a.property("handled",2);
// currentNodes[sfInstanceId2].should.have.a.property("handled",2);
currentNodes["3"].should.have.a.property("handled",1);
currentNodes["4"].should.have.a.property("handled",1);
currentNodes["1"].should.have.a.property("handled",2);
// currentNodes[sfInstanceId].should.have.a.property("handled",2);
// currentNodes[sfInstanceId2].should.have.a.property("handled",2);
currentNodes["3"].should.have.a.property("handled",1);
currentNodes["4"].should.have.a.property("handled",1);
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50);
},50);
});
});
describe('#stop', function() {
@@ -436,20 +439,20 @@ describe('Subflow', function() {
var activeNodes = flow.getActiveNodes();
activeNodes["1"].receive({payload:"test"});
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","test status");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("type","testStatus");
statusMessage.status.source.should.have.a.property("name","test-status-node");
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","test status");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("type","testStatus");
statusMessage.status.source.should.have.a.property("name","test-status-node");
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50);
});
it("passes a status event to the subflow's parent tab status node - targetted scope",function(done) {
var config = flowUtils.parseConfig([
@@ -472,21 +475,23 @@ describe('Subflow', function() {
activeNodes["1"].receive({payload:"test"});
parentFlowStatusCalled.should.be.false();
setTimeout(function() {
parentFlowStatusCalled.should.be.false();
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","test status");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("type","testStatus");
statusMessage.status.source.should.have.a.property("name","test-status-node");
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","test status");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("type","testStatus");
statusMessage.status.source.should.have.a.property("name","test-status-node");
flow.stop().then(function() {
flow.stop().then(function() {
done();
});
done();
});
},50);
});
});
@@ -517,19 +522,21 @@ describe('Subflow', function() {
activeNodes["1"].receive({payload:"test-payload"});
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","test-payload");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","2");
statusMessage.status.source.should.have.a.property("type","subflow:sf1");
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","test-payload");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","2");
statusMessage.status.source.should.have.a.property("type","subflow:sf1");
flow.stop().then(function() {
flow.stop().then(function() {
done();
});
done();
});
},50);
});
it("emits a status event when a message is passed to a subflow-status node - msg.payload as status obj", function(done) {
var config = flowUtils.parseConfig([
@@ -557,19 +564,21 @@ describe('Subflow', function() {
activeNodes["1"].receive({payload:{text:"payload-obj"}});
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","payload-obj");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","2");
statusMessage.status.source.should.have.a.property("type","subflow:sf1");
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","payload-obj");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","2");
statusMessage.status.source.should.have.a.property("type","subflow:sf1");
flow.stop().then(function() {
flow.stop().then(function() {
done();
});
done();
});
},50);
});
it("emits a status event when a message is passed to a subflow-status node - msg.status", function(done) {
var config = flowUtils.parseConfig([
@@ -597,19 +606,21 @@ describe('Subflow', function() {
activeNodes["1"].receive({status:{text:"status-obj"}});
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","status-obj");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","2");
statusMessage.status.source.should.have.a.property("type","subflow:sf1");
statusMessage.should.have.a.property("status");
statusMessage.status.should.have.a.property("text","status-obj");
statusMessage.status.should.have.a.property("source");
statusMessage.status.source.should.have.a.property("id","2");
statusMessage.status.source.should.have.a.property("type","subflow:sf1");
flow.stop().then(function() {
flow.stop().then(function() {
done();
});
done();
});
},50);
});
it("does not emit a regular status event if it contains a subflow-status node", function(done) {
var config = flowUtils.parseConfig([
@@ -666,18 +677,20 @@ describe('Subflow', function() {
activeNodes["1"].receive({payload:"test"});
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
setTimeout(function() {
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","test error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("type","testError");
statusMessage.error.source.should.have.a.property("name","test-error-node");
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","test error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("type","testError");
statusMessage.error.source.should.have.a.property("name","test-error-node");
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50);
});
it("passes an error event to the subflow's parent tab catch node - targetted scope",function(done) {
var config = flowUtils.parseConfig([
@@ -699,20 +712,22 @@ describe('Subflow', function() {
activeNodes["1"].receive({payload:"test"});
parentFlowErrorCalled.should.be.false();
setTimeout(function() {
parentFlowErrorCalled.should.be.false();
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
currentNodes["sn"].should.have.a.property("handled",1);
var statusMessage = currentNodes["sn"].messages[0];
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","test error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("type","testError");
statusMessage.error.source.should.have.a.property("name","test-error-node");
statusMessage.should.have.a.property("error");
statusMessage.error.should.have.a.property("message","test error");
statusMessage.error.should.have.a.property("source");
statusMessage.error.source.should.have.a.property("type","testError");
statusMessage.error.source.should.have.a.property("name","test-error-node");
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50);
});
});
@@ -756,11 +771,13 @@ describe('Subflow', function() {
process.env["__KEY__"] = "__VAL__";
currentNodes["1"].receive({payload: "test"});
currentNodes["3"].should.have.a.property("received", "__VAL__");
flow.stop().then(function() {
done();
});
setTimeout(function() {
currentNodes["3"].should.have.a.property("received", "__VAL__");
flow.stop().then(function() {
done();
});
},50);
});
it("can access subflow env var", function(done) {
@@ -792,13 +809,15 @@ describe('Subflow', function() {
}
process.env["__KEY__"] = "__VAL0__";
setEnv(testenv_node, "__KEY__", "__VAL1__");
currentNodes["1"].receive({payload: "test"});
currentNodes["3"].should.have.a.property("received", "__VAL1__");
flow.stop().then(function() {
done();
});
currentNodes["1"].receive({payload: "test"});
setTimeout(function() {
currentNodes["3"].should.have.a.property("received", "__VAL1__");
flow.stop().then(function() {
done();
});
},50);
});
it("can access nested subflow env var", function(done) {
@@ -840,21 +859,27 @@ describe('Subflow', function() {
process.env["__KEY__"] = "__VAL0__";
currentNodes["1"].receive({payload: "test"});
currentNodes["3"].should.have.a.property("received", "__VAL0__");
setTimeout(function() {
currentNodes["3"].should.have.a.property("received", "__VAL0__");
setEnv(node_sf1_1, "__KEY__", "__VAL1__");
currentNodes["1"].receive({payload: "test"});
currentNodes["3"].should.have.a.property("received", "__VAL1__");
setEnv(node_sf1_1, "__KEY__", "__VAL1__");
currentNodes["1"].receive({payload: "test"});
setTimeout(function() {
currentNodes["3"].should.have.a.property("received", "__VAL1__");
setEnv(node_sf2_1, "__KEY__", "__VAL2__");
currentNodes["1"].receive({payload: "test"});
currentNodes["3"].should.have.a.property("received", "__VAL2__");
setEnv(node_sf2_1, "__KEY__", "__VAL2__");
currentNodes["1"].receive({payload: "test"});
setTimeout(function() {
currentNodes["3"].should.have.a.property("received", "__VAL2__");
flow.stop().then(function() {
done();
});
flow.stop().then(function() {
done();
});
},50);
},50);
},50);
});
});
});