mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge branch 'master' into dev
This commit is contained in:
@@ -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'],
|
||||
//
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -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");
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
@@ -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();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user