Merge branch 'master' into dev

This commit is contained in:
Nick O'Leary
2019-11-21 21:57:58 +00:00
59 changed files with 779 additions and 343 deletions

View File

@@ -61,7 +61,7 @@ exports.config = {
maxInstances: 2,
//
browserName: 'chrome',
chromeOptions: {
'goog:chromeOptions': {
args: process.env.NODE_RED_NON_HEADLESS
// Runs tests with opening a browser.
? ['--disable-gpu']
@@ -134,7 +134,7 @@ exports.config = {
// Services take over a specific job you don't want to take care of. They enhance
// your test setup with almost no effort. Unlike plugins, they don't add new
// commands. Instead, they hook themselves up into the test process.
port: '9515',
port: 9515,
path: '/',
services: ['chromedriver'],
//

View File

@@ -251,7 +251,8 @@ describe('delay Node', function() {
var helperNode1 = helper.getNode("helperNode1");
var receivedMessagesStack = [];
var rate = 1000/aLimit;
// Add a small grace to the calculated delay
var rate = 1000/aLimit + 10;
var receiveTimestamp;

View File

@@ -298,7 +298,7 @@ describe('Subflow', function() {
// // stoppedNodes.should.have.a.property(sfConfigId);
done();
});
},50);
},150);
});
it("instantiates a subflow inside a subflow and stops it",function(done) {
var config = flowUtils.parseConfig([
@@ -331,7 +331,7 @@ describe('Subflow', function() {
Object.keys(currentNodes).should.have.length(0);
done();
});
},50);
},150);
});
it("rewires a subflow node on update/start",function(done){
@@ -391,8 +391,8 @@ describe('Subflow', function() {
flow.stop().then(function() {
done();
});
},50);
},50);
},150);
},150);
});
});
describe('#stop', function() {
@@ -452,7 +452,7 @@ describe('Subflow', function() {
flow.stop().then(function() {
done();
});
},50);
},150);
});
it("passes a status event to the subflow's parent tab status node - targetted scope",function(done) {
var config = flowUtils.parseConfig([
@@ -491,7 +491,7 @@ describe('Subflow', function() {
done();
});
},50);
},150);
});
});
@@ -536,7 +536,7 @@ describe('Subflow', function() {
done();
});
},50);
},150);
});
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([
@@ -578,7 +578,7 @@ describe('Subflow', function() {
done();
});
},50);
},150);
});
it("emits a status event when a message is passed to a subflow-status node - msg.status", function(done) {
var config = flowUtils.parseConfig([
@@ -620,7 +620,7 @@ describe('Subflow', function() {
done();
});
},50);
},150);
});
it("does not emit a regular status event if it contains a subflow-status node", function(done) {
var config = flowUtils.parseConfig([
@@ -690,7 +690,7 @@ describe('Subflow', function() {
flow.stop().then(function() {
done();
});
},50);
},150);
});
it("passes an error event to the subflow's parent tab catch node - targetted scope",function(done) {
var config = flowUtils.parseConfig([
@@ -727,7 +727,7 @@ describe('Subflow', function() {
flow.stop().then(function() {
done();
});
},50);
},150);
});
});
@@ -777,7 +777,7 @@ describe('Subflow', function() {
flow.stop().then(function() {
done();
});
},50);
},150);
});
it("can access subflow env var", function(done) {
@@ -817,7 +817,7 @@ describe('Subflow', function() {
flow.stop().then(function() {
done();
});
},50);
},150);
});
it("can access nested subflow env var", function(done) {
@@ -875,9 +875,9 @@ describe('Subflow', function() {
flow.stop().then(function() {
done();
});
},50);
},50);
},50);
},150);
},150);
},150);
});
});

View File

