mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Add registry test for node module loading
This commit is contained in:
parent
1697aee9f6
commit
f7f58a2347
@ -219,7 +219,8 @@ function loadNodesFromModule(moduleDir,pkg) {
|
|||||||
var iconDirs = [];
|
var iconDirs = [];
|
||||||
for (var n in nodes) {
|
for (var n in nodes) {
|
||||||
if (nodes.hasOwnProperty(n)) {
|
if (nodes.hasOwnProperty(n)) {
|
||||||
results.push(loadNodeConfig(path.join(moduleDir,nodes[n]),pkg.name+":"+n));
|
var file = path.join(moduleDir,nodes[n]);
|
||||||
|
results.push(loadNodeConfig(file,pkg.name+":"+n));
|
||||||
var iconDir = path.join(moduleDir,path.dirname(nodes[n]),"icons");
|
var iconDir = path.join(moduleDir,path.dirname(nodes[n]),"icons");
|
||||||
if (iconDirs.indexOf(iconDir) == -1) {
|
if (iconDirs.indexOf(iconDir) == -1) {
|
||||||
if (fs.existsSync(iconDir)) {
|
if (fs.existsSync(iconDir)) {
|
||||||
@ -302,7 +303,7 @@ function loadNodeConfig(file,name) {
|
|||||||
* location of nodeFiles - used by the tests
|
* location of nodeFiles - used by the tests
|
||||||
* @return a promise that resolves on completion of loading
|
* @return a promise that resolves on completion of loading
|
||||||
*/
|
*/
|
||||||
function load(defaultNodesDir) {
|
function load(defaultNodesDir,disableNodePathScan) {
|
||||||
return when.promise(function(resolve,reject) {
|
return when.promise(function(resolve,reject) {
|
||||||
// Find all of the nodes to load
|
// Find all of the nodes to load
|
||||||
var nodeFiles;
|
var nodeFiles;
|
||||||
@ -330,7 +331,7 @@ function load(defaultNodesDir) {
|
|||||||
// This indicates a test is being run - don't want to pick up
|
// This indicates a test is being run - don't want to pick up
|
||||||
// unexpected nodes.
|
// unexpected nodes.
|
||||||
// Urgh.
|
// Urgh.
|
||||||
if (!defaultNodesDir) {
|
if (!disableNodePathScan) {
|
||||||
// Find all of the modules containing nodes
|
// Find all of the modules containing nodes
|
||||||
var moduleFiles = scanTreeForNodesModules();
|
var moduleFiles = scanTreeForNodesModules();
|
||||||
moduleFiles.forEach(function(moduleFile) {
|
moduleFiles.forEach(function(moduleFile) {
|
||||||
|
@ -39,7 +39,7 @@ describe('NodeRegistry', function() {
|
|||||||
|
|
||||||
it('handles nodes that export a function', function(done) {
|
it('handles nodes that export a function', function(done) {
|
||||||
typeRegistry.init({});
|
typeRegistry.init({});
|
||||||
typeRegistry.load(__dirname+"/resources/TestNode1").then(function() {
|
typeRegistry.load(__dirname+"/resources/TestNode1",true).then(function() {
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.have.lengthOf(1);
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
list[0].should.have.property("id");
|
list[0].should.have.property("id");
|
||||||
@ -61,7 +61,7 @@ describe('NodeRegistry', function() {
|
|||||||
|
|
||||||
it('handles nodes that export a function returning a resolving promise', function(done) {
|
it('handles nodes that export a function returning a resolving promise', function(done) {
|
||||||
typeRegistry.init({});
|
typeRegistry.init({});
|
||||||
typeRegistry.load(__dirname+"/resources/TestNode2").then(function() {
|
typeRegistry.load(__dirname+"/resources/TestNode2",true).then(function() {
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.have.lengthOf(1);
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
list[0].should.have.property("id");
|
list[0].should.have.property("id");
|
||||||
@ -81,7 +81,7 @@ describe('NodeRegistry', function() {
|
|||||||
|
|
||||||
it('handles nodes that export a function returning a rejecting promise', function(done) {
|
it('handles nodes that export a function returning a rejecting promise', function(done) {
|
||||||
typeRegistry.init({});
|
typeRegistry.init({});
|
||||||
typeRegistry.load(__dirname+"/resources/TestNode3").then(function() {
|
typeRegistry.load(__dirname+"/resources/TestNode3",true).then(function() {
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.have.lengthOf(1);
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
list[0].should.have.property("id");
|
list[0].should.have.property("id");
|
||||||
@ -103,7 +103,7 @@ describe('NodeRegistry', function() {
|
|||||||
|
|
||||||
it('handles files containing multiple nodes', function(done) {
|
it('handles files containing multiple nodes', function(done) {
|
||||||
typeRegistry.init({});
|
typeRegistry.init({});
|
||||||
typeRegistry.load(__dirname+"/resources/MultipleNodes1").then(function() {
|
typeRegistry.load(__dirname+"/resources/MultipleNodes1",true).then(function() {
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.have.lengthOf(1);
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
list[0].should.have.property("id");
|
list[0].should.have.property("id");
|
||||||
@ -126,7 +126,7 @@ describe('NodeRegistry', function() {
|
|||||||
|
|
||||||
it('handles nested directories', function(done) {
|
it('handles nested directories', function(done) {
|
||||||
typeRegistry.init({});
|
typeRegistry.init({});
|
||||||
typeRegistry.load(__dirname+"/resources/NestedDirectoryNode").then(function() {
|
typeRegistry.load(__dirname+"/resources/NestedDirectoryNode",true).then(function() {
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.have.lengthOf(1);
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
list[0].should.have.property("id");
|
list[0].should.have.property("id");
|
||||||
@ -143,7 +143,7 @@ describe('NodeRegistry', function() {
|
|||||||
it('emits type-registered and node-icon-dir events', function(done) {
|
it('emits type-registered and node-icon-dir events', function(done) {
|
||||||
var eventEmitSpy = sinon.spy(events,"emit");
|
var eventEmitSpy = sinon.spy(events,"emit");
|
||||||
typeRegistry.init({});
|
typeRegistry.init({});
|
||||||
typeRegistry.load(__dirname+"/resources/NestedDirectoryNode").then(function() {
|
typeRegistry.load(__dirname+"/resources/NestedDirectoryNode",true).then(function() {
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.have.lengthOf(1);
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
list[0].should.have.property("name","NestedNode.js");
|
list[0].should.have.property("name","NestedNode.js");
|
||||||
@ -171,7 +171,7 @@ describe('NodeRegistry', function() {
|
|||||||
typeRegistry.init({
|
typeRegistry.init({
|
||||||
nodesDir:[__dirname+"/resources/TestNode1",__dirname+"/resources/DuplicateTestNode"]
|
nodesDir:[__dirname+"/resources/TestNode1",__dirname+"/resources/DuplicateTestNode"]
|
||||||
});
|
});
|
||||||
typeRegistry.load("wontexist").then(function() {
|
typeRegistry.load("wontexist",true).then(function() {
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
|
|
||||||
list.should.be.an.Array.and.have.lengthOf(2);
|
list.should.be.an.Array.and.have.lengthOf(2);
|
||||||
@ -206,7 +206,7 @@ describe('NodeRegistry', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typeRegistry.init(settings);
|
typeRegistry.init(settings);
|
||||||
typeRegistry.load("wontexist").then(function(){
|
typeRegistry.load("wontexist",true).then(function(){
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.have.lengthOf(1);
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
list[0].should.have.property("types",["test-node-1"]);
|
list[0].should.have.property("types",["test-node-1"]);
|
||||||
@ -223,7 +223,7 @@ describe('NodeRegistry', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typeRegistry.init(settings);
|
typeRegistry.init(settings);
|
||||||
typeRegistry.load("wontexist").then(function(){
|
typeRegistry.load("wontexist",true).then(function(){
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.be.empty;
|
list.should.be.an.Array.and.be.empty;
|
||||||
done();
|
done();
|
||||||
@ -234,7 +234,7 @@ describe('NodeRegistry', function() {
|
|||||||
|
|
||||||
it('returns nothing for an unregistered type config', function() {
|
it('returns nothing for an unregistered type config', function() {
|
||||||
typeRegistry.init({});
|
typeRegistry.init({});
|
||||||
typeRegistry.load("wontexist").then(function(){
|
typeRegistry.load("wontexist",true).then(function(){
|
||||||
var config = typeRegistry.getNodeConfig("imaginary-shark");
|
var config = typeRegistry.getNodeConfig("imaginary-shark");
|
||||||
(config === null).should.be.true;
|
(config === null).should.be.true;
|
||||||
}).catch(function(e) {
|
}).catch(function(e) {
|
||||||
@ -247,7 +247,7 @@ describe('NodeRegistry', function() {
|
|||||||
nodesExcludes: [ "TestNode1.js" ],
|
nodesExcludes: [ "TestNode1.js" ],
|
||||||
nodesDir:[__dirname+"/resources/TestNode1",__dirname+"/resources/TestNode2"]
|
nodesDir:[__dirname+"/resources/TestNode1",__dirname+"/resources/TestNode2"]
|
||||||
});
|
});
|
||||||
typeRegistry.load("wontexist").then(function() {
|
typeRegistry.load("wontexist",true).then(function() {
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.have.lengthOf(1);
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
list[0].should.have.property("types",["test-node-2"]);
|
list[0].should.have.property("types",["test-node-2"]);
|
||||||
@ -261,7 +261,7 @@ describe('NodeRegistry', function() {
|
|||||||
typeRegistry.init({
|
typeRegistry.init({
|
||||||
nodesDir:[__dirname+"/resources/TestNode1",__dirname+"/resources/TestNode2"]
|
nodesDir:[__dirname+"/resources/TestNode1",__dirname+"/resources/TestNode2"]
|
||||||
});
|
});
|
||||||
typeRegistry.load("wontexist").then(function() {
|
typeRegistry.load("wontexist",true).then(function() {
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
|
|
||||||
var nodeConfigs = typeRegistry.getNodeConfigs();
|
var nodeConfigs = typeRegistry.getNodeConfigs();
|
||||||
@ -280,7 +280,7 @@ describe('NodeRegistry', function() {
|
|||||||
|
|
||||||
it('allows nodes to be added', function(done) {
|
it('allows nodes to be added', function(done) {
|
||||||
typeRegistry.init({});
|
typeRegistry.init({});
|
||||||
typeRegistry.load("wontexist").then(function(){
|
typeRegistry.load("wontexist",true).then(function(){
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.be.empty;
|
list.should.be.an.Array.and.be.empty;
|
||||||
|
|
||||||
@ -306,7 +306,7 @@ describe('NodeRegistry', function() {
|
|||||||
|
|
||||||
it('rejects adding duplicate nodes', function(done) {
|
it('rejects adding duplicate nodes', function(done) {
|
||||||
typeRegistry.init({});
|
typeRegistry.init({});
|
||||||
typeRegistry.load(__dirname+"/resources/TestNode1").then(function(){
|
typeRegistry.load(__dirname+"/resources/TestNode1",true).then(function(){
|
||||||
var list = typeRegistry.getNodeList();
|
var list = typeRegistry.getNodeList();
|
||||||
list.should.be.an.Array.and.have.lengthOf(1);
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
|
|
||||||
@ -323,4 +323,64 @@ describe('NodeRegistry', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('scans the node_modules path for node files', function(done) {
|
||||||
|
var fs = require("fs");
|
||||||
|
var path = require("path");
|
||||||
|
|
||||||
|
var eventEmitSpy = sinon.spy(events,"emit");
|
||||||
|
var pathJoin = (function() {
|
||||||
|
var _join = path.join;
|
||||||
|
return sinon.stub(path,"join",function() {
|
||||||
|
if (arguments.length == 3 && arguments[2] == "package.json") {
|
||||||
|
return _join(__dirname,"/resources/TestNodeModule/node_modules/",arguments[1],arguments[2]);
|
||||||
|
}
|
||||||
|
if (arguments.length == 2 && arguments[1] == "TestNodeModule") {
|
||||||
|
return _join(__dirname,"/resources/TestNodeModule/node_modules/",arguments[1]);
|
||||||
|
}
|
||||||
|
return _join.apply(this,arguments);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
var readdirSync = (function() {
|
||||||
|
var originalReaddirSync = fs.readdirSync;
|
||||||
|
var callCount = 0;
|
||||||
|
return sinon.stub(fs,"readdirSync",function(dir) {
|
||||||
|
var result = [];
|
||||||
|
if (callCount == 1) {
|
||||||
|
result = originalReaddirSync(__dirname+"/resources/TestNodeModule/node_modules");
|
||||||
|
}
|
||||||
|
callCount++;
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
typeRegistry.init({});
|
||||||
|
typeRegistry.load("wontexist",false).then(function(){
|
||||||
|
var list = typeRegistry.getNodeList();
|
||||||
|
list.should.be.an.Array.and.have.lengthOf(1);
|
||||||
|
list[0].should.have.property("id");
|
||||||
|
list[0].should.have.property("name","TestNodeModule:TestNodeMod1");
|
||||||
|
list[0].should.have.property("types",["test-node-mod-1"]);
|
||||||
|
list[0].should.have.property("enabled",true);
|
||||||
|
list[0].should.not.have.property("err");
|
||||||
|
|
||||||
|
|
||||||
|
eventEmitSpy.callCount.should.equal(2);
|
||||||
|
|
||||||
|
eventEmitSpy.firstCall.args[0].should.be.equal("node-icon-dir");
|
||||||
|
eventEmitSpy.firstCall.args[1].should.be.equal(__dirname+"/resources/TestNodeModule/node_modules/TestNodeModule/icons");
|
||||||
|
|
||||||
|
eventEmitSpy.secondCall.args[0].should.be.equal("type-registered");
|
||||||
|
eventEmitSpy.secondCall.args[1].should.be.equal("test-node-mod-1");
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(function(e) {
|
||||||
|
done(e);
|
||||||
|
}).finally(function() {
|
||||||
|
readdirSync.restore();
|
||||||
|
pathJoin.restore();
|
||||||
|
eventEmitSpy.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
5
test/red/nodes/resources/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.html
generated
vendored
Normal file
5
test/red/nodes/resources/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.html
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<script type="text/x-red" data-template-name="test-node-mod-1"></script>
|
||||||
|
<script type="text/x-red" data-help-name="test-node-mod-1"></script>
|
||||||
|
<script type="text/javascript">RED.nodes.registerType('test-node-mod-1',{});</script>
|
||||||
|
<style></style>
|
||||||
|
<p>this should be filtered out</p>
|
5
test/red/nodes/resources/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.js
generated
vendored
Normal file
5
test/red/nodes/resources/TestNodeModule/node_modules/TestNodeModule/TestNodeModule.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// A test node that exports a function
|
||||||
|
module.exports = function(RED) {
|
||||||
|
function TestNode(n) {}
|
||||||
|
RED.nodes.registerType("test-node-mod-1",TestNode);
|
||||||
|
}
|
3
test/red/nodes/resources/TestNodeModule/node_modules/TestNodeModule/icons/file.txt
generated
vendored
Normal file
3
test/red/nodes/resources/TestNodeModule/node_modules/TestNodeModule/icons/file.txt
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
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
|
10
test/red/nodes/resources/TestNodeModule/node_modules/TestNodeModule/package.json
generated
vendored
Normal file
10
test/red/nodes/resources/TestNodeModule/node_modules/TestNodeModule/package.json
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name" : "TestNodeModule",
|
||||||
|
"version" : "0.0.1",
|
||||||
|
"description" : "A test node module",
|
||||||
|
"node-red" : {
|
||||||
|
"nodes": {
|
||||||
|
"TestNodeMod1": "TestNodeModule.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user