diff --git a/red/runtime/nodes/registry/deprecated.js b/red/runtime-registry/deprecated.js similarity index 100% rename from red/runtime/nodes/registry/deprecated.js rename to red/runtime-registry/deprecated.js diff --git a/red/runtime/nodes/registry/index.js b/red/runtime-registry/index.js similarity index 88% rename from red/runtime/nodes/registry/index.js rename to red/runtime-registry/index.js index 8e6fbbe7b..a020a7827 100644 --- a/red/runtime/nodes/registry/index.js +++ b/red/runtime-registry/index.js @@ -17,6 +17,7 @@ var registry = require("./registry"); var loader = require("./loader"); var installer = require("./installer"); +var library = require("./library"); var settings; @@ -24,7 +25,8 @@ function init(runtime) { settings = runtime.settings; installer.init(runtime); loader.init(runtime); - registry.init(settings,loader); + registry.init(settings,loader,runtime.events); + library.init(); } function load() { @@ -79,5 +81,11 @@ module.exports = { cleanModuleList: registry.cleanModuleList, - paletteEditorEnabled: installer.paletteEditorEnabled + paletteEditorEnabled: installer.paletteEditorEnabled, + + getNodeExampleFlows: library.getExampleFlows, + getNodeExampleFlowPath: library.getExampleFlowPath, + + deprecated: require("./deprecated") + }; diff --git a/red/runtime/nodes/registry/installer.js b/red/runtime-registry/installer.js similarity index 98% rename from red/runtime/nodes/registry/installer.js rename to red/runtime-registry/installer.js index bb5b54249..6f4baa852 100644 --- a/red/runtime/nodes/registry/installer.js +++ b/red/runtime-registry/installer.js @@ -19,9 +19,10 @@ var path = require("path"); var fs = require("fs"); var registry = require("./registry"); +var library = require("./library"); var log; -var events = require("../../events"); +var events; var child_process = require('child_process'); var npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm'; @@ -32,6 +33,7 @@ var moduleRe = /^(@[^/]+?[/])?[^/]+?$/; var slashRe = process.platform === "win32" ? /\\|[/]/ : /[/]/; function init(runtime) { + events = runtime.events; settings = runtime.settings; log = runtime.log; } @@ -210,8 +212,7 @@ function uninstallModule(module) { } else { log.info(log._("server.install.uninstalled",{name:module})); reportRemovedModules(list); - // TODO: tidy up internal event names - events.emit("node-module-uninstalled",module) + library.removeExamplesDir(module); resolve(list); } } diff --git a/red/runtime/nodes/library.js b/red/runtime-registry/library.js similarity index 83% rename from red/runtime/nodes/library.js rename to red/runtime-registry/library.js index 04597bd40..9f7c6e8b2 100644 --- a/red/runtime/nodes/library.js +++ b/red/runtime-registry/library.js @@ -59,11 +59,11 @@ function getFlowsFromPath(path) { }) } -function addNodeExamplesDir(module) { - exampleRoots[module.name] = module.path; - getFlowsFromPath(module.path).then(function(result) { +function addNodeExamplesDir(module,path) { + exampleRoots[module] = path; + return getFlowsFromPath(path).then(function(result) { exampleFlows = exampleFlows||{d:{}}; - exampleFlows.d[module.name] = result; + exampleFlows.d[module] = result; }); } function removeNodeExamplesDir(module) { @@ -77,17 +77,9 @@ function removeNodeExamplesDir(module) { } -function init(_runtime) { - - runtime = _runtime; - +function init() { exampleRoots = {}; exampleFlows = null; - - runtime.events.removeListener("node-examples-dir",addNodeExamplesDir); - runtime.events.on("node-examples-dir",addNodeExamplesDir); - runtime.events.removeListener("node-module-uninstalled",removeNodeExamplesDir); - runtime.events.on("node-module-uninstalled",removeNodeExamplesDir); } function getExampleFlows() { @@ -103,6 +95,8 @@ function getExampleFlowPath(module,path) { module.exports = { init: init, + addExamplesDir: addNodeExamplesDir, + removeExamplesDir: removeNodeExamplesDir, getExampleFlows: getExampleFlows, getExampleFlowPath: getExampleFlowPath } diff --git a/red/runtime/nodes/registry/loader.js b/red/runtime-registry/loader.js similarity index 93% rename from red/runtime/nodes/registry/loader.js rename to red/runtime-registry/loader.js index f4f33f63e..f0bd86587 100644 --- a/red/runtime/nodes/registry/loader.js +++ b/red/runtime-registry/loader.js @@ -22,6 +22,8 @@ var semver = require("semver"); var localfilesystem = require("./localfilesystem"); var registry = require("./registry"); +var i18n = require("../util").i18n; // TODO: separate module + var settings; var runtime; @@ -110,7 +112,7 @@ function createNodeApi(node) { if (args[0].indexOf(":") === -1) { args[0] = node.namespace+":"+args[0]; } - return runtime.i18n._.apply(null,args); + return i18n._.apply(null,args); } return red; } @@ -118,6 +120,7 @@ function createNodeApi(node) { function loadNodeFiles(nodeFiles) { var promises = []; + var nodes = []; for (var module in nodeFiles) { /* istanbul ignore else */ if (nodeFiles.hasOwnProperty(module)) { @@ -125,6 +128,7 @@ function loadNodeFiles(nodeFiles) { !semver.satisfies(runtime.version().replace(/(\-[1-9A-Za-z-][0-9A-Za-z-\.]*)?(\+[0-9A-Za-z-\.]+)?$/,""), nodeFiles[module].redVersion)) { //TODO: log it runtime.log.warn("["+module+"] "+runtime.log._("server.node-version-mismatch",{version:nodeFiles[module].redVersion})); + nodeFiles[module].err = "version_mismatch"; continue; } if (module == "node-red" || !registry.getModuleInfo(module)) { @@ -154,7 +158,14 @@ function loadNodeFiles(nodeFiles) { } try { - promises.push(loadNodeConfig(nodeFiles[module].nodes[node])) + promises.push(loadNodeConfig(nodeFiles[module].nodes[node]).then((function() { + var m = module; + var n = node; + return function(nodeSet) { + nodeFiles[m].nodes[n] = nodeSet; + nodes.push(nodeSet); + } + })())); } catch(err) { // } @@ -164,10 +175,13 @@ function loadNodeFiles(nodeFiles) { } } return when.settle(promises).then(function(results) { - var nodes = results.map(function(r) { - registry.addNodeSet(r.value.id,r.value,r.value.version); - return r.value; - }); + for (var module in nodeFiles) { + if (nodeFiles.hasOwnProperty(module)) { + if (!nodeFiles[module].err) { + registry.addModule(nodeFiles[module]); + } + } + } return loadNodeSetList(nodes); }); } @@ -239,7 +253,7 @@ function loadNodeConfig(fileInfo) { index = regExp.lastIndex; var help = content.substring(regExp.lastIndex-match[1].length,regExp.lastIndex); - var lang = runtime.i18n.defaultLang; + var lang = i18n.defaultLang; if ((match = langRegExp.exec(help)) !== null) { lang = match[1]; } @@ -270,7 +284,7 @@ function loadNodeConfig(fileInfo) { fs.stat(path.join(path.dirname(file),"locales"),function(err,stat) { if (!err) { node.namespace = node.id; - runtime.i18n.registerMessageCatalog(node.id, + i18n.registerMessageCatalog(node.id, path.join(path.dirname(file),"locales"), path.basename(file,".js")+".json") .then(function() { @@ -414,10 +428,10 @@ function getNodeHelp(node,lang) { } if (help) { node.help[lang] = help; - } else if (lang === runtime.i18n.defaultLang) { + } else if (lang === i18n.defaultLang) { return null; } else { - node.help[lang] = getNodeHelp(node, runtime.i18n.defaultLang); + node.help[lang] = getNodeHelp(node, i18n.defaultLang); } } return node.help[lang]; diff --git a/red/runtime/nodes/registry/localfilesystem.js b/red/runtime-registry/localfilesystem.js similarity index 83% rename from red/runtime/nodes/registry/localfilesystem.js rename to red/runtime-registry/localfilesystem.js index f8a1c83db..877491f2f 100644 --- a/red/runtime/nodes/registry/localfilesystem.js +++ b/red/runtime-registry/localfilesystem.js @@ -19,7 +19,8 @@ var path = require("path"); var events; var log; -var i18n; + +var i18n = require("../util").i18n; // TODO: separate module var settings; var disableNodePathScan = false; @@ -29,7 +30,6 @@ function init(runtime) { settings = runtime.settings; events = runtime.events; log = runtime.log; - i18n = runtime.i18n; } function isIncluded(name) { @@ -84,6 +84,7 @@ function getLocalNodeFiles(dir) { var result = []; var files = []; + var icons = []; try { files = fs.readdirSync(dir); } catch(err) { @@ -102,14 +103,16 @@ function getLocalNodeFiles(dir) { } else if (stats.isDirectory()) { // Ignore /.dirs/, /lib/ /node_modules/ if (!/^(\..*|lib|icons|node_modules|test|locales)$/.test(fn)) { - result = result.concat(getLocalNodeFiles(path.join(dir,fn))); + var subDirResults = getLocalNodeFiles(path.join(dir,fn)); + result = result.concat(subDirResults.files); + icons = icons.concat(subDirResults.icons); } else if (fn === "icons") { var iconList = scanIconDir(path.join(dir,fn)); - events.emit("node-icon-dir",{name:'node-red',path:path.join(dir,fn),icons:iconList}); + icons.push({path:path.join(dir,fn),icons:iconList}); } } }); - return result; + return {files: result, icons: icons} } function scanDirForNodesModules(dir,moduleName) { @@ -197,7 +200,7 @@ function getModuleNodeFiles(module) { var nodes = pkg['node-red'].nodes||{}; var results = []; var iconDirs = []; - + var iconList = []; for (var n in nodes) { /* istanbul ignore else */ if (nodes.hasOwnProperty(n)) { @@ -212,47 +215,55 @@ function getModuleNodeFiles(module) { if (iconDirs.indexOf(iconDir) == -1) { try { fs.statSync(iconDir); - var iconList = scanIconDir(iconDir); - events.emit("node-icon-dir",{name:pkg.name,path:iconDir,icons:iconList}); + var icons = scanIconDir(iconDir); + iconList.push({path:iconDir,icons:icons}); iconDirs.push(iconDir); } catch(err) { } } } } + var result = {files:results,icons:iconList}; + var examplesDir = path.join(moduleDir,"examples"); try { fs.statSync(examplesDir) - events.emit("node-examples-dir",{name:pkg.name,path:examplesDir}); + result.examples = {path:examplesDir}; + // events.emit("node-examples-dir",{name:pkg.name,path:examplesDir}); } catch(err) { } - return results; + return result; } function getNodeFiles(disableNodePathScan) { var dir; // Find all of the nodes to load var nodeFiles = []; + var results; - var dir = path.resolve(__dirname + '/../../../../public/icons'); - var iconList = scanIconDir(dir); - events.emit("node-icon-dir",{name:'node-red',path:dir,icons:iconList}); + var dir = path.resolve(__dirname + '/../../public/icons'); + var iconList = [{path:dir,icons:scanIconDir(dir)}]; if (settings.coreNodesDir) { - nodeFiles = getLocalNodeFiles(path.resolve(settings.coreNodesDir)); + results = getLocalNodeFiles(path.resolve(settings.coreNodesDir)); + nodeFiles = nodeFiles.concat(results.files); + iconList = iconList.concat(results.icons); + var defaultLocalesPath = path.join(settings.coreNodesDir,"core","locales"); i18n.registerMessageCatalog("node-red",defaultLocalesPath,"messages.json"); } if (settings.userDir) { dir = path.join(settings.userDir,"lib","icons"); - iconList = scanIconDir(dir); - if (iconList.length > 0) { - events.emit("node-icon-dir",{name:'Library',path:dir,icons:iconList}); + var icons = scanIconDir(dir); + if (icons.length > 0) { + iconList.push({path:dir,icons:icons}); } dir = path.join(settings.userDir,"nodes"); - nodeFiles = nodeFiles.concat(getLocalNodeFiles(dir)); + results = getLocalNodeFiles(path.resolve(dir)); + nodeFiles = nodeFiles.concat(results.files); + iconList = iconList.concat(results.icons); } if (settings.nodesDir) { dir = settings.nodesDir; @@ -260,7 +271,9 @@ function getNodeFiles(disableNodePathScan) { dir = [dir]; } for (var i=0;iicon_paths[module.name].push(path.resolve(icon.path)) ) } - - if (version) { - moduleConfigs[set.module].version = version; + if (module.examples) { + library.addExamplesDir(module.name,module.examples.path); } - moduleConfigs[set.module].local = set.local; - - 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) { @@ -370,27 +364,6 @@ function getCaller(){ return stack[0].getFileName(); } -function inheritNode(constructor) { - if(Object.getPrototypeOf(constructor.prototype) === Object.prototype) { - util.inherits(constructor,Node); - } else { - var proto = constructor.prototype; - while(Object.getPrototypeOf(proto) !== Object.prototype) { - proto = Object.getPrototypeOf(proto); - } - //TODO: This is a partial implementation of util.inherits >= node v5.0.0 - // which should be changed when support for node < v5.0.0 is dropped - // see: https://github.com/nodejs/node/pull/3455 - proto.constructor.super_ = Node; - if(Object.setPrototypeOf) { - Object.setPrototypeOf(proto, Node.prototype); - } else { - // hack for node v0.10 - proto.__proto__ = Node.prototype; - } - } -} - function registerNodeConstructor(nodeSet,type,constructor) { if (nodeConstructors.hasOwnProperty(type)) { throw new Error(type+" already registered"); @@ -398,9 +371,6 @@ function registerNodeConstructor(nodeSet,type,constructor) { //TODO: Ensure type is known - but doing so will break some tests // that don't have a way to register a node template ahead // of registering the constructor - if(!(constructor.prototype instanceof Node)) { - inheritNode(constructor); - } var nodeSetInfo = getFullNodeInfo(nodeSet); if (nodeSetInfo) { @@ -584,10 +554,10 @@ function setModulePendingUpdated(module,version) { } var icon_paths = { - "node-red":[path.resolve(__dirname + '/../../../../public/icons')] + "node-red":[path.resolve(__dirname + '/../../public/icons')] }; var iconCache = {}; -var defaultIcon = path.resolve(__dirname + '/../../../../public/icons/arrow-in.png'); +var defaultIcon = path.resolve(__dirname + '/../../public/icons/arrow-in.png'); function nodeIconDir(dir) { icon_paths[dir.name] = icon_paths[dir.name] || []; @@ -648,7 +618,8 @@ function getNodeIcons() { for (var module in moduleConfigs) { if (moduleConfigs.hasOwnProperty(module)) { if (moduleConfigs[module].icons) { - iconList[module] = moduleConfigs[module].icons; + iconList[module] = []; + moduleConfigs[module].icons.forEach(icon=>{ iconList[module] = iconList[module].concat(icon.icons)}) } } } @@ -664,7 +635,9 @@ var registry = module.exports = { registerNodeConstructor: registerNodeConstructor, getNodeConstructor: getNodeConstructor, - addNodeSet: addNodeSet, + + addModule: addModule, + enableNodeSet: enableNodeSet, disableNodeSet: disableNodeSet, diff --git a/red/runtime/library/index.js b/red/runtime/library/index.js index e0d8b6d82..cc8cd1509 100644 --- a/red/runtime/library/index.js +++ b/red/runtime/library/index.js @@ -69,6 +69,7 @@ function getEntry(type,path) { } catch(err) { return reject(err); } + return; } } // IF we get here, we didn't find the file diff --git a/red/runtime/nodes/flows/Flow.js b/red/runtime/nodes/flows/Flow.js index ddf887ee7..6f4e132df 100644 --- a/red/runtime/nodes/flows/Flow.js +++ b/red/runtime/nodes/flows/Flow.js @@ -16,10 +16,11 @@ var when = require("when"); var clone = require("clone"); -var typeRegistry = require("../registry"); +var typeRegistry = require("../../../runtime-registry"); var Log; var redUtil = require("../../util"); var flowUtil = require("./util"); +var Node; var nodeCloseTimeout = 15000; @@ -292,6 +293,7 @@ function Flow(global,flow) { function createNode(type,config) { var nn = null; + try { var nt = typeRegistry.get(type); if (nt) { var conf = clone(config); @@ -315,6 +317,9 @@ function createNode(type,config) { } else { Log.error(Log._("nodes.flow.unknown-type", {type:type})); } +} catch(err) { + Log.error(err); +} return nn; } @@ -498,6 +503,7 @@ module.exports = { init: function(runtime) { nodeCloseTimeout = runtime.settings.nodeCloseTimeout || 15000; Log = runtime.log; + Node = require("../Node"); }, create: function(global,conf) { return new Flow(global,conf); diff --git a/red/runtime/nodes/flows/index.js b/red/runtime/nodes/flows/index.js index e62961b94..a17a938b8 100644 --- a/red/runtime/nodes/flows/index.js +++ b/red/runtime/nodes/flows/index.js @@ -19,7 +19,10 @@ var when = require("when"); var Flow = require('./Flow'); -var typeRegistry = require("../registry"); +var typeRegistry = require("../../../runtime-registry"); +var deprecated = typeRegistry.deprecated; + + var context = require("../context") var credentials = require("../credentials"); @@ -27,7 +30,6 @@ var flowUtil = require("./util"); var log; var events = require("../../events"); var redUtil = require("../../util"); -var deprecated = require("../registry/deprecated"); var storage = null; var settings = null; diff --git a/red/runtime/nodes/flows/util.js b/red/runtime/nodes/flows/util.js index 16b9f461b..cda79adc6 100644 --- a/red/runtime/nodes/flows/util.js +++ b/red/runtime/nodes/flows/util.js @@ -16,7 +16,7 @@ var clone = require("clone"); var redUtil = require("../../util"); var subflowInstanceRE = /^subflow:(.+)$/; -var typeRegistry = require("../registry"); +var typeRegistry = require("../../../runtime-registry"); function diffNodes(oldNode,newNode) { if (oldNode == null) { @@ -203,7 +203,7 @@ module.exports = { var linkMap = {}; var changedTabs = {}; - + // Look for tabs that have been removed for (id in oldConfig.flows) { if (oldConfig.flows.hasOwnProperty(id) && (!newConfig.flows.hasOwnProperty(id))) { diff --git a/red/runtime/nodes/index.js b/red/runtime/nodes/index.js index f5f7533e1..af6082a8b 100644 --- a/red/runtime/nodes/index.js +++ b/red/runtime/nodes/index.js @@ -18,15 +18,16 @@ var when = require("when"); var path = require("path"); var fs = require("fs"); var clone = require("clone"); +var util = require("util"); + +var registry = require("../../runtime-registry"); -var registry = require("./registry"); var credentials = require("./credentials"); var flows = require("./flows"); var flowUtil = require("./flows/util") var context = require("./context"); var Node = require("./Node"); var log; -var library = require("./library"); var events = require("../events"); @@ -61,6 +62,26 @@ function registerType(nodeSet,type,constructor,opts) { } } } + if(!(constructor.prototype instanceof Node)) { + if(Object.getPrototypeOf(constructor.prototype) === Object.prototype) { + util.inherits(constructor,Node); + } else { + var proto = constructor.prototype; + while(Object.getPrototypeOf(proto) !== Object.prototype) { + proto = Object.getPrototypeOf(proto); + } + //TODO: This is a partial implementation of util.inherits >= node v5.0.0 + // which should be changed when support for node < v5.0.0 is dropped + // see: https://github.com/nodejs/node/pull/3455 + proto.constructor.super_ = Node; + if(Object.setPrototypeOf) { + Object.setPrototypeOf(proto, Node.prototype); + } else { + // hack for node v0.10 + proto.__proto__ = Node.prototype; + } + } + } registry.registerType(nodeSet,type,constructor); } @@ -99,7 +120,6 @@ function init(runtime) { flows.init(runtime); registry.init(runtime); context.init(runtime.settings); - library.init(runtime); } function disableNode(id) { @@ -188,8 +208,8 @@ module.exports = { getNodeConfig: registry.getNodeConfig, getNodeIconPath: registry.getNodeIconPath, getNodeIcons: registry.getNodeIcons, - getNodeExampleFlows: library.getExampleFlows, - getNodeExampleFlowPath: library.getExampleFlowPath, + getNodeExampleFlows: registry.getNodeExampleFlows, + getNodeExampleFlowPath: registry.getNodeExampleFlowPath, clearRegistry: registry.clear, cleanModuleList: registry.cleanModuleList, diff --git a/red/runtime/storage/localfilesystem/util.js b/red/runtime/storage/localfilesystem/util.js index 8164147ab..7515f7bb1 100644 --- a/red/runtime/storage/localfilesystem/util.js +++ b/red/runtime/storage/localfilesystem/util.js @@ -83,7 +83,6 @@ module.exports = { try { fs.renameSync(path,backupPath); } catch(err) { - console.log(err); } } return when.promise(function(resolve,reject) { diff --git a/test/red/runtime/nodes/registry/deprecated_spec.js b/test/red/runtime-registry/deprecated_spec.js similarity index 91% rename from test/red/runtime/nodes/registry/deprecated_spec.js rename to test/red/runtime-registry/deprecated_spec.js index 738433505..43ceb6d6a 100644 --- a/test/red/runtime/nodes/registry/deprecated_spec.js +++ b/test/red/runtime-registry/deprecated_spec.js @@ -16,7 +16,7 @@ var should = require("should"); -var deprecated = require("../../../../../red/runtime/nodes/registry/deprecated.js"); +var deprecated = require("../../../red/runtime-registry/deprecated.js"); describe('deprecated', function() { it('should return info on a node',function() { diff --git a/test/red/runtime/nodes/registry/index_spec.js b/test/red/runtime-registry/index_spec.js similarity index 92% rename from test/red/runtime/nodes/registry/index_spec.js rename to test/red/runtime-registry/index_spec.js index 590d60040..14d8772c2 100644 --- a/test/red/runtime/nodes/registry/index_spec.js +++ b/test/red/runtime-registry/index_spec.js @@ -20,16 +20,13 @@ var path = require("path"); var when = require("when"); var fs = require("fs"); -var registry = require("../../../../../red/runtime/nodes/registry"); +var registry = require("../../../red/runtime-registry"); -var installer = require("../../../../../red/runtime/nodes/registry/installer"); -var loader = require("../../../../../red/runtime/nodes/registry/loader"); -var typeRegistry = require("../../../../../red/runtime/nodes/registry/registry"); +var installer = require("../../../red/runtime-registry/installer"); +var loader = require("../../../red/runtime-registry/loader"); +var typeRegistry = require("../../../red/runtime-registry/registry"); - - - -describe('red/nodes/registry/index', function() { +describe('red/registry/index', function() { var stubs = []; afterEach(function() { while(stubs.length) { diff --git a/test/red/runtime/nodes/registry/installer_spec.js b/test/red/runtime-registry/installer_spec.js similarity index 95% rename from test/red/runtime/nodes/registry/installer_spec.js rename to test/red/runtime-registry/installer_spec.js index 78566a3d3..3005bf473 100644 --- a/test/red/runtime/nodes/registry/installer_spec.js +++ b/test/red/runtime-registry/installer_spec.js @@ -22,9 +22,9 @@ var fs = require('fs'); var EventEmitter = require('events'); var child_process = require('child_process'); -var installer = require("../../../../../red/runtime/nodes/registry/installer"); -var registry = require("../../../../../red/runtime/nodes/registry/index"); -var typeRegistry = require("../../../../../red/runtime/nodes/registry/registry"); +var installer = require("../../../red/runtime-registry/installer"); +var registry = require("../../../red/runtime-registry/index"); +var typeRegistry = require("../../../red/runtime-registry/registry"); describe('nodes/registry/installer', function() { @@ -39,7 +39,7 @@ describe('nodes/registry/installer', function() { } before(function() { - installer.init({log:mockLog, settings:{}}); + installer.init({log:mockLog, settings:{}, events: new EventEmitter()}); }); afterEach(function() { if (child_process.spawn.restore) { @@ -166,7 +166,7 @@ describe('nodes/registry/installer', function() { }); it("rejects when non-existant path is provided", function(done) { this.timeout(10000); - var resourcesDir = path.resolve(path.join(__dirname,"..","resources","local","TestNodeModule","node_modules","NonExistant")); + var resourcesDir = path.resolve(path.join(__dirname,"resources","local","TestNodeModule","node_modules","NonExistant")); installer.installModule(resourcesDir).then(function() { done(new Error("Unexpected success")); }).catch(function(err) { @@ -186,7 +186,7 @@ describe('nodes/registry/installer', function() { var addModule = sinon.stub(registry,"addModule",function(md) { return when.resolve(nodeInfo); }); - var resourcesDir = path.resolve(path.join(__dirname,"..","resources","local","TestNodeModule","node_modules","TestNodeModule")); + var resourcesDir = path.resolve(path.join(__dirname,"resources","local","TestNodeModule","node_modules","TestNodeModule")); sinon.stub(child_process,"spawn",function(cmd,args,opt) { var ee = new EventEmitter(); ee.stdout = new EventEmitter(); diff --git a/test/red/runtime/nodes/library_spec.js b/test/red/runtime-registry/library_spec.js similarity index 61% rename from test/red/runtime/nodes/library_spec.js rename to test/red/runtime-registry/library_spec.js index 6596c8c7b..dd7262dca 100644 --- a/test/red/runtime/nodes/library_spec.js +++ b/test/red/runtime-registry/library_spec.js @@ -14,56 +14,47 @@ * limitations under the License. **/ -var EventEmitter = require('events').EventEmitter; -var events = new EventEmitter(); - var should = require("should"); var fs = require("fs"); var path = require("path"); -var library = require("../../../../red/runtime/nodes/library") +var library = require("../../../red/runtime-registry/library"); describe("library api", function() { it('returns null list when no modules have been registered', function() { - library.init({events:events}); + library.init(); should.not.exist(library.getExampleFlows()); }); it('returns null path when module is not known', function() { - library.init({events:events}); + library.init(); should.not.exist(library.getExampleFlowPath('foo','bar')); }); it('returns a valid example path', function(done) { - library.init({events:events}); - events.emit('node-examples-dir',{ - name: "test-module", - path: path.resolve(__dirname+'/../../../resources/examples') - }); - setTimeout(function() { + library.init(); + library.addExamplesDir("test-module",path.resolve(__dirname+'/resources/examples')).then(function() { try { var flows = library.getExampleFlows(); flows.should.deepEqual({"d":{"test-module":{"f":["one"]}}}); var examplePath = library.getExampleFlowPath('test-module','one'); - examplePath.should.eql(path.resolve(__dirname+'/../../../resources/examples/one.json')) + examplePath.should.eql(path.resolve(__dirname+'/resources/examples/one.json')) - events.emit('node-module-uninstalled', 'test-module'); + library.removeExamplesDir('test-module'); - setTimeout(function() { - try { - should.not.exist(library.getExampleFlows()); - should.not.exist(library.getExampleFlowPath('test-module','one')); - done(); - } catch(err) { - done(err); - } - },20); + try { + should.not.exist(library.getExampleFlows()); + should.not.exist(library.getExampleFlowPath('test-module','one')); + done(); + } catch(err) { + done(err); + } }catch(err) { done(err); } - },20); + }); }) }); diff --git a/test/red/runtime/nodes/registry/loader_spec.js b/test/red/runtime-registry/loader_spec.js similarity index 59% rename from test/red/runtime/nodes/registry/loader_spec.js rename to test/red/runtime-registry/loader_spec.js index 4f9ddf8a7..93d2eeba2 100644 --- a/test/red/runtime/nodes/registry/loader_spec.js +++ b/test/red/runtime-registry/loader_spec.js @@ -20,14 +20,14 @@ var sinon = require("sinon"); var path = require("path"); var fs = require("fs"); -var loader = require("../../../../../red/runtime/nodes/registry/loader"); +var loader = require("../../../red/runtime-registry/loader"); -var localfilesystem = require("../../../../../red/runtime/nodes/registry/localfilesystem"); -var registry = require("../../../../../red/runtime/nodes/registry/registry"); +var localfilesystem = require("../../../red/runtime-registry/localfilesystem"); +var registry = require("../../../red/runtime-registry/registry"); -var nodes = require("../../../../../red/runtime/nodes/registry"); +var nodes = require("../../../red/runtime-registry"); -var resourcesDir = path.resolve(path.join(__dirname,"..","resources","local")); +var resourcesDir = path.resolve(path.join(__dirname,"resources","local")); describe("red/nodes/registry/loader",function() { var stubs = []; @@ -42,18 +42,12 @@ describe("red/nodes/registry/loader",function() { stubs.pop().restore(); } }) - describe("#init",function() { - it("init",function() { - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){},log:{info:function(){},_:function(){}}}}); - localfilesystem.init.called.should.be.true(); - }); - }); describe("#load",function() { it("load empty set without settings available", function(done) { stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};})); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};})); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return false;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return false;}}}); loader.load("foo",true).then(function() { localfilesystem.getNodeFiles.called.should.be.true(); localfilesystem.getNodeFiles.lastCall.args[0].should.eql('foo'); @@ -65,7 +59,7 @@ describe("red/nodes/registry/loader",function() { it("load empty set with settings available triggers registery save", function(done) { stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};})); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};})); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.load("foo",true).then(function() { registry.saveNodeList.called.should.be.true(); done(); @@ -79,6 +73,7 @@ describe("red/nodes/registry/loader",function() { var result = {}; result["node-red"] = { "name": "node-red", + "version": "1.2.3", "nodes": { "TestNode1": { "file": path.join(resourcesDir,"TestNode1","TestNode1.js"), @@ -91,27 +86,32 @@ describe("red/nodes/registry/loader",function() { })); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); - stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); // This module isn't already loaded stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { - registry.addNodeSet.called.should.be.true(); - registry.addNodeSet.lastCall.args[0].should.eql("node-red/TestNode1"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('id',"node-red/TestNode1"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('module',"node-red"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('enabled',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('loaded',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('version',undefined); - registry.addNodeSet.lastCall.args[1].should.have.a.property('types'); - registry.addNodeSet.lastCall.args[1].types.should.have.a.length(1); - registry.addNodeSet.lastCall.args[1].types[0].should.eql('test-node-1'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('config'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('help'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('namespace','node-red'); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('err'); + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("TestNode1"); + module.nodes.TestNode1.should.have.property("id","node-red/TestNode1"); + module.nodes.TestNode1.should.have.property("module","node-red"); + module.nodes.TestNode1.should.have.property("name","TestNode1"); + module.nodes.TestNode1.should.have.property("file"); + module.nodes.TestNode1.should.have.property("template"); + module.nodes.TestNode1.should.have.property("enabled",true); + module.nodes.TestNode1.should.have.property("loaded",true); + module.nodes.TestNode1.should.have.property("types"); + module.nodes.TestNode1.types.should.have.a.length(1); + module.nodes.TestNode1.types[0].should.eql('test-node-1'); + module.nodes.TestNode1.should.have.property("config"); + module.nodes.TestNode1.should.have.property("help"); + module.nodes.TestNode1.should.have.property("namespace","node-red"); nodes.registerType.calledOnce.should.be.true(); nodes.registerType.lastCall.args[0].should.eql('node-red/TestNode1'); @@ -128,6 +128,7 @@ describe("red/nodes/registry/loader",function() { var result = {}; result["node-red"] = { "name": "node-red", + "version": "4.5.6", "nodes": { "MultipleNodes1": { "file": path.join(resourcesDir,"MultipleNodes1","MultipleNodes1.js"), @@ -140,27 +141,33 @@ describe("red/nodes/registry/loader",function() { })); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); - stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); // This module isn't already loaded stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { - registry.addNodeSet.called.should.be.true(); - registry.addNodeSet.lastCall.args[0].should.eql("node-red/MultipleNodes1"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('id',"node-red/MultipleNodes1"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('module',"node-red"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('enabled',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('loaded',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('version',undefined); - registry.addNodeSet.lastCall.args[1].should.have.a.property('types'); - registry.addNodeSet.lastCall.args[1].types.should.have.a.length(2); - registry.addNodeSet.lastCall.args[1].types[0].should.eql('test-node-multiple-1a'); - registry.addNodeSet.lastCall.args[1].types[1].should.eql('test-node-multiple-1b'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('config'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('help'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('namespace','node-red'); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('err'); + + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","4.5.6"); + module.should.have.property("nodes"); + module.nodes.should.have.property("MultipleNodes1"); + module.nodes.MultipleNodes1.should.have.property("id","node-red/MultipleNodes1"); + module.nodes.MultipleNodes1.should.have.property("module","node-red"); + module.nodes.MultipleNodes1.should.have.property("name","MultipleNodes1"); + module.nodes.MultipleNodes1.should.have.property("file"); + module.nodes.MultipleNodes1.should.have.property("template"); + module.nodes.MultipleNodes1.should.have.property("enabled",true); + module.nodes.MultipleNodes1.should.have.property("loaded",true); + module.nodes.MultipleNodes1.should.have.property("types"); + module.nodes.MultipleNodes1.types.should.have.a.length(2); + module.nodes.MultipleNodes1.types[0].should.eql('test-node-multiple-1a'); + module.nodes.MultipleNodes1.types[1].should.eql('test-node-multiple-1b'); + module.nodes.MultipleNodes1.should.have.property("config"); + module.nodes.MultipleNodes1.should.have.property("help"); + module.nodes.MultipleNodes1.should.have.property("namespace","node-red"); nodes.registerType.calledTwice.should.be.true(); nodes.registerType.firstCall.args[0].should.eql('node-red/MultipleNodes1'); @@ -168,6 +175,7 @@ describe("red/nodes/registry/loader",function() { nodes.registerType.secondCall.args[0].should.eql('node-red/MultipleNodes1'); nodes.registerType.secondCall.args[1].should.eql('test-node-multiple-1b'); + done(); }).catch(function(err) { done(err); @@ -180,6 +188,7 @@ describe("red/nodes/registry/loader",function() { var result = {}; result["node-red"] = { "name": "node-red", + "version":"2.4.6", "nodes": { "TestNode2": { "file": path.join(resourcesDir,"TestNode2","TestNode2.js"), @@ -192,27 +201,34 @@ describe("red/nodes/registry/loader",function() { })); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); - stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); // This module isn't already loaded stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { - registry.addNodeSet.called.should.be.true(); - registry.addNodeSet.lastCall.args[0].should.eql("node-red/TestNode2"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('id',"node-red/TestNode2"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('module',"node-red"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('enabled',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('loaded',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('version',undefined); - registry.addNodeSet.lastCall.args[1].should.have.a.property('types'); - registry.addNodeSet.lastCall.args[1].types.should.have.a.length(1); - registry.addNodeSet.lastCall.args[1].types[0].should.eql('test-node-2'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('config'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('help'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('namespace','node-red'); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('err'); + + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","2.4.6"); + module.should.have.property("nodes"); + module.nodes.should.have.property("TestNode2"); + module.nodes.TestNode2.should.have.property("id","node-red/TestNode2"); + module.nodes.TestNode2.should.have.property("module","node-red"); + module.nodes.TestNode2.should.have.property("name","TestNode2"); + module.nodes.TestNode2.should.have.property("file"); + module.nodes.TestNode2.should.have.property("template"); + module.nodes.TestNode2.should.have.property("enabled",true); + module.nodes.TestNode2.should.have.property("loaded",true); + module.nodes.TestNode2.should.have.property("types"); + module.nodes.TestNode2.types.should.have.a.length(1); + module.nodes.TestNode2.types[0].should.eql('test-node-2'); + module.nodes.TestNode2.should.have.property("config"); + module.nodes.TestNode2.should.have.property("help"); + module.nodes.TestNode2.should.have.property("namespace","node-red"); + module.nodes.TestNode2.should.not.have.property('err'); nodes.registerType.calledOnce.should.be.true(); nodes.registerType.lastCall.args[0].should.eql('node-red/TestNode2'); @@ -230,6 +246,7 @@ describe("red/nodes/registry/loader",function() { var result = {}; result["node-red"] = { "name": "node-red", + "version":"1.2.3", "nodes": { "TestNode3": { "file": path.join(resourcesDir,"TestNode3","TestNode3.js"), @@ -242,29 +259,35 @@ describe("red/nodes/registry/loader",function() { })); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); - stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); // This module isn't already loaded stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { - registry.addNodeSet.called.should.be.true(); - registry.addNodeSet.lastCall.args[0].should.eql("node-red/TestNode3"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('id',"node-red/TestNode3"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('module',"node-red"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('enabled',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('loaded',false); - registry.addNodeSet.lastCall.args[1].should.have.a.property('version',undefined); - registry.addNodeSet.lastCall.args[1].should.have.a.property('types'); - registry.addNodeSet.lastCall.args[1].types.should.have.a.length(1); - registry.addNodeSet.lastCall.args[1].types[0].should.eql('test-node-3'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('config'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('help'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('namespace','node-red'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('err','fail'); + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("TestNode3"); + module.nodes.TestNode3.should.have.property("id","node-red/TestNode3"); + module.nodes.TestNode3.should.have.property("module","node-red"); + module.nodes.TestNode3.should.have.property("name","TestNode3"); + module.nodes.TestNode3.should.have.property("file"); + module.nodes.TestNode3.should.have.property("template"); + module.nodes.TestNode3.should.have.property("enabled",true); + module.nodes.TestNode3.should.have.property("loaded",false); + module.nodes.TestNode3.should.have.property("types"); + module.nodes.TestNode3.types.should.have.a.length(1); + module.nodes.TestNode3.types[0].should.eql('test-node-3'); + module.nodes.TestNode3.should.have.property("config"); + module.nodes.TestNode3.should.have.property("help"); + module.nodes.TestNode3.should.have.property("namespace","node-red"); + module.nodes.TestNode3.should.have.property('err','fail'); - nodes.registerType.calledOnce.should.be.false(); + nodes.registerType.called.should.be.false(); done(); }).catch(function(err) { @@ -277,6 +300,7 @@ describe("red/nodes/registry/loader",function() { var result = {}; result["node-red"] = { "name": "node-red", + "version":"1.2.3", "nodes": { "DoesNotExist": { "file": path.join(resourcesDir,"doesnotexist"), @@ -289,28 +313,34 @@ describe("red/nodes/registry/loader",function() { })); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); - stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); // This module isn't already loaded stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { - registry.addNodeSet.called.should.be.true(); - registry.addNodeSet.lastCall.args[0].should.eql("node-red/DoesNotExist"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('id',"node-red/DoesNotExist"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('module',"node-red"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('enabled',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('loaded',false); - registry.addNodeSet.lastCall.args[1].should.have.a.property('version',undefined); - registry.addNodeSet.lastCall.args[1].should.have.a.property('types'); - registry.addNodeSet.lastCall.args[1].types.should.have.a.length(0); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('config'); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('help'); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('namespace','node-red'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('err'); + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("DoesNotExist"); + module.nodes.DoesNotExist.should.have.property("id","node-red/DoesNotExist"); + module.nodes.DoesNotExist.should.have.property("module","node-red"); + module.nodes.DoesNotExist.should.have.property("name","DoesNotExist"); + module.nodes.DoesNotExist.should.have.property("file"); + module.nodes.DoesNotExist.should.have.property("template"); + module.nodes.DoesNotExist.should.have.property("enabled",true); + module.nodes.DoesNotExist.should.have.property("loaded",false); + module.nodes.DoesNotExist.should.have.property("types"); + module.nodes.DoesNotExist.types.should.have.a.length(0); + module.nodes.DoesNotExist.should.not.have.property("config"); + module.nodes.DoesNotExist.should.not.have.property("help"); + module.nodes.DoesNotExist.should.not.have.property("namespace","node-red"); + module.nodes.DoesNotExist.should.have.property('err'); - nodes.registerType.calledOnce.should.be.false(); + nodes.registerType.called.should.be.false(); done(); }).catch(function(err) { @@ -323,6 +353,7 @@ describe("red/nodes/registry/loader",function() { var result = {}; result["node-red"] = { "name": "node-red", + "version": "1.2.3", "nodes": { "DuffNode": { "file": path.join(resourcesDir,"DuffNode","DuffNode.js"), @@ -335,29 +366,36 @@ describe("red/nodes/registry/loader",function() { })); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return })); - stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); // This module isn't already loaded stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { - registry.addNodeSet.called.should.be.true(); - registry.addNodeSet.lastCall.args[0].should.eql("node-red/DuffNode"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('id',"node-red/DuffNode"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('module',"node-red"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('enabled',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('loaded',false); - registry.addNodeSet.lastCall.args[1].should.have.a.property('version',undefined); - registry.addNodeSet.lastCall.args[1].should.have.a.property('types'); - registry.addNodeSet.lastCall.args[1].types.should.have.a.length(0); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('config'); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('help'); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('namespace','node-red'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('err'); - registry.addNodeSet.lastCall.args[1].err.should.endWith("DuffNode.html does not exist"); - nodes.registerType.calledOnce.should.be.false(); + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","node-red"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("DuffNode"); + module.nodes.DuffNode.should.have.property("id","node-red/DuffNode"); + module.nodes.DuffNode.should.have.property("module","node-red"); + module.nodes.DuffNode.should.have.property("name","DuffNode"); + module.nodes.DuffNode.should.have.property("file"); + module.nodes.DuffNode.should.have.property("template"); + module.nodes.DuffNode.should.have.property("enabled",true); + module.nodes.DuffNode.should.have.property("loaded",false); + module.nodes.DuffNode.should.have.property("types"); + module.nodes.DuffNode.types.should.have.a.length(0); + module.nodes.DuffNode.should.not.have.property("config"); + module.nodes.DuffNode.should.not.have.property("help"); + module.nodes.DuffNode.should.not.have.property("namespace","node-red"); + module.nodes.DuffNode.should.have.property('err'); + module.nodes.DuffNode.err.should.endWith("DuffNode.html does not exist"); + + nodes.registerType.called.should.be.false(); done(); }).catch(function(err) { @@ -368,7 +406,7 @@ describe("red/nodes/registry/loader",function() { describe("#addModule",function() { it("throws error if settings unavailable", function() { - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return false;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return false;}}}); /*jshint immed: false */ (function(){ loader.addModule("test-module"); @@ -377,7 +415,7 @@ describe("red/nodes/registry/loader",function() { it("returns rejected error if module already loaded", function(done) { stubs.push(sinon.stub(registry,"getModuleInfo",function(){return{}})); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.addModule("test-module").catch(function(err) { err.code.should.eql("module_already_loaded"); @@ -389,7 +427,7 @@ describe("red/nodes/registry/loader",function() { stubs.push(sinon.stub(localfilesystem,"getModuleFiles",function() { throw new Error("failure"); })); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.addModule("test-module").catch(function(err) { err.message.should.eql("failure"); done(); @@ -419,25 +457,32 @@ describe("red/nodes/registry/loader",function() { })); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" })); - stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); + loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}}); loader.addModule("TestNodeModule").then(function(result) { result.should.eql("a node list"); - registry.addNodeSet.calledOnce.should.be.true(); - registry.addNodeSet.lastCall.args[0].should.eql("TestNodeModule/TestNode1"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('id',"TestNodeModule/TestNode1"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('module',"TestNodeModule"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('enabled',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('loaded',true); - registry.addNodeSet.lastCall.args[1].should.have.a.property('version',"1.2.3"); - registry.addNodeSet.lastCall.args[1].should.have.a.property('types'); - registry.addNodeSet.lastCall.args[1].types.should.have.a.length(1); - registry.addNodeSet.lastCall.args[1].types[0].should.eql('test-node-mod-1'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('config'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('help'); - registry.addNodeSet.lastCall.args[1].should.have.a.property('namespace','TestNodeModule'); - registry.addNodeSet.lastCall.args[1].should.not.have.a.property('err'); + + registry.addModule.called.should.be.true(); + var module = registry.addModule.lastCall.args[0]; + module.should.have.property("name","TestNodeModule"); + module.should.have.property("version","1.2.3"); + module.should.have.property("nodes"); + module.nodes.should.have.property("TestNode1"); + module.nodes.TestNode1.should.have.property("id","TestNodeModule/TestNode1"); + module.nodes.TestNode1.should.have.property("module","TestNodeModule"); + module.nodes.TestNode1.should.have.property("name","TestNode1"); + module.nodes.TestNode1.should.have.property("file"); + module.nodes.TestNode1.should.have.property("template"); + module.nodes.TestNode1.should.have.property("enabled",true); + module.nodes.TestNode1.should.have.property("loaded",true); + module.nodes.TestNode1.should.have.property("types"); + module.nodes.TestNode1.types.should.have.a.length(1); + module.nodes.TestNode1.types[0].should.eql('test-node-mod-1'); + module.nodes.TestNode1.should.have.property("config"); + module.nodes.TestNode1.should.have.property("help"); + module.nodes.TestNode1.should.have.property("namespace","TestNodeModule"); + module.nodes.TestNode1.should.not.have.property('err'); nodes.registerType.calledOnce.should.be.true(); done(); @@ -469,12 +514,12 @@ describe("red/nodes/registry/loader",function() { })); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" })); - stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); + stubs.push(sinon.stub(registry,"addModule", function(){ return })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({log:{"_":function(){},warn:function(){}},nodes:nodes,i18n:{defaultLang:"en-US"},events:{on:function(){},removeListener:function(){}},version: function() { return "0.12.0"}, settings:{available:function(){return true;}}}); + loader.init({log:{"_":function(){},warn:function(){}},nodes:nodes,version: function() { return "0.12.0"}, settings:{available:function(){return true;}}}); loader.addModule("TestNodeModule").then(function(result) { result.should.eql("a node list"); - registry.addNodeSet.called.should.be.false(); + registry.addModule.called.should.be.false(); nodes.registerType.called.should.be.false(); done(); }).catch(function(err) { diff --git a/test/red/runtime/nodes/registry/localfilesystem_spec.js b/test/red/runtime-registry/localfilesystem_spec.js similarity index 60% rename from test/red/runtime/nodes/registry/localfilesystem_spec.js rename to test/red/runtime-registry/localfilesystem_spec.js index d240e2ca5..c5f55da7c 100644 --- a/test/red/runtime/nodes/registry/localfilesystem_spec.js +++ b/test/red/runtime-registry/localfilesystem_spec.js @@ -19,13 +19,19 @@ var when = require("when"); var sinon = require("sinon"); var path = require("path"); -var localfilesystem = require("../../../../../red/runtime/nodes/registry/localfilesystem"); +var localfilesystem = require("../../../red/runtime-registry/localfilesystem"); -var resourcesDir = path.resolve(path.join(__dirname,"..","resources","local")); -var userDir = path.resolve(path.join(__dirname,"..","resources","userDir")); -var moduleDir = path.resolve(path.join(__dirname,"..","resources","local","TestNodeModule")); +var resourcesDir = path.resolve(path.join(__dirname,"resources","local")); +var userDir = path.resolve(path.join(__dirname,"resources","userDir")); +var moduleDir = path.resolve(path.join(__dirname,"resources","local","TestNodeModule")); + +var i18n = require("../../../red/util").i18n; // TODO: separate module describe("red/nodes/registry/localfilesystem",function() { + beforeEach(function() { + stubs.push(sinon.stub(i18n,"registerMessageCatalog", function() { return Promise.resolve(); })); + }) + var stubs = []; afterEach(function() { while(stubs.length) { @@ -46,7 +52,7 @@ describe("red/nodes/registry/localfilesystem",function() { } describe("#getNodeFiles",function() { it("Finds all the node files in the resources tree",function(done) { - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{coreNodesDir:resourcesDir}}); + localfilesystem.init({settings:{coreNodesDir:resourcesDir}}); var nodeList = localfilesystem.getNodeFiles(true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -54,10 +60,14 @@ describe("red/nodes/registry/localfilesystem",function() { nm.should.have.a.property("nodes"); var nodes = nm.nodes; checkNodes(nm.nodes,['TestNode1','MultipleNodes1','NestedNode','TestNode2','TestNode3','TestNode4'],['TestNodeModule']); + i18n.registerMessageCatalog.called.should.be.true(); + i18n.registerMessageCatalog.lastCall.args[0].should.eql('node-red'); + i18n.registerMessageCatalog.lastCall.args[1].should.eql(path.resolve(path.join(resourcesDir,"core","locales"))); + i18n.registerMessageCatalog.lastCall.args[2].should.eql('messages.json'); done(); }); it("Includes node files from settings",function(done) { - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{nodesIncludes:['TestNode1.js'],coreNodesDir:resourcesDir}}); + localfilesystem.init({settings:{nodesIncludes:['TestNode1.js'],coreNodesDir:resourcesDir}}); var nodeList = localfilesystem.getNodeFiles(true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -67,7 +77,7 @@ describe("red/nodes/registry/localfilesystem",function() { done(); }); it("Excludes node files from settings",function(done) { - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{nodesExcludes:['TestNode1.js'],coreNodesDir:resourcesDir}}); + localfilesystem.init({settings:{nodesExcludes:['TestNode1.js'],coreNodesDir:resourcesDir}}); var nodeList = localfilesystem.getNodeFiles(true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -77,7 +87,7 @@ describe("red/nodes/registry/localfilesystem",function() { done(); }); it("Finds nodes in userDir/nodes",function(done) { - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{userDir:userDir,coreNodesDir:__dirname}}); + localfilesystem.init({settings:{userDir:userDir}}); var nodeList = localfilesystem.getNodeFiles(true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -88,7 +98,7 @@ describe("red/nodes/registry/localfilesystem",function() { }); it("Finds nodes in settings.nodesDir (string)",function(done) { - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{nodesDir:userDir,coreNodesDir:__dirname}}); + localfilesystem.init({settings:{nodesDir:userDir}}); var nodeList = localfilesystem.getNodeFiles(true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -97,19 +107,19 @@ describe("red/nodes/registry/localfilesystem",function() { checkNodes(nm.nodes,['TestNode5'],['TestNode1']); done(); }); - it("Finds nodes in settings.nodesDir (string,relative path)",function(done) { - var relativeUserDir = path.join("test","red","runtime","nodes","resources","userDir"); - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{nodesDir:relativeUserDir,coreNodesDir:__dirname}}); - var nodeList = localfilesystem.getNodeFiles(true); - nodeList.should.have.a.property("node-red"); - var nm = nodeList['node-red']; - nm.should.have.a.property('name','node-red'); - nm.should.have.a.property("nodes"); - checkNodes(nm.nodes,['TestNode5'],['TestNode1']); - done(); - }); - it("Finds nodes in settings.nodesDir (array)",function(done) { - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{nodesDir:[userDir],coreNodesDir:__dirname}}); + it("Finds nodes in settings.nodesDir (string,relative path)",function(done) { + var relativeUserDir = path.join("test","red","runtime-registry","resources","userDir"); + localfilesystem.init({settings:{nodesDir:relativeUserDir}}); + var nodeList = localfilesystem.getNodeFiles(true); + nodeList.should.have.a.property("node-red"); + var nm = nodeList['node-red']; + nm.should.have.a.property('name','node-red'); + nm.should.have.a.property("nodes"); + checkNodes(nm.nodes,['TestNode5'],['TestNode1']); + done(); + }); + it("Finds nodes in settings.nodesDir (array)",function(done) { + localfilesystem.init({settings:{nodesDir:[userDir]}}); var nodeList = localfilesystem.getNodeFiles(true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -128,7 +138,7 @@ describe("red/nodes/registry/localfilesystem",function() { } return _join.apply(null,arguments); })); - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{coreNodesDir:moduleDir}}); + localfilesystem.init({settings:{coreNodesDir:moduleDir}}); var nodeList = localfilesystem.getNodeFiles(); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -146,6 +156,13 @@ describe("red/nodes/registry/localfilesystem",function() { nm.should.have.a.property("nodes"); checkNodes(nm.nodes,['VersionMismatchMod1','VersionMismatchMod2'],[],'VersionMismatchModule'); + i18n.registerMessageCatalog.called.should.be.true(); + i18n.registerMessageCatalog.lastCall.args[0].should.eql('node-red'); + i18n.registerMessageCatalog.lastCall.args[1].should.eql(path.resolve(path.join(moduleDir,"core","locales"))); + i18n.registerMessageCatalog.lastCall.args[2].should.eql('messages.json'); + + + done(); }); it.skip("finds locales directory"); @@ -153,42 +170,58 @@ describe("red/nodes/registry/localfilesystem",function() { it("scans icon files in the resources tree",function(done) { var count = 0; localfilesystem.init({ - i18n:{registerMessageCatalog:function(){}}, - events:{emit:function(eventName,dir){ - if (count === 0) { - eventName.should.equal("node-icon-dir"); - dir.name.should.equal("node-red"); - dir.icons.should.be.an.Array(); - count = 1; - } else if (count === 1) { - done(); - } - }}, + + // events:{emit:function(eventName,dir){ + // if (count === 0) { + // eventName.should.equal("node-icon-dir"); + // dir.name.should.equal("node-red"); + // dir.icons.should.be.an.Array(); + // count = 1; + // } else if (count === 1) { + // done(); + // } + // }}, settings:{coreNodesDir:resourcesDir} }); - localfilesystem.getNodeFiles(true); + var list = localfilesystem.getNodeFiles(true); + list.should.have.property("node-red"); + list["node-red"].should.have.property("icons"); + list["node-red"].icons.should.have.length(2); + list["node-red"].icons[1].should.have.property("path",path.join(__dirname,"resources/local/NestedDirectoryNode/NestedNode/icons")) + list["node-red"].icons[1].should.have.property("icons"); + list["node-red"].icons[1].icons.should.have.length(1); + list["node-red"].icons[1].icons[0].should.eql("arrow-in.png"); + done(); }); it("scans icons dir in library",function(done) { var count = 0; localfilesystem.init({ - i18n:{registerMessageCatalog:function(){}}, - events:{emit:function(eventName,dir){ - eventName.should.equal("node-icon-dir"); - if (count === 0) { - dir.name.should.equal("node-red"); - dir.icons.should.be.an.Array(); - count = 1; - } else if (count === 1) { - dir.name.should.equal("Library"); - dir.icons.should.be.an.Array(); - dir.icons.length.should.equal(1); - dir.icons[0].should.be.equal("test_icon.png"); - done(); - } - }}, + // + // events:{emit:function(eventName,dir){ + // eventName.should.equal("node-icon-dir"); + // if (count === 0) { + // dir.name.should.equal("node-red"); + // dir.icons.should.be.an.Array(); + // count = 1; + // } else if (count === 1) { + // dir.name.should.equal("Library"); + // dir.icons.should.be.an.Array(); + // dir.icons.length.should.equal(1); + // dir.icons[0].should.be.equal("test_icon.png"); + // done(); + // } + // }}, settings:{userDir:userDir} }); - localfilesystem.getNodeFiles(true); + var list = localfilesystem.getNodeFiles(true); + list.should.have.property("node-red"); + list["node-red"].should.have.property("icons"); + list["node-red"].icons.should.have.length(2); + list["node-red"].icons[1].should.have.property("path",path.join(__dirname,"resources/userDir/lib/icons")) + list["node-red"].icons[1].should.have.property("icons"); + list["node-red"].icons[1].icons.should.have.length(1); + list["node-red"].icons[1].icons[0].should.eql("test_icon.png"); + done(); }); }); describe("#getModuleFiles",function() { @@ -202,7 +235,7 @@ describe("red/nodes/registry/localfilesystem",function() { } return _join.apply(null,arguments); })); - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{coreNodesDir:moduleDir}}); + localfilesystem.init({settings:{coreNodesDir:moduleDir}}); var nodeModule = localfilesystem.getModuleFiles('TestNodeModule'); nodeModule.should.have.a.property('TestNodeModule'); nodeModule['TestNodeModule'].should.have.a.property('name','TestNodeModule'); @@ -226,7 +259,7 @@ describe("red/nodes/registry/localfilesystem",function() { } return _join.apply(null,arguments); })); - localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{coreNodesDir:moduleDir}}); + localfilesystem.init({settings:{coreNodesDir:moduleDir}}); /*jshint immed: false */ (function(){ localfilesystem.getModuleFiles('WontExistModule'); @@ -246,16 +279,24 @@ describe("red/nodes/registry/localfilesystem",function() { return _join.apply(null,arguments); })); localfilesystem.init({ - i18n:{registerMessageCatalog:function(){}}, - events:{emit:function(eventName,dir){ - eventName.should.equal("node-icon-dir"); - dir.name.should.equal("TestNodeModule"); - dir.icons.should.be.an.Array(); - done(); - }}, + + // events:{emit:function(eventName,dir){ + // eventName.should.equal("node-icon-dir"); + // dir.name.should.equal("TestNodeModule"); + // dir.icons.should.be.an.Array(); + // done(); + // }}, settings:{coreNodesDir:moduleDir} }); var nodeModule = localfilesystem.getModuleFiles('TestNodeModule'); + nodeModule.should.have.property("TestNodeModule"); + nodeModule.TestNodeModule.should.have.property('icons'); + + nodeModule.TestNodeModule.icons.should.have.length(1); + nodeModule.TestNodeModule.icons[0].should.have.property("path"); + nodeModule.TestNodeModule.icons[0].should.have.property("icons"); + nodeModule.TestNodeModule.icons[0].icons[0].should.eql("arrow-in.png"); + done(); }); }); }); diff --git a/test/red/runtime/nodes/registry/registry_spec.js b/test/red/runtime-registry/registry_spec.js similarity index 73% rename from test/red/runtime/nodes/registry/registry_spec.js rename to test/red/runtime-registry/registry_spec.js index c6f3e19af..f1af29f86 100644 --- a/test/red/runtime/nodes/registry/registry_spec.js +++ b/test/red/runtime-registry/registry_spec.js @@ -19,13 +19,10 @@ var when = require("when"); var sinon = require("sinon"); var path = require("path"); -var typeRegistry = require("../../../../../red/runtime/nodes/registry/registry"); +var typeRegistry = require("../../../red/runtime-registry/registry"); +var EventEmitter = require('events'); -var Node = require("../../../../../red/runtime/nodes/Node"); - -var events = require("../../../../../red/runtime/events"); - -var inherits = require("util").inherits; +var events = new EventEmitter(); describe("red/nodes/registry/registry",function() { @@ -86,7 +83,7 @@ describe("red/nodes/registry/registry",function() { describe('#init/load', function() { it('loads initial config', function(done) { - typeRegistry.init(settingsWithStorageAndInitialConfig); + typeRegistry.init(settingsWithStorageAndInitialConfig,null,events); typeRegistry.getNodeList().should.have.lengthOf(0); typeRegistry.load(); typeRegistry.getNodeList().should.have.lengthOf(1); @@ -123,7 +120,7 @@ describe("red/nodes/registry/registry",function() { }} }; 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); + typeRegistry.init(legacySettings,null,events); typeRegistry.load(); legacySettings.set.calledOnce.should.be.true(); legacySettings.set.args[0][1].should.eql(expected); @@ -132,10 +129,10 @@ describe("red/nodes/registry/registry",function() { }); - describe('#addNodeSet', function() { + describe.skip('#addNodeSet', function() { it('adds a node set for an unknown module', function() { - typeRegistry.init(settings); + typeRegistry.init(settings,null,events); typeRegistry.getNodeList().should.have.lengthOf(0); typeRegistry.getModuleList().should.eql({}); @@ -164,7 +161,7 @@ describe("red/nodes/registry/registry",function() { it('adds a node set to an existing module', function() { - typeRegistry.init(settings); + typeRegistry.init(settings,null,events); typeRegistry.getNodeList().should.have.lengthOf(0); typeRegistry.getModuleList().should.eql({}); @@ -193,7 +190,7 @@ describe("red/nodes/registry/registry",function() { }); it('doesnt add node set types if node set has an error', function() { - typeRegistry.init(settings); + typeRegistry.init(settings,null,events); typeRegistry.getNodeList().should.have.lengthOf(0); typeRegistry.getModuleList().should.eql({}); @@ -209,7 +206,7 @@ describe("red/nodes/registry/registry",function() { }); it('doesnt add node set if type already exists', function() { - typeRegistry.init(settings); + typeRegistry.init(settings,null,events); typeRegistry.getNodeList().should.have.lengthOf(0); typeRegistry.getModuleList().should.eql({}); @@ -243,7 +240,7 @@ describe("red/nodes/registry/registry",function() { describe("#enableNodeSet", function() { it('throws error if settings unavailable', function() { - typeRegistry.init(settings); + typeRegistry.init(settings,null,events); /*jshint immed: false */ (function(){ typeRegistry.enableNodeSet("test-module/test-name"); @@ -251,7 +248,7 @@ describe("red/nodes/registry/registry",function() { }); it('throws error if module unknown', function() { - typeRegistry.init(settingsWithStorageAndInitialConfig); + typeRegistry.init(settingsWithStorageAndInitialConfig,null,events); /*jshint immed: false */ (function(){ typeRegistry.enableNodeSet("test-module/unknown"); @@ -262,7 +259,7 @@ describe("red/nodes/registry/registry",function() { }); describe("#disableNodeSet", function() { it('throws error if settings unavailable', function() { - typeRegistry.init(settings); + typeRegistry.init(settings,null,events); /*jshint immed: false */ (function(){ typeRegistry.disableNodeSet("test-module/test-name"); @@ -270,7 +267,7 @@ describe("red/nodes/registry/registry",function() { }); it('throws error if module unknown', function() { - typeRegistry.init(settingsWithStorageAndInitialConfig); + typeRegistry.init(settingsWithStorageAndInitialConfig,null,events); /*jshint immed: false */ (function(){ typeRegistry.disableNodeSet("test-module/unknown"); @@ -281,7 +278,7 @@ describe("red/nodes/registry/registry",function() { describe('#getNodeConfig', function() { it('returns nothing for an unregistered type config', function(done) { - typeRegistry.init(settings); + typeRegistry.init(settings,null,events); var config = typeRegistry.getNodeConfig("imaginary-shark"); (config === null).should.be.true(); done(); @@ -290,26 +287,32 @@ describe("red/nodes/registry/registry",function() { describe('#saveNodeList',function() { it('rejects when settings unavailable',function(done) { - typeRegistry.init(stubSettings({},false,{})); - typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); + typeRegistry.init(stubSettings({},false,{}),null,events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: {"test-name":{module:"test-module",name:"test-name",types:[]}}}); typeRegistry.saveNodeList().catch(function(err) { done(); }); }); it('saves the list',function(done) { var s = stubSettings({},true,{}); - typeRegistry.init(s); - typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); - typeRegistry.addNodeSet("test-module/test-name-2",testNodeSet2WithError, "0.0.1"); + typeRegistry.init(s,null,events); + + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":testNodeSet1, + "test-name-2":testNodeSet2WithError + }}); + typeRegistry.saveNodeList().then(function() { s.set.called.should.be.true(); s.set.lastCall.args[0].should.eql('nodes'); var nodes = s.set.lastCall.args[1]; nodes.should.have.property('test-module'); for (var n in nodes['test-module'].nodes) { - var nn = nodes['test-module'].nodes[n]; - nn.should.not.have.property('err'); - nn.should.not.have.property('id'); + if (nodes['test-module'].nodes.hasOwnProperty(n)) { + var nn = nodes['test-module'].nodes[n]; + nn.should.not.have.property('err'); + nn.should.not.have.property('id'); + } } done(); }).catch(function(err) { @@ -321,7 +324,7 @@ describe("red/nodes/registry/registry",function() { describe('#removeModule',function() { it('throws error for unknown module', function() { var s = stubSettings({},true,{}); - typeRegistry.init(s); + typeRegistry.init(s,null,events); /*jshint immed: false */ (function(){ typeRegistry.removeModule("test-module/unknown"); @@ -329,7 +332,7 @@ describe("red/nodes/registry/registry",function() { }); it('throws error for unavaiable settings', function() { var s = stubSettings({},false,{}); - typeRegistry.init(s); + typeRegistry.init(s,null,events); /*jshint immed: false */ (function(){ typeRegistry.removeModule("test-module/unknown"); @@ -337,8 +340,10 @@ describe("red/nodes/registry/registry",function() { }); it('removes a known module', function() { var s = stubSettings({},true,{}); - typeRegistry.init(s); - typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1"); + typeRegistry.init(s,null,events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":testNodeSet1 + }}); var moduleList = typeRegistry.getModuleList(); moduleList.should.have.a.property("test-module"); typeRegistry.getNodeList().should.have.lengthOf(1); @@ -354,45 +359,48 @@ describe("red/nodes/registry/registry",function() { it('returns node config', function() { typeRegistry.init(settings,{ getNodeHelp: function(config) { return "HE"+config.name+"LP" } - }); - typeRegistry.addNodeSet("test-module/test-name",{ - id: "test-module/test-name", - module: "test-module", - name: "test-name", - enabled: true, - loaded: false, - config: "configA", - types: [ "test-a","test-b"] - }, "0.0.1"); - typeRegistry.getNodeConfig("test-module/test-name").should.eql('configAHEtest-nameLP'); - typeRegistry.getAllNodeConfigs().should.eql('configAHEtest-nameLP'); + },events); - typeRegistry.addNodeSet("test-module/test-name-2",{ - id: "test-module/test-name-2", - module: "test-module", - name: "test-name-2", - enabled: true, - loaded: false, - config: "configB", - types: [ "test-c","test-d"] - }, "0.0.1"); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"] + }, + "test-name-2":{ + id: "test-module/test-name-2", + module: "test-module", + name: "test-name-2", + enabled: true, + loaded: false, + config: "configB", + types: [ "test-c","test-d"] + } + }}); + typeRegistry.getNodeConfig("test-module/test-name").should.eql('configAHEtest-nameLP'); typeRegistry.getNodeConfig("test-module/test-name-2").should.eql('configBHEtest-name-2LP'); typeRegistry.getAllNodeConfigs().should.eql('configAHEtest-nameLPconfigBHEtest-name-2LP'); }); }); describe('#getModuleInfo', function() { it('returns module info', function() { - typeRegistry.init(settings,{}); - typeRegistry.addNodeSet("test-module/test-name",{ - id: "test-module/test-name", - module: "test-module", - name: "test-name", - enabled: true, - loaded: false, - config: "configA", - types: [ "test-a","test-b"], - file: "abc" - }, "0.0.1"); + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + } + }}); var moduleInfo = typeRegistry.getModuleInfo("test-module"); moduleInfo.should.have.a.property('name','test-module'); moduleInfo.should.have.a.property('version','0.0.1'); @@ -404,17 +412,19 @@ describe("red/nodes/registry/registry",function() { }); describe('#getNodeInfo', function() { it('returns node info', function() { - typeRegistry.init(settings,{}); - typeRegistry.addNodeSet("test-module/test-name",{ - id: "test-module/test-name", - module: "test-module", - name: "test-name", - enabled: true, - loaded: false, - config: "configA", - types: [ "test-a","test-b"], - file: "abc" - }, "0.0.1"); + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + } + }}); var nodeSetInfo = typeRegistry.getNodeInfo("test-module/test-name"); nodeSetInfo.should.have.a.property('id',"test-module/test-name"); nodeSetInfo.should.not.have.a.property('config'); @@ -423,18 +433,20 @@ describe("red/nodes/registry/registry",function() { }); describe('#getFullNodeInfo', function() { it('returns node info', function() { - typeRegistry.init(settings,{}); - typeRegistry.addNodeSet("test-module/test-name",{ - id: "test-module/test-name", - module: "test-module", - name: "test-name", - enabled: true, - loaded: false, - config: "configA", - types: [ "test-a","test-b"], - file: "abc" + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" - }, "0.0.1"); + } + }}); var nodeSetInfo = typeRegistry.getFullNodeInfo("test-module/test-name"); nodeSetInfo.should.have.a.property('id',"test-module/test-name"); nodeSetInfo.should.have.a.property('config'); @@ -446,27 +458,29 @@ describe("red/nodes/registry/registry",function() { }); describe('#getNodeList', function() { it("returns a filtered list", function() { - typeRegistry.init(settings,{}); - typeRegistry.addNodeSet("test-module/test-name",{ - id: "test-module/test-name", - module: "test-module", - name: "test-name", - enabled: true, - loaded: false, - config: "configA", - types: [ "test-a","test-b"], - file: "abc" - }, "0.0.1"); - typeRegistry.addNodeSet("test-module/test-name-2",{ - id: "test-module/test-name-2", - module: "test-module", - name: "test-name-2", - enabled: true, - loaded: false, - config: "configB", - types: [ "test-c","test-d"], - file: "def" - }, "0.0.1"); + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + }, + "test-name-2":{ + id: "test-module/test-name-2", + module: "test-module", + name: "test-name-2", + enabled: true, + loaded: false, + config: "configB", + types: [ "test-c","test-d"], + file: "def" + } + }}); var filterCallCount = 0; var filteredList = typeRegistry.getNodeList(function(n) { filterCallCount++; return n.name === 'test-name-2';}); filterCallCount.should.eql(2); @@ -478,8 +492,7 @@ describe("red/nodes/registry/registry",function() { describe('#registerNodeConstructor', function() { var TestNodeConstructor; beforeEach(function() { - TestNodeConstructor = function TestNodeConstructor() { - }; + TestNodeConstructor = function TestNodeConstructor() {}; sinon.stub(events,'emit'); }); afterEach(function() { @@ -502,44 +515,36 @@ describe("red/nodes/registry/registry",function() { }).should.throw("node-type already registered"); events.emit.calledOnce.should.be.true(); }); - it('extends a constructor with the Node constructor', function() { - TestNodeConstructor.prototype.should.not.be.an.instanceOf(Node); - typeRegistry.registerNodeConstructor('node-set','node-type',TestNodeConstructor); - TestNodeConstructor.prototype.should.be.an.instanceOf(Node); - }); - it('does not override a constructor\'s prototype', function() { - function Foo(){}; - inherits(TestNodeConstructor,Foo); - TestNodeConstructor.prototype.should.be.an.instanceOf(Foo); - TestNodeConstructor.prototype.should.not.be.an.instanceOf(Node); - - typeRegistry.registerNodeConstructor('node-set','node-type',TestNodeConstructor); - - TestNodeConstructor.prototype.should.be.an.instanceOf(Node); - TestNodeConstructor.prototype.should.be.an.instanceOf(Foo); - - typeRegistry.registerNodeConstructor('node-set','node-type2',TestNodeConstructor); - TestNodeConstructor.prototype.should.be.an.instanceOf(Node); - TestNodeConstructor.prototype.should.be.an.instanceOf(Foo); - }); }); describe('#getNodeIconPath', function() { it('returns the default icon when getting an unknown icon', function() { - var defaultIcon = path.resolve(__dirname+'/../../../../../public/icons/arrow-in.png'); + var defaultIcon = path.resolve(__dirname+'/../../../public/icons/arrow-in.png'); var iconPath = typeRegistry.getNodeIconPath('random-module','youwonthaveme.png'); iconPath.should.eql(defaultIcon); }); it('returns a registered icon' , function() { - var testIcon = path.resolve(__dirname+'/../../../../resources/icons/test_icon.png'); - events.emit("node-icon-dir",{name:"test-module", path: path.resolve(__dirname+'/../../../../resources/icons'), icons:[]}); + var testIcon = path.resolve(__dirname+'/resources/userDir/lib/icons/'); + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + } + },icons: [{path:testIcon,icons:['test_icon.png']}]}); var iconPath = typeRegistry.getNodeIconPath('test-module','test_icon.png'); - iconPath.should.eql(testIcon); + iconPath.should.eql(testIcon+"/test_icon.png"); }); it('returns the debug icon when getting an unknown module', function() { - var debugIcon = path.resolve(__dirname+'/../../../../../public/icons/debug.png'); + var debugIcon = path.resolve(__dirname+'/../../../public/icons/debug.png'); var iconPath = typeRegistry.getNodeIconPath('unknown-module', 'debug.png'); iconPath.should.eql(debugIcon); }); @@ -552,16 +557,22 @@ describe("red/nodes/registry/registry",function() { }); it('returns an icon list of registered node module', function() { - typeRegistry.addNodeSet("test-module/test-name",testNodeSet1,"0.0.1"); - events.emit("node-icon-dir",{name:"test-module", path:"",icons:["test_icon1.png"]}); + var testIcon = path.resolve(__dirname+'/resources/userDir/lib/icons/'); + typeRegistry.init(settings,{},events); + typeRegistry.addModule({name: "test-module",version:"0.0.1",nodes: { + "test-name":{ + id: "test-module/test-name", + module: "test-module", + name: "test-name", + enabled: true, + loaded: false, + config: "configA", + types: [ "test-a","test-b"], + file: "abc" + } + },icons: [{path:testIcon,icons:['test_icon.png']}]}); var iconList = typeRegistry.getNodeIcons(); - iconList.should.eql({"test-module":["test_icon1.png"]}); - }); - - it('returns an icon list of unregistered node module', function() { - events.emit("node-icon-dir",{name:"test-module", path:"", icons:["test_icon1.png", "test_icon2.png"]}); - var iconList = typeRegistry.getNodeIcons(); - iconList.should.eql({"test-module":["test_icon1.png","test_icon2.png"]}); + iconList.should.eql({"test-module":["test_icon.png"]}); }); }); diff --git a/test/resources/examples/one.json b/test/red/runtime-registry/resources/examples/one.json similarity index 100% rename from test/resources/examples/one.json rename to test/red/runtime-registry/resources/examples/one.json diff --git a/test/red/runtime/nodes/resources/local/DuffNode/DuffNode.js b/test/red/runtime-registry/resources/local/DuffNode/DuffNode.js similarity index 100% rename from test/red/runtime/nodes/resources/local/DuffNode/DuffNode.js rename to test/red/runtime-registry/resources/local/DuffNode/DuffNode.js diff --git a/test/red/runtime/nodes/resources/local/DuplicateTestNode/TestNode1.html b/test/red/runtime-registry/resources/local/DuplicateTestNode/TestNode1.html similarity index 100% rename from test/red/runtime/nodes/resources/local/DuplicateTestNode/TestNode1.html rename to test/red/runtime-registry/resources/local/DuplicateTestNode/TestNode1.html diff --git a/test/red/runtime/nodes/resources/local/DuplicateTestNode/TestNode1.js b/test/red/runtime-registry/resources/local/DuplicateTestNode/TestNode1.js similarity index 100% rename from test/red/runtime/nodes/resources/local/DuplicateTestNode/TestNode1.js rename to test/red/runtime-registry/resources/local/DuplicateTestNode/TestNode1.js diff --git a/test/red/runtime/nodes/resources/local/MultipleNodes1/MultipleNodes1.html b/test/red/runtime-registry/resources/local/MultipleNodes1/MultipleNodes1.html similarity index 100% rename from test/red/runtime/nodes/resources/local/MultipleNodes1/MultipleNodes1.html rename to test/red/runtime-registry/resources/local/MultipleNodes1/MultipleNodes1.html diff --git a/test/red/runtime/nodes/resources/local/MultipleNodes1/MultipleNodes1.js b/test/red/runtime-registry/resources/local/MultipleNodes1/MultipleNodes1.js similarity index 100% rename from test/red/runtime/nodes/resources/local/MultipleNodes1/MultipleNodes1.js rename to test/red/runtime-registry/resources/local/MultipleNodes1/MultipleNodes1.js diff --git a/test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/NestedNode.html b/test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/NestedNode.html similarity index 100% rename from test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/NestedNode.html rename to test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/NestedNode.html diff --git a/test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/NestedNode.js b/test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/NestedNode.js similarity index 100% rename from test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/NestedNode.js rename to test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/NestedNode.js diff --git a/test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/icons/arrow-in.png b/test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/icons/arrow-in.png new file mode 100644 index 000000000..e38f39146 Binary files /dev/null and b/test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/icons/arrow-in.png differ diff --git a/test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.html b/test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.html similarity index 100% rename from test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.html rename to test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.html diff --git a/test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.js b/test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.js similarity index 100% rename from test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.js rename to test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/lib/ShouldNotLoad.js diff --git a/test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.html b/test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.html similarity index 100% rename from test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.html rename to test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.html diff --git a/test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.js b/test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.js similarity index 100% rename from test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.js rename to test/red/runtime-registry/resources/local/NestedDirectoryNode/NestedNode/test/ShouldNotLoad.js diff --git a/test/red/runtime/nodes/resources/local/TestNode1/TestNode1.html b/test/red/runtime-registry/resources/local/TestNode1/TestNode1.html similarity index 100% rename from test/red/runtime/nodes/resources/local/TestNode1/TestNode1.html rename to test/red/runtime-registry/resources/local/TestNode1/TestNode1.html diff --git a/test/red/runtime/nodes/resources/local/TestNode1/TestNode1.js b/test/red/runtime-registry/resources/local/TestNode1/TestNode1.js similarity index 100% rename from test/red/runtime/nodes/resources/local/TestNode1/TestNode1.js rename to test/red/runtime-registry/resources/local/TestNode1/TestNode1.js diff --git a/test/red/runtime/nodes/resources/local/TestNode2/TestNode2.html b/test/red/runtime-registry/resources/local/TestNode2/TestNode2.html similarity index 100% rename from test/red/runtime/nodes/resources/local/TestNode2/TestNode2.html rename to test/red/runtime-registry/resources/local/TestNode2/TestNode2.html diff --git a/test/red/runtime/nodes/resources/local/TestNode2/TestNode2.js b/test/red/runtime-registry/resources/local/TestNode2/TestNode2.js similarity index 100% rename from test/red/runtime/nodes/resources/local/TestNode2/TestNode2.js rename to test/red/runtime-registry/resources/local/TestNode2/TestNode2.js diff --git a/test/red/runtime/nodes/resources/local/TestNode3/TestNode3.html b/test/red/runtime-registry/resources/local/TestNode3/TestNode3.html similarity index 100% rename from test/red/runtime/nodes/resources/local/TestNode3/TestNode3.html rename to test/red/runtime-registry/resources/local/TestNode3/TestNode3.html diff --git a/test/red/runtime/nodes/resources/local/TestNode3/TestNode3.js b/test/red/runtime-registry/resources/local/TestNode3/TestNode3.js similarity index 100% rename from test/red/runtime/nodes/resources/local/TestNode3/TestNode3.js rename to test/red/runtime-registry/resources/local/TestNode3/TestNode3.js diff --git a/test/red/runtime/nodes/resources/local/TestNode4/TestNode4.html b/test/red/runtime-registry/resources/local/TestNode4/TestNode4.html similarity index 100% rename from test/red/runtime/nodes/resources/local/TestNode4/TestNode4.html rename to test/red/runtime-registry/resources/local/TestNode4/TestNode4.html diff --git a/test/red/runtime/nodes/resources/local/TestNode4/TestNode4.js b/test/red/runtime-registry/resources/local/TestNode4/TestNode4.js similarity index 100% rename from test/red/runtime/nodes/resources/local/TestNode4/TestNode4.js rename to test/red/runtime-registry/resources/local/TestNode4/TestNode4.js diff --git a/test/red/runtime/nodes/resources/userDir/lib/icons/file.txt b/test/red/runtime-registry/resources/userDir/lib/icons/file.txt similarity index 100% rename from test/red/runtime/nodes/resources/userDir/lib/icons/file.txt rename to test/red/runtime-registry/resources/userDir/lib/icons/file.txt diff --git a/test/red/runtime/nodes/resources/userDir/lib/icons/test_icon.png b/test/red/runtime-registry/resources/userDir/lib/icons/test_icon.png similarity index 100% rename from test/red/runtime/nodes/resources/userDir/lib/icons/test_icon.png rename to test/red/runtime-registry/resources/userDir/lib/icons/test_icon.png diff --git a/test/red/runtime/nodes/resources/userDir/nodes/TestNode5/TestNode5.html b/test/red/runtime-registry/resources/userDir/nodes/TestNode5/TestNode5.html similarity index 100% rename from test/red/runtime/nodes/resources/userDir/nodes/TestNode5/TestNode5.html rename to test/red/runtime-registry/resources/userDir/nodes/TestNode5/TestNode5.html diff --git a/test/red/runtime/nodes/resources/userDir/nodes/TestNode5/TestNode5.js b/test/red/runtime-registry/resources/userDir/nodes/TestNode5/TestNode5.js similarity index 100% rename from test/red/runtime/nodes/resources/userDir/nodes/TestNode5/TestNode5.js rename to test/red/runtime-registry/resources/userDir/nodes/TestNode5/TestNode5.js diff --git a/test/red/runtime/nodes/flows/Flow_spec.js b/test/red/runtime/nodes/flows/Flow_spec.js index 2cd348448..8560e0571 100644 --- a/test/red/runtime/nodes/flows/Flow_spec.js +++ b/test/red/runtime/nodes/flows/Flow_spec.js @@ -24,7 +24,7 @@ var flowUtils = require("../../../../../red/runtime/nodes/flows/util"); var Flow = require("../../../../../red/runtime/nodes/flows/Flow"); var flows = require("../../../../../red/runtime/nodes/flows"); var Node = require("../../../../../red/runtime/nodes/Node"); -var typeRegistry = require("../../../../../red/runtime/nodes/registry"); +var typeRegistry = require("../../../../../red/runtime-registry"); describe('Flow', function() { diff --git a/test/red/runtime/nodes/flows/index_spec.js b/test/red/runtime/nodes/flows/index_spec.js index c39085187..32d7be2aa 100644 --- a/test/red/runtime/nodes/flows/index_spec.js +++ b/test/red/runtime/nodes/flows/index_spec.js @@ -23,7 +23,7 @@ var RedNode = require("../../../../../red/runtime/nodes/Node"); var RED = require("../../../../../red/runtime/nodes"); var events = require("../../../../../red/runtime/events"); var credentials = require("../../../../../red/runtime/nodes/credentials"); -var typeRegistry = require("../../../../../red/runtime/nodes/registry"); +var typeRegistry = require("../../../../../red/runtime-registry"); var Flow = require("../../../../../red/runtime/nodes/flows/Flow"); describe('flows/index', function() { diff --git a/test/red/runtime/nodes/flows/util_spec.js b/test/red/runtime/nodes/flows/util_spec.js index 2cdc72fb3..dda43ce9a 100644 --- a/test/red/runtime/nodes/flows/util_spec.js +++ b/test/red/runtime/nodes/flows/util_spec.js @@ -19,7 +19,7 @@ var sinon = require("sinon"); var when = require("when"); var clone = require("clone"); var flowUtil = require("../../../../../red/runtime/nodes/flows/util"); -var typeRegistry = require("../../../../../red/runtime/nodes/registry"); +var typeRegistry = require("../../../../../red/runtime-registry"); var redUtil = require("../../../../../red/runtime/util"); describe('flows/util', function() { diff --git a/test/red/runtime/nodes/index_spec.js b/test/red/runtime/nodes/index_spec.js index f36918a10..3225581e3 100644 --- a/test/red/runtime/nodes/index_spec.js +++ b/test/red/runtime/nodes/index_spec.js @@ -19,9 +19,12 @@ var fs = require('fs-extra'); var path = require('path'); var when = require("when"); var sinon = require('sinon'); +var inherits = require("util").inherits; + var index = require("../../../../red/runtime/nodes/index"); var flows = require("../../../../red/runtime/nodes/flows"); -var registry = require("../../../../red/runtime/nodes/registry"); +var registry = require("../../../../red/runtime-registry"); +var Node = require("../../../../red/runtime/nodes/Node"); describe("red/nodes/index", function() { before(function() { @@ -122,7 +125,45 @@ describe("red/nodes/index", function() { registry.registerType.firstCall.args[2].should.eql(TestNode); }); }); + describe("extends constructor with Node constructor", function() { + var TestNodeConstructor; + before(function() { + sinon.stub(registry,"registerType"); + }); + after(function() { + registry.registerType.restore(); + }); + beforeEach(function() { + TestNodeConstructor = function TestNodeConstructor() {}; + var runtime = { + settings: settings, + storage: storage, + log: {debug:function() {}, warn:sinon.spy()}, + events: new EventEmitter() + } + index.init(runtime); + }) + it('extends a constructor with the Node constructor', function() { + TestNodeConstructor.prototype.should.not.be.an.instanceOf(Node); + index.registerType('node-set','node-type',TestNodeConstructor); + TestNodeConstructor.prototype.should.be.an.instanceOf(Node); + }); + it('does not override a constructor prototype', function() { + function Foo(){}; + inherits(TestNodeConstructor,Foo); + TestNodeConstructor.prototype.should.be.an.instanceOf(Foo); + TestNodeConstructor.prototype.should.not.be.an.instanceOf(Node); + index.registerType('node-set','node-type',TestNodeConstructor); + + TestNodeConstructor.prototype.should.be.an.instanceOf(Node); + TestNodeConstructor.prototype.should.be.an.instanceOf(Foo); + + index.registerType('node-set','node-type2',TestNodeConstructor); + TestNodeConstructor.prototype.should.be.an.instanceOf(Node); + TestNodeConstructor.prototype.should.be.an.instanceOf(Foo); + }); + }); describe("register credentials definition", function() { var http = require('http'); var express = require('express'); @@ -294,7 +335,6 @@ describe("red/nodes/index", function() { }); describe('allows modules to be removed from the registry', function() { - var registry = require("../../../../red/runtime/nodes/registry"); var randomNodeInfo = {id:"5678",types:["random"]}; var randomModuleInfo = { name:"random", diff --git a/test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/icons/file.txt b/test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/icons/file.txt deleted file mode 100644 index 59a29af14..000000000 --- a/test/red/runtime/nodes/resources/local/NestedDirectoryNode/NestedNode/icons/file.txt +++ /dev/null @@ -1,3 +0,0 @@ -This file exists just to ensure the 'icons' directory is in the repository. -TODO: a future test needs to ensure the right icon files are loaded - this - directory can be used for that diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/EmptyModule/file.txt b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/EmptyModule/file.txt deleted file mode 100644 index 0ce8dcaed..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/EmptyModule/file.txt +++ /dev/null @@ -1 +0,0 @@ -This file exists just to ensure the parent directory is in the repository. diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.html b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.html deleted file mode 100644 index 17483f7ca..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - -

this should be filtered out

diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.js b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.js deleted file mode 100644 index c79c2ceb6..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.js +++ /dev/null @@ -1,5 +0,0 @@ -// A test node that exports a function -module.exports = function(RED) { - function TestNode(n) {} - RED.nodes.registerType("test-node-mod-1",TestNode); -} diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule2.html b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule2.html deleted file mode 100644 index a1f1b6c79..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule2.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - -

this should be filtered out

diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule2.js b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule2.js deleted file mode 100644 index d359fb3f2..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/TestNodeModule2.js +++ /dev/null @@ -1,4 +0,0 @@ -// A test node that exports a function -module.exports = function(RED) { - throw new Error("fail to load"); -} diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/icons/file.txt b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/icons/file.txt deleted file mode 100644 index 59a29af14..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/icons/file.txt +++ /dev/null @@ -1,3 +0,0 @@ -This file exists just to ensure the 'icons' directory is in the repository. -TODO: a future test needs to ensure the right icon files are loaded - this - directory can be used for that diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/package.json b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/package.json deleted file mode 100644 index 8eba5b04b..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name" : "TestNodeModule", - "version" : "0.0.1", - "description" : "A test node module", - "node-red" : { - "nodes": { - "TestNodeMod1": "TestNodeModule.js", - "TestNodeMod2": "TestNodeModule2.js" - } - } -} diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule.html b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule.html deleted file mode 100644 index 17483f7ca..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - -

this should be filtered out

diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule.js b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule.js deleted file mode 100644 index c79c2ceb6..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule.js +++ /dev/null @@ -1,5 +0,0 @@ -// A test node that exports a function -module.exports = function(RED) { - function TestNode(n) {} - RED.nodes.registerType("test-node-mod-1",TestNode); -} diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule2.html b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule2.html deleted file mode 100644 index a1f1b6c79..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule2.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - -

this should be filtered out

diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule2.js b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule2.js deleted file mode 100644 index d359fb3f2..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/TestNodeModule2.js +++ /dev/null @@ -1,4 +0,0 @@ -// A test node that exports a function -module.exports = function(RED) { - throw new Error("fail to load"); -} diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/icons/file.txt b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/icons/file.txt deleted file mode 100644 index 59a29af14..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/icons/file.txt +++ /dev/null @@ -1,3 +0,0 @@ -This file exists just to ensure the 'icons' directory is in the repository. -TODO: a future test needs to ensure the right icon files are loaded - this - directory can be used for that diff --git a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/package.json b/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/package.json deleted file mode 100644 index 4f9e46518..000000000 --- a/test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/VersionMismatchModule/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name" : "VersionMismatchModule", - "version" : "0.0.1", - "description" : "A test node module", - "node-red" : { - "version": "100.0.0", - "nodes": { - "VersionMismatchMod1": "TestNodeModule.js", - "VersionMismatchMod2": "TestNodeModule2.js" - } - } -}