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

Handle missing tab nodes in a loaded flow config

This commit is contained in:
Nick O'Leary 2016-05-04 22:09:11 +01:00
parent 41445a1b48
commit 337f5f9b98
2 changed files with 47 additions and 23 deletions

View File

@ -102,6 +102,7 @@ module.exports = {
} }
} }
}); });
var addedTabs = {};
config.forEach(function(n) { config.forEach(function(n) {
if (n.type !== 'subflow' && n.type !== 'tab') { if (n.type !== 'subflow' && n.type !== 'tab') {
for (var prop in n) { for (var prop in n) {
@ -110,9 +111,25 @@ module.exports = {
flow.configs[n[prop]]._users.push(n.id) flow.configs[n[prop]]._users.push(n.id)
} }
} }
if (n.z && !flow.subflows[n.z]) {
if (!flow.flows[n.z]) {
flow.flows[n.z] = {type:'tab',id:n.z};
flow.flows[n.z].subflows = {};
flow.flows[n.z].configs = {};
flow.flows[n.z].nodes = {};
addedTabs[n.z] = flow.flows[n.z];
}
if (addedTabs[n.z]) {
if (n.hasOwnProperty('x') && n.hasOwnProperty('y')) {
addedTabs[n.z].nodes[n.id] = n;
} else {
addedTabs[n.z].configs[n.id] = n;
}
}
}
} }
}); });
return flow; return flow;
}, },

View File

