diff --git a/red/nodes/registry.js b/red/nodes/registry.js deleted file mode 100644 index fdc47d488..000000000 --- a/red/nodes/registry.js +++ /dev/null @@ -1,850 +0,0 @@ -/** - * Copyright 2014, 2015 IBM Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -var util = require("util"); -var when = require("when"); -var whenNode = require('when/node'); -var fs = require("fs"); -var path = require("path"); -var crypto = require("crypto"); -var UglifyJS = require("uglify-js"); - -var events = require("../events"); - -var Node; -var settings; - -function filterNodeInfo(n) { - var r = { - id: n.id, - name: n.name, - types: n.types, - enabled: n.enabled - }; - if (n.hasOwnProperty("module")) { - r.module = n.module; - } - if (n.hasOwnProperty("err")) { - r.err = n.err.toString(); - } - return r; -} - -function getModule(id) { - return id.split("/")[0]; -} - -function getNode(id) { - return id.split("/")[1]; -} - -var registry = (function() { - var nodeConfigCache = null; - var moduleConfigs = {}; - var nodeList = []; - var nodeConstructors = {}; - var nodeTypeToId = {}; - var moduleNodes = {}; - - function saveNodeList() { - var moduleList = {}; - - for (var module in moduleConfigs) { - /* istanbul ignore else */ - if (moduleConfigs.hasOwnProperty(module)) { - if (Object.keys(moduleConfigs[module].nodes).length > 0) { - if (!moduleList[module]) { - moduleList[module] = { - name: module, - version: moduleConfigs[module].version, - nodes: {} - }; - } - var nodes = moduleConfigs[module].nodes; - for(var node in nodes) { - /* istanbul ignore else */ - if (nodes.hasOwnProperty(node)) { - var config = nodes[node]; - var n = filterNodeInfo(config); - delete n.err; - delete n.file; - delete n.id; - n.file = config.file; - moduleList[module].nodes[node] = n; - } - } - } - } - } - if (settings.available()) { - return settings.set("nodes",moduleList); - } else { - return when.reject("Settings unavailable"); - } - } - - function loadNodeConfigs() { - var configs = settings.get("nodes"); - - if (!configs) { - return {}; - } else if (configs['node-red']) { - return configs; - } else { - // Migrate from the 0.9.1 format of settings - var newConfigs = {}; - for (var id in configs) { - /* istanbul ignore else */ - if (configs.hasOwnProperty(id)) { - var nodeConfig = configs[id]; - var moduleName; - var nodeSetName; - - if (nodeConfig.module) { - moduleName = nodeConfig.module; - nodeSetName = nodeConfig.name.split(":")[1]; - } else { - moduleName = "node-red"; - nodeSetName = nodeConfig.name.replace(/^\d+-/,"").replace(/\.js$/,""); - } - - if (!newConfigs[moduleName]) { - newConfigs[moduleName] = { - name: moduleName, - nodes:{} - }; - } - newConfigs[moduleName].nodes[nodeSetName] = { - name: nodeSetName, - types: nodeConfig.types, - enabled: nodeConfig.enabled, - module: moduleName - }; - } - } - settings.set("nodes",newConfigs); - return newConfigs; - } - } - - return { - init: function() { - if (settings.available()) { - moduleConfigs = loadNodeConfigs(); - } else { - moduleConfigs = {}; - } - moduleNodes = {}; - nodeTypeToId = {}; - nodeConstructors = {}; - nodeList = []; - nodeConfigCache = null; - }, - addNodeSet: function(id,set,version) { - if (!set.err) { - set.types.forEach(function(t) { - nodeTypeToId[t] = id; - }); - } - - moduleNodes[set.module] = moduleNodes[set.module]||[]; - moduleNodes[set.module].push(set.name); - - if (!moduleConfigs[set.module]) { - moduleConfigs[set.module] = { - name: set.module, - nodes: {} - }; - } - - if (version) { - moduleConfigs[set.module].version = version; - } - - moduleConfigs[set.module].nodes[set.name] = set; - nodeList.push(id); - nodeConfigCache = null; - }, - removeNode: function(id) { - var config = moduleConfigs[getModule(id)].nodes[getNode(id)]; - if (!config) { - throw new Error("Unrecognised id: "+id); - } - delete moduleConfigs[getModule(id)].nodes[getNode(id)]; - var i = nodeList.indexOf(id); - if (i > -1) { - nodeList.splice(i,1); - } - config.types.forEach(function(t) { - delete nodeConstructors[t]; - delete nodeTypeToId[t]; - }); - config.enabled = false; - config.loaded = false; - nodeConfigCache = null; - return filterNodeInfo(config); - }, - removeModule: function(module) { - if (!settings.available()) { - throw new Error("Settings unavailable"); - } - var nodes = moduleNodes[module]; - if (!nodes) { - throw new Error("Unrecognised module: "+module); - } - var infoList = []; - for (var i=0;i 0) { - // result += ''; - //} - nodeConfigCache = result; - } - return nodeConfigCache; - }, - - getNodeConfig: function(id) { - var config = moduleConfigs[getModule(id)]; - if (!config) { - return null; - } - config = config.nodes[getNode(id)]; - if (config) { - var result = config.config; - //if (config.script) { - // result += ''; - //} - return result; - } else { - return null; - } - }, - - getNodeConstructor: function(type) { - var id = nodeTypeToId[type]; - - var config; - if (typeof id === "undefined") { - config = undefined; - } else { - config = moduleConfigs[getModule(id)].nodes[getNode(id)]; - } - - if (!config || (config.enabled && !config.err)) { - return nodeConstructors[type]; - } - return null; - }, - - clear: function() { - nodeConfigCache = null; - moduleConfigs = {}; - nodeList = []; - nodeConstructors = {}; - nodeTypeToId = {}; - }, - - getTypeId: function(type) { - return nodeTypeToId[type]; - }, - - enableNodeSet: function(typeOrId) { - if (!settings.available()) { - throw new Error("Settings unavailable"); - } - - var id = typeOrId; - if (nodeTypeToId[typeOrId]) { - id = nodeTypeToId[typeOrId]; - } - - var config; - try { - config = moduleConfigs[getModule(id)].nodes[getNode(id)]; - delete config.err; - config.enabled = true; - if (!config.loaded) { - // TODO: honour the promise this returns - loadNodeModule(config); - } - nodeConfigCache = null; - saveNodeList(); - } catch (err) { - throw new Error("Unrecognised id: "+typeOrId); - } - return filterNodeInfo(config); - }, - - disableNodeSet: function(typeOrId) { - if (!settings.available()) { - throw new Error("Settings unavailable"); - } - var id = typeOrId; - if (nodeTypeToId[typeOrId]) { - id = nodeTypeToId[typeOrId]; - } - var config; - try { - config = moduleConfigs[getModule(id)].nodes[getNode(id)]; - // TODO: persist setting - config.enabled = false; - nodeConfigCache = null; - saveNodeList(); - } catch (err) { - throw new Error("Unrecognised id: "+id); - } - return filterNodeInfo(config); - }, - - saveNodeList: saveNodeList, - - cleanModuleList: function() { - var removed = false; - for (var mod in moduleConfigs) { - /* istanbul ignore else */ - if (moduleConfigs.hasOwnProperty(mod)) { - var nodes = moduleConfigs[mod].nodes; - var node; - if (mod == "node-red") { - // For core nodes, look for nodes that are enabled, !loaded and !errored - for (node in nodes) { - /* istanbul ignore else */ - if (nodes.hasOwnProperty(node)) { - var n = nodes[node]; - if (n.enabled && !n.err && !n.loaded) { - registry.removeNode(mod+"/"+node); - removed = true; - } - } - } - } else if (moduleConfigs[mod] && !moduleNodes[mod]) { - // For node modules, look for missing ones - for (node in nodes) { - /* istanbul ignore else */ - if (nodes.hasOwnProperty(node)) { - registry.removeNode(mod+"/"+node); - removed = true; - } - } - delete moduleConfigs[mod]; - } - } - } - if (removed) { - saveNodeList(); - } - } - }; -})(); - - - -function init(_settings) { - Node = require("./Node"); - settings = _settings; - registry.init(); -} - -/** - * Synchronously walks the directory looking for node files. - * Emits 'node-icon-dir' events for an icon dirs found - * @param dir the directory to search - * @return an array of fully-qualified paths to .js files - */ -function getNodeFiles(dir) { - var result = []; - var files = []; - try { - files = fs.readdirSync(dir); - } catch(err) { - return result; - } - files.sort(); - files.forEach(function(fn) { - var stats = fs.statSync(path.join(dir,fn)); - if (stats.isFile()) { - if (/\.js$/.test(fn)) { - var valid = true; - if (settings.nodesExcludes) { - for (var i=0;i]*)data-template-name=['"]([^'"]*)['"]/gi; - var match = null; - - while((match = regExp.exec(content)) !== null) { - types.push(match[2]); - } - node.types = types; - node.config = content; - - // TODO: parse out the javascript portion of the template - //node.script = ""; - for (var i=0;i]*)data-template-name=['"]([^'"]*)['"]/gi; + var match = null; + + while((match = regExp.exec(content)) !== null) { + types.push(match[2]); + } + node.types = types; + node.config = content; + + // TODO: parse out the javascript portion of the template + //node.script = ""; + for (var i=0;i 0) { + if (!moduleList[module]) { + moduleList[module] = { + name: module, + version: moduleConfigs[module].version, + nodes: {} + }; + } + var nodes = moduleConfigs[module].nodes; + for(var node in nodes) { + /* istanbul ignore else */ + if (nodes.hasOwnProperty(node)) { + var config = nodes[node]; + var n = filterNodeInfo(config); + delete n.err; + delete n.file; + delete n.id; + n.file = config.file; + moduleList[module].nodes[node] = n; + } + } + } + } + } + if (settings.available()) { + return settings.set("nodes",moduleList); + } else { + return when.reject("Settings unavailable"); + } +} + +function loadNodeConfigs() { + var configs = settings.get("nodes"); + + if (!configs) { + return {}; + } else if (configs['node-red']) { + return configs; + } else { + // Migrate from the 0.9.1 format of settings + var newConfigs = {}; + for (var id in configs) { + /* istanbul ignore else */ + if (configs.hasOwnProperty(id)) { + var nodeConfig = configs[id]; + var moduleName; + var nodeSetName; + + if (nodeConfig.module) { + moduleName = nodeConfig.module; + nodeSetName = nodeConfig.name.split(":")[1]; + } else { + moduleName = "node-red"; + nodeSetName = nodeConfig.name.replace(/^\d+-/,"").replace(/\.js$/,""); + } + + if (!newConfigs[moduleName]) { + newConfigs[moduleName] = { + name: moduleName, + nodes:{} + }; + } + newConfigs[moduleName].nodes[nodeSetName] = { + name: nodeSetName, + types: nodeConfig.types, + enabled: nodeConfig.enabled, + module: moduleName + }; + } + } + settings.set("nodes",newConfigs); + return newConfigs; + } +} + +function addNodeSet(id,set,version) { + if (!set.err) { + set.types.forEach(function(t) { + nodeTypeToId[t] = id; + }); + } + + moduleNodes[set.module] = moduleNodes[set.module]||[]; + moduleNodes[set.module].push(set.name); + + if (!moduleConfigs[set.module]) { + moduleConfigs[set.module] = { + name: set.module, + nodes: {} + }; + } + + if (version) { + moduleConfigs[set.module].version = version; + } + + moduleConfigs[set.module].nodes[set.name] = set; + nodeList.push(id); + nodeConfigCache = null; +} + +function removeNode(id) { + var config = moduleConfigs[getModule(id)].nodes[getNode(id)]; + if (!config) { + throw new Error("Unrecognised id: "+id); + } + delete moduleConfigs[getModule(id)].nodes[getNode(id)]; + var i = nodeList.indexOf(id); + if (i > -1) { + nodeList.splice(i,1); + } + config.types.forEach(function(t) { + delete nodeConstructors[t]; + delete nodeTypeToId[t]; + }); + config.enabled = false; + config.loaded = false; + nodeConfigCache = null; + return filterNodeInfo(config); +} + +function removeModule(module) { + if (!settings.available()) { + throw new Error("Settings unavailable"); + } + var nodes = moduleNodes[module]; + if (!nodes) { + throw new Error("Unrecognised module: "+module); + } + var infoList = []; + for (var i=0;i 0) { + // result += ''; + //} + nodeConfigCache = result; + } + return nodeConfigCache; +} + +function getNodeConfig(id) { + var config = moduleConfigs[getModule(id)]; + if (!config) { + return null; + } + config = config.nodes[getNode(id)]; + if (config) { + var result = config.config; + //if (config.script) { + // result += ''; + //} + return result; + } else { + return null; + } +} + +function getNodeConstructor(type) { + var id = nodeTypeToId[type]; + + var config; + if (typeof id === "undefined") { + config = undefined; + } else { + config = moduleConfigs[getModule(id)].nodes[getNode(id)]; + } + + if (!config || (config.enabled && !config.err)) { + return nodeConstructors[type]; + } + return null; +} + +function clear() { + nodeConfigCache = null; + moduleConfigs = {}; + nodeList = []; + nodeConstructors = {}; + nodeTypeToId = {}; +} + +function getTypeId(type) { + return nodeTypeToId[type]; +} + +function enableNodeSet(typeOrId) { + if (!settings.available()) { + throw new Error("Settings unavailable"); + } + + var id = typeOrId; + if (nodeTypeToId[typeOrId]) { + id = nodeTypeToId[typeOrId]; + } + + var config; + try { + config = moduleConfigs[getModule(id)].nodes[getNode(id)]; + delete config.err; + config.enabled = true; + //if (!config.loaded) { + // // TODO: honour the promise this returns + // loadNodeModule(config); + //} + nodeConfigCache = null; + saveNodeList(); + } catch (err) { + throw new Error("Unrecognised id: "+typeOrId); + } + return filterNodeInfo(config); +} + +function disableNodeSet(typeOrId) { + if (!settings.available()) { + throw new Error("Settings unavailable"); + } + var id = typeOrId; + if (nodeTypeToId[typeOrId]) { + id = nodeTypeToId[typeOrId]; + } + var config; + try { + config = moduleConfigs[getModule(id)].nodes[getNode(id)]; + // TODO: persist setting + config.enabled = false; + nodeConfigCache = null; + saveNodeList(); + } catch (err) { + throw new Error("Unrecognised id: "+id); + } + return filterNodeInfo(config); +} + +function cleanModuleList() { + var removed = false; + for (var mod in moduleConfigs) { + /* istanbul ignore else */ + if (moduleConfigs.hasOwnProperty(mod)) { + var nodes = moduleConfigs[mod].nodes; + var node; + if (mod == "node-red") { + // For core nodes, look for nodes that are enabled, !loaded and !errored + for (node in nodes) { + /* istanbul ignore else */ + if (nodes.hasOwnProperty(node)) { + var n = nodes[node]; + if (n.enabled && !n.err && !n.loaded) { + removeNode(mod+"/"+node); + removed = true; + } + } + } + } else if (moduleConfigs[mod] && !moduleNodes[mod]) { + // For node modules, look for missing ones + for (node in nodes) { + /* istanbul ignore else */ + if (nodes.hasOwnProperty(node)) { + removeNode(mod+"/"+node); + removed = true; + } + } + delete moduleConfigs[mod]; + } + } + } + if (removed) { + saveNodeList(); + } +} + +var registry = module.exports = { + init: init, + clear: clear, + + registerNodeConstructor: registerNodeConstructor, + getNodeConstructor: getNodeConstructor, + + addNodeSet: addNodeSet, + enableNodeSet: enableNodeSet, + disableNodeSet: disableNodeSet, + + removeModule: removeModule, + + getNodeInfo: getNodeInfo, + getNodeList: getNodeList, + getModuleList: getModuleList, + getModuleInfo: getModuleInfo, + + /** + * Gets all of the node template configs + * @return all of the node templates in a single string + */ + getAllNodeConfigs: getAllNodeConfigs, + getNodeConfig: getNodeConfig, + + getTypeId: getTypeId, + + saveNodeList: saveNodeList, + + cleanModuleList: cleanModuleList +}; diff --git a/red/server.js b/red/server.js index 773dd2075..cbdaf3af6 100644 --- a/red/server.js +++ b/red/server.js @@ -64,6 +64,7 @@ function start() { log.info("Loading palette nodes"); redNodes.init(settings,storage,app); redNodes.load().then(function() { + var i; var nodeErrors = redNodes.getNodeList(function(n) { return n.err!=null;}); var nodeMissing = redNodes.getNodeList(function(n) { return n.module && n.enabled && !n.loaded && !n.err;}); diff --git a/test/red/nodes/registry_spec.js b/test/red/nodes/registry/index_spec.js similarity index 94% rename from test/red/nodes/registry_spec.js rename to test/red/nodes/registry/index_spec.js index b1c0f092c..9be323a39 100644 --- a/test/red/nodes/registry_spec.js +++ b/test/red/nodes/registry/index_spec.js @@ -19,18 +19,17 @@ var sinon = require("sinon"); var path = require("path"); var when = require("when"); -var RedNodes = require("../../../red/nodes"); -var RedNode = require("../../../red/nodes/Node"); -var typeRegistry = require("../../../red/nodes/registry"); -var events = require("../../../red/events"); +var RedNodes = require("../../../../red/nodes"); +var RedNode = require("../../../../red/nodes/Node"); +var typeRegistry = require("../../../../red/nodes/registry"); +var events = require("../../../../red/events"); afterEach(function() { typeRegistry.clear(); }); -describe('red/nodes/registry', function() { - - var resourcesDir = __dirname+ path.sep + "resources" + path.sep; +describe('red/nodes/registry/index', function() { + var resourcesDir = path.join(__dirname,"..","resources",path.sep); function stubSettings(s,available,initialConfig) { s.available = function() {return available;}; @@ -40,52 +39,7 @@ describe('red/nodes/registry', function() { } var settings = stubSettings({},false,null); var settingsWithStorage = stubSettings({},true,null); - var settingsWithStorageAndInitialConfig = stubSettings({},true,{"node-red":{module:"testModule",name:"testName",version:"testVersion",nodes:{"node":{id:"node-red/testName",name:"test",types:["a","b"],enabled:true}}}}); - it('loads initial config', function(done) { - typeRegistry.init(settingsWithStorageAndInitialConfig); - typeRegistry.getNodeList().should.have.lengthOf(1); - done(); - }); - - it('migrates legacy format', function(done) { - var settings = { - available: function() { return true; }, - set: sinon.stub().returns(when.resolve()), - get: function() { return { - "123": { - "name": "72-sentiment.js", - "types": [ - "sentiment" - ], - "enabled": true - }, - "456": { - "name": "20-inject.js", - "types": [ - "inject" - ], - "enabled": true - }, - "789": { - "name": "testModule:a-module.js", - "types": [ - "example" - ], - "enabled":true, - "module":"testModule" - } - }} - }; - var expected = JSON.parse('{"node-red":{"name":"node-red","nodes":{"sentiment":{"name":"sentiment","types":["sentiment"],"enabled":true,"module":"node-red"},"inject":{"name":"inject","types":["inject"],"enabled":true,"module":"node-red"}}},"testModule":{"name":"testModule","nodes":{"a-module.js":{"name":"a-module.js","types":["example"],"enabled":true,"module":"testModule"}}}}'); - typeRegistry.init(settings); - settings.set.calledOnce.should.be.true; - settings.set.args[0][1].should.eql(expected); - done(); - - - }); - it('handles nodes that export a function', function(done) { typeRegistry.init(settings); typeRegistry.load(resourcesDir + "TestNode1",true).then(function() { @@ -376,7 +330,6 @@ describe('red/nodes/registry', function() { }).finally(function() { settingsSave.restore(); }); - }); it('returns node info by type or id', function(done) { diff --git a/test/red/nodes/registry/loader_spec.js b/test/red/nodes/registry/loader_spec.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/red/nodes/registry/localfilesystem_spec.js b/test/red/nodes/registry/localfilesystem_spec.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/red/nodes/registry/registry_spec.js b/test/red/nodes/registry/registry_spec.js new file mode 100644 index 000000000..1aac149c2 --- /dev/null +++ b/test/red/nodes/registry/registry_spec.js @@ -0,0 +1,188 @@ +/** + * Copyright 2015 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var when = require("when"); +var sinon = require("sinon"); + +var typeRegistry = require("../../../../red/nodes/registry/registry"); + +describe("red/nodes/registry/registry",function() { + + beforeEach(function() { + typeRegistry.clear(); + }); + + function stubSettings(s,available,initialConfig) { + s.available = function() {return available;}; + s.set = function(s,v) { return when.resolve();}; + s.get = function(s) { return initialConfig;}; + return s; + } + + var settings = stubSettings({},false,null); + var settingsWithStorageAndInitialConfig = stubSettings({},true,{"node-red":{module:"testModule",name:"testName",version:"testVersion",nodes:{"node":{id:"node-red/testName",name:"test",types:["a","b"],enabled:true}}}}); + + var testNodeSet1 = { + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + types: [ "test-a","test-b"] + }; + + var testNodeSet2 = { + id: "test-module/test-name-2", + module: "test-module", + name: "test-name-2", + enabled: true, + loaded: false, + types: [ "test-c","test-d"] + }; + var testNodeSet2WithError = { + id: "test-module/test-name-2", + module: "test-module", + name: "test-name-2", + enabled: true, + loaded: false, + err: "I have an error", + types: [ "test-c","test-d"] + }; + + + + + describe('#init', function() { + it('loads initial config', function(done) { + typeRegistry.init(settingsWithStorageAndInitialConfig); + typeRegistry.getNodeList().should.have.lengthOf(1); + done(); + }); + + it('migrates legacy format', function(done) { + var legacySettings = { + available: function() { return true; }, + set: sinon.stub().returns(when.resolve()), + get: function() { return { + "123": { + "name": "72-sentiment.js", + "types": [ + "sentiment" + ], + "enabled": true + }, + "456": { + "name": "20-inject.js", + "types": [ + "inject" + ], + "enabled": true + }, + "789": { + "name": "testModule:a-module.js", + "types": [ + "example" + ], + "enabled":true, + "module":"testModule" + } + }} + }; + var expected = JSON.parse('{"node-red":{"name":"node-red","nodes":{"sentiment":{"name":"sentiment","types":["sentiment"],"enabled":true,"module":"node-red"},"inject":{"name":"inject","types":["inject"],"enabled":true,"module":"node-red"}}},"testModule":{"name":"testModule","nodes":{"a-module.js":{"name":"a-module.js","types":["example"],"enabled":true,"module":"testModule"}}}}'); + typeRegistry.init(legacySettings); + legacySettings.set.calledOnce.should.be.true; + legacySettings.set.args[0][1].should.eql(expected); + done(); + }); + }); + + + describe('#addNodeSet', function() { + it('adds a node set for an unknown module', function() { + + typeRegistry.init(settings); + + typeRegistry.getNodeList().should.have.lengthOf(0); + typeRegistry.getModuleList().should.have.lengthOf(0); + + typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); + + typeRegistry.getNodeList().should.have.lengthOf(1); + typeRegistry.getModuleList().should.have.lengthOf(1); + + }); + + it('adds a node set to an existing module', function() { + + typeRegistry.init(settings); + typeRegistry.getNodeList().should.have.lengthOf(0); + typeRegistry.getModuleList().should.have.lengthOf(0); + + typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); + + typeRegistry.addNodeSet("test-module/test-name-2",testNodeSet2); + + typeRegistry.getNodeList().should.have.lengthOf(2); + typeRegistry.getModuleList().should.have.lengthOf(1); + }); + + it('doesnt add node set types if node set has an error', function() { + typeRegistry.init(settings); + typeRegistry.getNodeList().should.have.lengthOf(0); + typeRegistry.getModuleList().should.have.lengthOf(0); + + typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); + + typeRegistry.getTypeId("test-a").should.eql("test-module/test-name"); + + should.not.exist(typeRegistry.getTypeId("test-c")); + + typeRegistry.addNodeSet("test-module/test-name-2",testNodeSet2WithError, "0.0.1"); + + should.not.exist(typeRegistry.getTypeId("test-c")); + }); + }); + + describe("#enableNodeSet", function() { + it('throws error if settings unavailable', function() { + typeRegistry.init(settings); + /*jshint immed: false */ + (function(){ + typeRegistry.enableNodeSet("test-module/test-name"); + }).should.throw("Settings unavailable"); + }); + + it('throws error if module unknown', function() { + typeRegistry.init(settingsWithStorageAndInitialConfig); + /*jshint immed: false */ + (function(){ + typeRegistry.enableNodeSet("test-module/unknown"); + }).should.throw("Unrecognised id: test-module/unknown"); + }); + + }); + + describe('#getNodeConfig', function() { + it('returns nothing for an unregistered type config', function(done) { + typeRegistry.init(settings); + var config = typeRegistry.getNodeConfig("imaginary-shark"); + (config === null).should.be.true; + done(); + }); + }); + +});