@@ -19,6 +19,7 @@ var fs = require('fs-extra');
var path = require('path');
var sinon = require('sinon');
var NR_TEST_UTILS = require("nr-test-utils");
var process = require("process");
var localfilesystem = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem");
var log = NR_TEST_UTILS.require("@node-red/util").log;
@@ -474,4 +475,44 @@ describe('storage/localfilesystem', function() {
done(err);
});
});
it('should handle flow file in random unc path and non-existent subfolder',function(done) {
// only test on win32
if (process.platform !== 'win32') {
console.log('skipped test as not win32');
done();
return;
}
// get a real windows path
var flowFile = path.win32.resolve(userDir+'/some/random/path');
var rootdir = path.win32.resolve(userDir+'/some');
// make it into a local UNC path
flowFile = flowFile.replace('C:\\', '\\\\localhost\\c$\\');
localfilesystem.init({userDir:userDir, flowFile:flowFile}, mockRuntime).then(function() {
fs.existsSync(flowFile).should.be.false();
localfilesystem.saveFlows(testFlow).then(function() {
fs.existsSync(flowFile).should.be.true();
localfilesystem.getFlows().then(function(flows) {
flows.should.eql(testFlow);
// cleanup
fs.removeSync(rootdir);
done();
}).catch(function(err) {
// cleanup
fs.removeSync(rootdir);
done(err);
});
}).catch(function(err) {
// cleanup
fs.removeSync(rootdir);
done(err);
});
}).catch(function(err) {
// cleanup
fs.removeSync(rootdir);
done(err);
});
});
});

View File

@@ -224,5 +224,29 @@ describe("@node-red/util/log", function() {
});
it('it can log without exception', function() {
var msg = {
msg: {
mystrangeobj:"hello",
},
};
msg.msg.toString = function(){
throw new Error('Exception in toString - should have been caught');
}
msg.msg.constructor = { name: "strangeobj" };
var ret = log.info(msg.msg);
});
it('it can log an object but use .message', function() {
var msg = {
msg: {
message: "my special message",
mystrangeobj:"hello",
},
};
var ret = log.info(msg.msg);
sinon.assert.calledWithMatch(util.log,"my special message");
});
});

View File

@@ -772,6 +772,117 @@ describe("@node-red/util/util", function() {
var resultJson = JSON.parse(result.msg);
resultJson.socket.should.eql('[internal]');
});
it('object which fails to serialise', function(done) {
var msg = {
msg: {
obj:{
cantserialise:{
message:'this will not be displayed',
toJSON: function(val) {
throw 'this exception should have been caught';
return 'should not display because we threw first';
},
},
canserialise:{
message:'this should be displayed',
}
},
}
};
var result = util.encodeObject(msg);
result.format.should.eql("error");
var success = (result.msg.indexOf('cantserialise') > 0);
success &= (result.msg.indexOf('this exception should have been caught') > 0);
success &= (result.msg.indexOf('canserialise') > 0);
success.should.eql(1);
done();
});
it('object which fails to serialise - different error type', function(done) {
var msg = {
msg: {
obj:{
cantserialise:{
message:'this will not be displayed',
toJSON: function(val) {
throw new Error('this exception should have been caught');
return 'should not display because we threw first';
},
},
canserialise:{
message:'this should be displayed',
}
},
}
};
var result = util.encodeObject(msg);
result.format.should.eql("error");
var success = (result.msg.indexOf('cantserialise') > 0);
success &= (result.msg.indexOf('this exception should have been caught') > 0);
success &= (result.msg.indexOf('canserialise') > 0);
success.should.eql(1);
done();
});
it('very large object which fails to serialise should be truncated', function(done) {
var msg = {
msg: {
obj:{
big:"",
cantserialise:{
message:'this will not be displayed',
toJSON: function(val) {
throw new Error('this exception should have been caught');
return 'should not display because we threw first';
},
},
canserialise:{
message:'this should be displayed',
}
},
}
};
for (var i = 0; i < 1000; i++) {
msg.msg.obj.big += 'some more string ';
}
var result = util.encodeObject(msg);
result.format.should.eql("error");
var resultJson = JSON.parse(result.msg);
var success = (resultJson.message.length <= 1000);
success.should.eql(true);
done();
});
it('test bad toString', function(done) {
var msg = {
msg: {
mystrangeobj:"hello",
},
};
msg.msg.toString = function(){
throw new Error('Exception in toString - should have been caught');
}
msg.msg.constructor = { name: "strangeobj" };
var result = util.encodeObject(msg);
var success = (result.msg.indexOf('[Type not printable]') >= 0);
success.should.eql(true);
done();
});
it('test bad object constructor', function(done) {
var msg = {
msg: {
mystrangeobj:"hello",
constructor: {
get name(){
throw new Error('Exception in constructor name');
}
}
},
};
var result = util.encodeObject(msg);
done();
});
});
});
});