@ -38,42 +38,42 @@ describe('flows/util', function() {
describe('#diffNodes',function() { describe('#diffNodes',function() {
it('handles a null old node', function() { it('handles a null old node', function() {
flowUtil.diffNodes(null,{}).should.be.true; flowUtil.diffNodes(null,{}).should.be.true();
}); });
it('ignores x/y changes', function() { it('ignores x/y changes', function() {
flowUtil.diffNodes({x:10,y:10},{x:20,y:10}).should.be.false; flowUtil.diffNodes({x:10,y:10},{x:20,y:10}).should.be.false();
flowUtil.diffNodes({x:10,y:10},{x:10,y:20}).should.be.false; flowUtil.diffNodes({x:10,y:10},{x:10,y:20}).should.be.false();
}); });
it('ignores wiring changes', function() { it('ignores wiring changes', function() {
flowUtil.diffNodes({wires:[]},{wires:[1,2,3]}).should.be.false; flowUtil.diffNodes({wires:[]},{wires:[1,2,3]}).should.be.false();
}); });
it('spots existing property change - string', function() { it('spots existing property change - string', function() {
flowUtil.diffNodes({a:"foo"},{a:"bar"}).should.be.true; flowUtil.diffNodes({a:"foo"},{a:"bar"}).should.be.true();
}); });
it('spots existing property change - number', function() { it('spots existing property change - number', function() {
flowUtil.diffNodes({a:0},{a:1}).should.be.true; flowUtil.diffNodes({a:0},{a:1}).should.be.true();
}); });
it('spots existing property change - boolean', function() { it('spots existing property change - boolean', function() {
flowUtil.diffNodes({a:true},{a:false}).should.be.true; flowUtil.diffNodes({a:true},{a:false}).should.be.true();
}); });
it('spots existing property change - truthy', function() { it('spots existing property change - truthy', function() {
flowUtil.diffNodes({a:true},{a:1}).should.be.true; flowUtil.diffNodes({a:true},{a:1}).should.be.true();
}); });
it('spots existing property change - falsey', function() { it('spots existing property change - falsey', function() {
flowUtil.diffNodes({a:false},{a:0}).should.be.true; flowUtil.diffNodes({a:false},{a:0}).should.be.true();
}); });
it('spots existing property change - array', function() { it('spots existing property change - array', function() {
flowUtil.diffNodes({a:[0,1,2]},{a:[0,2,3]}).should.be.true; flowUtil.diffNodes({a:[0,1,2]},{a:[0,2,3]}).should.be.true();
}); });
it('spots existing property change - object', function() { it('spots existing property change - object', function() {
flowUtil.diffNodes({a:{a:[0,1,2]}},{a:{a:[0,2,3]}}).should.be.true; flowUtil.diffNodes({a:{a:[0,1,2]}},{a:{a:[0,2,3]}}).should.be.true();
flowUtil.diffNodes({a:{a:[0,1,2]}},{a:{b:[0,1,2]}}).should.be.true; flowUtil.diffNodes({a:{a:[0,1,2]}},{a:{b:[0,1,2]}}).should.be.true();
}); });
it('spots added property', function() { it('spots added property', function() {
flowUtil.diffNodes({a:"foo"},{a:"foo",b:"bar"}).should.be.true; flowUtil.diffNodes({a:"foo"},{a:"foo",b:"bar"}).should.be.true();
}); });
it('spots removed property', function() { it('spots removed property', function() {
flowUtil.diffNodes({a:"foo",b:"bar"},{a:"foo"}).should.be.true; flowUtil.diffNodes({a:"foo",b:"bar"},{a:"foo"}).should.be.true();
}); });
@ -88,8 +88,7 @@ describe('flows/util', function() {
]; ];
var parsedConfig = flowUtil.parseConfig(originalConfig); var parsedConfig = flowUtil.parseConfig(originalConfig);
var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}}},"missingTypes":[]}; var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}}},"missingTypes":[]};
parsedConfig.should.eql(expectedConfig);
redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true;
}); });
it('parses a single-tab flow with global config node', function() { it('parses a single-tab flow with global config node', function() {
@ -100,7 +99,7 @@ describe('flows/util', function() {
]; ];
var parsedConfig = flowUtil.parseConfig(originalConfig); var parsedConfig = flowUtil.parseConfig(originalConfig);
var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]},"cn":{"id":"cn","type":"test"},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{"cn":{"id":"cn","type":"test","_users":["t1-1"]}},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]}}}},"missingTypes":[]}; var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]},"cn":{"id":"cn","type":"test"},"t1":{"id":"t1","type":"tab"}},"subflows":{},"configs":{"cn":{"id":"cn","type":"test","_users":["t1-1"]}},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]}}}},"missingTypes":[]};
redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true; parsedConfig.should.eql(expectedConfig);
}); });
it('parses a multi-tab flow', function() { it('parses a multi-tab flow', function() {
@ -112,8 +111,7 @@ describe('flows/util', function() {
]; ];
var parsedConfig = flowUtil.parseConfig(originalConfig); var parsedConfig = flowUtil.parseConfig(originalConfig);
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t2":{"id":"t2","type":"tab"},"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}},"t2":{"id":"t2","type":"tab","subflows":{},"configs":{},"nodes":{"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}}}},"missingTypes":[]}; var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]},"t2":{"id":"t2","type":"tab"},"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","wires":[]}}},"t2":{"id":"t2","type":"tab","subflows":{},"configs":{},"nodes":{"t2-1":{"id":"t2-1","x":10,"y":10,"z":"t2","type":"test","wires":[]}}}},"missingTypes":[]};
parsedConfig.should.eql(expectedConfig);
redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true;
}); });
it('parses a subflow flow', function() { it('parses a subflow flow', function() {
@ -125,8 +123,7 @@ describe('flows/util', function() {
]; ];
var parsedConfig = flowUtil.parseConfig(originalConfig); var parsedConfig = flowUtil.parseConfig(originalConfig);
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[]},"sf1":{"id":"sf1","type":"subflow"},"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"subflows":{"sf1":{"id":"sf1","type":"subflow","configs":{},"nodes":{"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"instances":[{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}]}},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}}}},"missingTypes":[]}; var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[]},"sf1":{"id":"sf1","type":"subflow"},"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"subflows":{"sf1":{"id":"sf1","type":"subflow","configs":{},"nodes":{"sf1-1":{"id":"sf1-1","x":10,"y":10,"z":"sf1","type":"test","wires":[]}},"instances":[{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}]}},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"subflow:sf1","wires":[],"subflow":"sf1"}}}},"missingTypes":[]};
parsedConfig.should.eql(expectedConfig);
redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true;
}); });
it('parses a flow with a missing type', function() { it('parses a flow with a missing type', function() {
@ -138,7 +135,17 @@ describe('flows/util', function() {
var parsedConfig = flowUtil.parseConfig(originalConfig); var parsedConfig = flowUtil.parseConfig(originalConfig);
parsedConfig.missingTypes.should.eql(['missing']); parsedConfig.missingTypes.should.eql(['missing']);
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},"t1-2":{"id":"t1-2","x":10,"y":10,"z":"t1","type":"missing","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},'t1-2': { id: 't1-2', x: 10, y: 10, z: 't1', type: 'missing', wires: [] }}}},"missingTypes":["missing"]}; var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},"t1-2":{"id":"t1-2","x":10,"y":10,"z":"t1","type":"missing","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},'t1-2': { id: 't1-2', x: 10, y: 10, z: 't1', type: 'missing', wires: [] }}}},"missingTypes":["missing"]};
redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true; redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true();
});
it('parses a flow with a missing flow', function() {
var originalConfig = [
{id:"t1-1",x:10,y:10,z:"t1",type:"test",foo:"cn", wires:[]},
{id:"cn",type:"test"},
];
var parsedConfig = flowUtil.parseConfig(originalConfig);
var expectedConfig = {"allNodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]},"cn":{"id":"cn","type":"test"}},"subflows":{},"configs":{"cn":{"id":"cn","type":"test","_users":["t1-1"]}},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"test","foo":"cn","wires":[]}}}},"missingTypes":[]};
parsedConfig.should.eql(expectedConfig);
}); });