blob: 81c1a2ceb1a6e51225a20857fb01c3937fc69059 [file] [log] [blame]
Chinthakayala, Sheshashailavas (sc2914)d1569972017-08-28 05:25:46 -09001/**
2 * Copyright 2014 IBM Corp.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 **/
16
17var should = require("should");
18var sinon = require("sinon");
19var path = require("path");
20var when = require("when");
21
22var RedNodes = require("../../../red/nodes");
23var RedNode = require("../../../red/nodes/Node");
24var typeRegistry = require("../../../red/nodes/registry");
25var events = require("../../../red/events");
26
27afterEach(function() {
28 typeRegistry.clear();
29});
30
31describe('NodeRegistry', function() {
32
33 var resourcesDir = __dirname+ path.sep + "resources" + path.sep;
34
35 function stubSettings(s,available) {
36 s.available = function() {return available;}
37 s.set = function(s,v) { return when.resolve()},
38 s.get = function(s) { return null;}
39 return s
40 }
41 var settings = stubSettings({},false);
42 var settingsWithStorage = stubSettings({},true);
43
44 it('automatically registers new nodes',function() {
45 var testNode = RedNodes.getNode('123');
46 should.not.exist(n);
47 var n = new RedNode({id:'123',type:'abc'});
48
49 var newNode = RedNodes.getNode('123');
50
51 should.strictEqual(n,newNode);
52 });
53
54 it('handles nodes that export a function', function(done) {
55 typeRegistry.init(settings);
56 typeRegistry.load(resourcesDir + "TestNode1",true).then(function() {
57 var list = typeRegistry.getNodeList();
58 list.should.be.an.Array.and.have.lengthOf(1);
59 list[0].should.have.property("id");
60 list[0].should.have.property("name","TestNode1.js");
61 list[0].should.have.property("types",["test-node-1"]);
62 list[0].should.have.property("enabled",true);
63 list[0].should.not.have.property("err");
64
65 var nodeConstructor = typeRegistry.get("test-node-1");
66 nodeConstructor.should.be.type("function");
67
68 done();
69 }).catch(function(e) {
70 done(e);
71 });
72
73 });
74
75
76 it('handles nodes that export a function returning a resolving promise', function(done) {
77 typeRegistry.init(settings);
78 typeRegistry.load(resourcesDir + "TestNode2",true).then(function() {
79 var list = typeRegistry.getNodeList();
80 list.should.be.an.Array.and.have.lengthOf(1);
81 list[0].should.have.property("id");
82 list[0].should.have.property("name","TestNode2.js");
83 list[0].should.have.property("types",["test-node-2"]);
84 list[0].should.have.property("enabled",true);
85 list[0].should.not.have.property("err");
86 var nodeConstructor = typeRegistry.get("test-node-2");
87 nodeConstructor.should.be.type("function");
88
89 done();
90 }).catch(function(e) {
91 done(e);
92 });
93
94 });
95
96 it('handles nodes that export a function returning a rejecting promise', function(done) {
97 typeRegistry.init(settings);
98 typeRegistry.load(resourcesDir + "TestNode3",true).then(function() {
99 var list = typeRegistry.getNodeList();
100 list.should.be.an.Array.and.have.lengthOf(1);
101 list[0].should.have.property("id");
102 list[0].should.have.property("name","TestNode3.js");
103 list[0].should.have.property("types",["test-node-3"]);
104 list[0].should.have.property("enabled",true);
105 list[0].should.have.property("err","fail");
106
107 var nodeConstructor = typeRegistry.get("test-node-3");
108 (nodeConstructor === null).should.be.true;
109
110 done();
111 }).catch(function(e) {
112 done(e);
113 });
114
115 });
116
117 it('handles files containing multiple nodes', function(done) {
118 typeRegistry.init(settings);
119 typeRegistry.load(resourcesDir + "MultipleNodes1",true).then(function() {
120 var list = typeRegistry.getNodeList();
121 list.should.be.an.Array.and.have.lengthOf(1);
122 list[0].should.have.property("id");
123 list[0].should.have.property("name","MultipleNodes1.js");
124 list[0].should.have.property("types",["test-node-multiple-1a","test-node-multiple-1b"]);
125 list[0].should.have.property("enabled",true);
126 list[0].should.not.have.property("err");
127
128 var nodeConstructor = typeRegistry.get("test-node-multiple-1a");
129 nodeConstructor.should.be.type("function");
130
131 nodeConstructor = typeRegistry.get("test-node-multiple-1b");
132 nodeConstructor.should.be.type("function");
133
134 done();
135 }).catch(function(e) {
136 done(e);
137 });
138 });
139
140 it('handles nested directories', function(done) {
141 typeRegistry.init(settings);
142 typeRegistry.load(resourcesDir + "NestedDirectoryNode",true).then(function() {
143 var list = typeRegistry.getNodeList();
144 list.should.be.an.Array.and.have.lengthOf(1);
145 list[0].should.have.property("id");
146 list[0].should.have.property("name","NestedNode.js");
147 list[0].should.have.property("types",["nested-node-1"]);
148 list[0].should.have.property("enabled",true);
149 list[0].should.not.have.property("err");
150 done();
151 }).catch(function(e) {
152 done(e);
153 });
154 });
155
156 it('emits type-registered and node-icon-dir events', function(done) {
157 var eventEmitSpy = sinon.spy(events,"emit");
158 typeRegistry.init(settings);
159 typeRegistry.load(resourcesDir + "NestedDirectoryNode",true).then(function() {
160 var list = typeRegistry.getNodeList();
161 list.should.be.an.Array.and.have.lengthOf(1);
162 list[0].should.have.property("name","NestedNode.js");
163 list[0].should.have.property("types",["nested-node-1"]);
164 list[0].should.have.property("enabled",true);
165 list[0].should.not.have.property("err");
166
167 eventEmitSpy.callCount.should.equal(2);
168
169 eventEmitSpy.firstCall.args[0].should.be.equal("node-icon-dir");
170 eventEmitSpy.firstCall.args[1].should.be.equal(
171 resourcesDir + "NestedDirectoryNode" + path.sep + "NestedNode" + path.sep + "icons");
172
173 eventEmitSpy.secondCall.args[0].should.be.equal("type-registered");
174 eventEmitSpy.secondCall.args[1].should.be.equal("nested-node-1");
175
176 done();
177 }).catch(function(e) {
178 done(e);
179 }).finally(function() {
180 eventEmitSpy.restore();
181 });
182 });
183
184 it('rejects a duplicate node type registration', function(done) {
185
186 typeRegistry.init(stubSettings({
187 nodesDir:[resourcesDir + "TestNode1",resourcesDir + "DuplicateTestNode"]
188 },false));
189 typeRegistry.load("wontexist",true).then(function() {
190 var list = typeRegistry.getNodeList();
191
192 list.should.be.an.Array.and.have.lengthOf(2);
193 list[0].should.have.property("id");
194 list[0].should.have.property("name","TestNode1.js");
195 list[0].should.have.property("types",["test-node-1"]);
196 list[0].should.have.property("enabled",true);
197 list[0].should.not.have.property("err");
198
199 list[1].should.have.property("id");
200 list[1].id.should.not.equal(list[0].id);
201
202 list[1].should.have.property("name","TestNode1.js");
203 list[1].should.have.property("types",["test-node-1"]);
204 list[1].should.have.property("enabled",true);
205 list[1].should.have.property("err");
206 /already registered/.test(list[1].err).should.be.true;
207
208 var nodeConstructor = typeRegistry.get("test-node-1");
209 // Verify the duplicate node hasn't replaced the original one
210 nodeConstructor.name.should.be.equal("TestNode");
211
212 done();
213 }).catch(function(e) {
214 done(e);
215 });
216 });
217
218 it('handles nodesDir as a string', function(done) {
219
220 typeRegistry.init(stubSettings({
221 nodesDir :resourcesDir + "TestNode1"
222 },false));
223 typeRegistry.load("wontexist",true).then(function(){
224 var list = typeRegistry.getNodeList();
225 list.should.be.an.Array.and.have.lengthOf(1);
226 list[0].should.have.property("types",["test-node-1"]);
227 done();
228 }).catch(function(e) {
229 done("Loading of non-existing nodesDir should succeed");
230 });
231
232 });
233
234 it('handles invalid nodesDir',function(done) {
235
236 typeRegistry.init(stubSettings({
237 nodesDir : "wontexist"
238 },false));
239 typeRegistry.load("wontexist",true).then(function(){
240 var list = typeRegistry.getNodeList();
241 list.should.be.an.Array.and.be.empty;
242 done();
243 }).catch(function(e) {
244 done("Loading of non-existing nodesDir should succeed");
245 });
246 });
247
248 it('returns nothing for an unregistered type config', function() {
249 typeRegistry.init(settings);
250 typeRegistry.load("wontexist",true).then(function(){
251 var config = typeRegistry.getNodeConfig("imaginary-shark");
252 (config === null).should.be.true;
253 }).catch(function(e) {
254 done(e);
255 });
256 });
257
258 it('excludes node files listed in nodesExcludes',function(done) {
259 typeRegistry.init(stubSettings({
260 nodesExcludes: [ "TestNode1.js" ],
261 nodesDir:[resourcesDir + "TestNode1",resourcesDir + "TestNode2"]
262 },false));
263 typeRegistry.load("wontexist",true).then(function() {
264 var list = typeRegistry.getNodeList();
265 list.should.be.an.Array.and.have.lengthOf(1);
266 list[0].should.have.property("types",["test-node-2"]);
267 done();
268 }).catch(function(e) {
269 done(e);
270 });
271 });
272
273 it('returns the node configurations', function(done) {
274 typeRegistry.init(stubSettings({
275 nodesDir:[resourcesDir + "TestNode1",resourcesDir + "TestNode2"]
276 },false));
277 typeRegistry.load("wontexist",true).then(function() {
278 var list = typeRegistry.getNodeList();
279
280 var nodeConfigs = typeRegistry.getNodeConfigs();
281
282 // TODO: this is brittle...
283 nodeConfigs.should.equal("<script type=\"text/x-red\" data-template-name=\"test-node-1\"></script>\n<script type=\"text/x-red\" data-help-name=\"test-node-1\"></script>\n<script type=\"text/javascript\">RED.nodes.registerType('test-node-1',{});</script>\n<style></style>\n<p>this should be filtered out</p>\n<script type=\"text/x-red\" data-template-name=\"test-node-2\"></script>\n<script type=\"text/x-red\" data-help-name=\"test-node-2\"></script>\n<script type=\"text/javascript\">RED.nodes.registerType('test-node-2',{});</script>\n<style></style>\n");
284
285 var nodeId = list[0].id;
286 var nodeConfig = typeRegistry.getNodeConfig(nodeId);
287 nodeConfig.should.equal("<script type=\"text/x-red\" data-template-name=\"test-node-1\"></script>\n<script type=\"text/x-red\" data-help-name=\"test-node-1\"></script>\n<script type=\"text/javascript\">RED.nodes.registerType('test-node-1',{});</script>\n<style></style>\n<p>this should be filtered out</p>\n");
288 done();
289 }).catch(function(e) {
290 done(e);
291 });
292 });
293
294 it('stores the node list', function(done) {
295 var settings = {
296 nodesDir:[resourcesDir + "TestNode1",resourcesDir + "TestNode2",resourcesDir + "TestNode3"],
297 available: function() { return true; },
298 set: function(s,v) {return when.resolve();},
299 get: function(s) { return null;}
300 }
301 var settingsSave = sinon.spy(settings,"set");
302 typeRegistry.init(settings);
303 typeRegistry.load("wontexist",true).then(function() {
304 var list = typeRegistry.getNodeList();
305 list.should.be.Array.and.have.length(3);
306
307 settingsSave.callCount.should.equal(1);
308 settingsSave.firstCall.args[0].should.be.equal("nodes");
309 var savedList = settingsSave.firstCall.args[1];
310
311 savedList[list[0].id].name == list[0].name;
312 savedList[list[1].id].name == list[1].name;
313 savedList[list[2].id].name == list[2].name;
314
315 savedList[list[0].id].should.not.have.property("err");
316 savedList[list[1].id].should.not.have.property("err");
317 savedList[list[2].id].should.not.have.property("err");
318
319 done();
320 }).catch(function(e) {
321 done(e);
322 }).finally(function() {
323 settingsSave.restore();
324 });
325
326 });
327
328 it('allows nodes to be added by filename', function(done) {
329 var settings = {
330 available: function() { return true; },
331 set: function(s,v) {return when.resolve();},
332 get: function(s) { return null;}
333 }
334 typeRegistry.init(settings);
335 typeRegistry.load("wontexist",true).then(function(){
336 var list = typeRegistry.getNodeList();
337 list.should.be.an.Array.and.be.empty;
338
339 typeRegistry.addNode(resourcesDir + "TestNode1/TestNode1.js").then(function(node) {
340 list = typeRegistry.getNodeList();
341 list[0].should.have.property("id");
342 list[0].should.have.property("name","TestNode1.js");
343 list[0].should.have.property("types",["test-node-1"]);
344 list[0].should.have.property("enabled",true);
345 list[0].should.not.have.property("err");
346
347 node.should.be.an.Array.and.have.lengthOf(1);
348 node.should.eql(list);
349
350 done();
351 }).catch(function(e) {
352 done(e);
353 });
354
355 }).catch(function(e) {
356 done(e);
357 });
358 });
359
360 it('fails to add non-existent filename', function(done) {
361 typeRegistry.init(settingsWithStorage);
362 typeRegistry.load("wontexist",true).then(function(){
363 var list = typeRegistry.getNodeList();
364 list.should.be.an.Array.and.be.empty;
365 typeRegistry.addNode(resourcesDir + "DoesNotExist/DoesNotExist.js").then(function(nodes) {
366 nodes.should.be.an.Array.and.have.lengthOf(1);
367 nodes[0].should.have.property("id");
368 nodes[0].should.have.property("types",[]);
369 nodes[0].should.have.property("err");
370 done();
371 }).otherwise(function(e) {
372 done(e);
373 });
374
375 }).catch(function(e) {
376 done(e);
377 });
378 });
379
380 it('returns node info by type or id', function(done) {
381 typeRegistry.init(settings);
382 typeRegistry.load(resourcesDir + "TestNode1",true).then(function() {
383 var list = typeRegistry.getNodeList();
384 list.should.be.an.Array.and.have.lengthOf(1);
385
386 var id = list[0].id;
387 var type = list[0].types[0];
388
389 list[0].should.have.property("id");
390 list[0].should.have.property("name","TestNode1.js");
391 list[0].should.have.property("types",["test-node-1"]);
392 list[0].should.have.property("enabled",true);
393 list[0].should.not.have.property("err");
394
395 var info = typeRegistry.getNodeInfo(id);
396 list[0].should.eql(info);
397
398 var info2 = typeRegistry.getNodeInfo(type);
399 list[0].should.eql(info2);
400
401 done();
402 }).catch(function(e) {
403 done(e);
404 });
405
406 });
407
408
409 it('rejects adding duplicate nodes', function(done) {
410 typeRegistry.init(settingsWithStorage);
411 typeRegistry.load(resourcesDir + "TestNode1",true).then(function(){
412 var list = typeRegistry.getNodeList();
413 list.should.be.an.Array.and.have.lengthOf(1);
414
415 typeRegistry.addNode({file:resourcesDir + "TestNode1" + path.sep + "TestNode1.js"}).then(function(node) {
416 done(new Error("duplicate node loaded"));
417 }).otherwise(function(e) {
418 var list = typeRegistry.getNodeList();
419 list.should.be.an.Array.and.have.lengthOf(1);
420 done();
421 });
422
423 }).catch(function(e) {
424 done(e);
425 });
426 });
427
428 it('removes nodes from the registry', function(done) {
429 typeRegistry.init(settingsWithStorage);
430 typeRegistry.load(resourcesDir + "TestNode1",true).then(function() {
431 var list = typeRegistry.getNodeList();
432 list.should.be.an.Array.and.have.lengthOf(1);
433 list[0].should.have.property("id");
434 list[0].should.have.property("name","TestNode1.js");
435 list[0].should.have.property("types",["test-node-1"]);
436 list[0].should.have.property("enabled",true);
437 list[0].should.have.property("loaded",true);
438
439 typeRegistry.getNodeConfigs().length.should.be.greaterThan(0);
440
441 var info = typeRegistry.removeNode(list[0].id);
442
443 info.should.have.property("id",list[0].id);
444 info.should.have.property("enabled",false);
445 info.should.have.property("loaded",false);
446
447 typeRegistry.getNodeList().should.be.an.Array.and.be.empty;
448 typeRegistry.getNodeConfigs().length.should.equal(0);
449
450 var nodeConstructor = typeRegistry.get("test-node-1");
451 (typeof nodeConstructor).should.be.equal("undefined");
452
453
454 done();
455 }).catch(function(e) {
456 done(e);
457 });
458 });
459
460 it('rejects removing unknown nodes from the registry', function(done) {
461 typeRegistry.init(settings);
462 typeRegistry.load("wontexist",true).then(function() {
463 var list = typeRegistry.getNodeList();
464 list.should.be.an.Array.and.be.empty;
465
466
467 /*jshint immed: false */
468 (function() {
469 typeRegistry.removeNode("1234");
470 }).should.throw();
471
472 done();
473 }).catch(function(e) {
474 done(e);
475 });
476 });
477
478 it('scans the node_modules path for node files', function(done) {
479 var fs = require("fs");
480 var path = require("path");
481
482 var eventEmitSpy = sinon.spy(events,"emit");
483 var pathJoin = (function() {
484 var _join = path.join;
485 return sinon.stub(path,"join",function() {
486 if (arguments.length == 3 && arguments[2] == "package.json") {
487 return _join(resourcesDir,"TestNodeModule" + path.sep + "node_modules" + path.sep,arguments[1],arguments[2]);
488 }
489 if (arguments.length == 2 && arguments[1] == "TestNodeModule") {
490 return _join(resourcesDir,"TestNodeModule" + path.sep + "node_modules" + path.sep,arguments[1]);
491 }
492 return _join.apply(this,arguments);
493 });
494 })();
495
496 var readdirSync = (function() {
497 var originalReaddirSync = fs.readdirSync;
498 var callCount = 0;
499 return sinon.stub(fs,"readdirSync",function(dir) {
500 var result = [];
501 if (callCount == 1) {
502 result = originalReaddirSync(resourcesDir + "TestNodeModule" + path.sep + "node_modules");
503 }
504 callCount++;
505 return result;
506 });
507 })();
508
509 typeRegistry.init(settings);
510 typeRegistry.load("wontexist",false).then(function(){
511 var list = typeRegistry.getNodeList();
512 list.should.be.an.Array.and.have.lengthOf(2);
513 list[0].should.have.property("id");
514 list[0].should.have.property("name","TestNodeModule:TestNodeMod1");
515 list[0].should.have.property("types",["test-node-mod-1"]);
516 list[0].should.have.property("enabled",true);
517 list[0].should.not.have.property("err");
518
519 list[1].should.have.property("id");
520 list[1].should.have.property("name","TestNodeModule:TestNodeMod2");
521 list[1].should.have.property("types",["test-node-mod-2"]);
522 list[1].should.have.property("enabled",true);
523 list[1].should.have.property("err");
524
525
526 eventEmitSpy.callCount.should.equal(2);
527
528 eventEmitSpy.firstCall.args[0].should.be.equal("node-icon-dir");
529 eventEmitSpy.firstCall.args[1].should.be.equal(
530 resourcesDir + "TestNodeModule" + path.sep+ "node_modules" + path.sep + "TestNodeModule" + path.sep + "icons");
531
532 eventEmitSpy.secondCall.args[0].should.be.equal("type-registered");
533 eventEmitSpy.secondCall.args[1].should.be.equal("test-node-mod-1");
534
535 done();
536 }).catch(function(e) {
537 done(e);
538 }).finally(function() {
539 readdirSync.restore();
540 pathJoin.restore();
541 eventEmitSpy.restore();
542 });
543 });
544
545 it('allows nodes to be added by module name', function(done) {
546 var fs = require("fs");
547 var path = require("path");
548
549 var pathJoin = (function() {
550 var _join = path.join;
551 return sinon.stub(path,"join",function() {
552 if (arguments.length == 3 && arguments[2] == "package.json") {
553 return _join(resourcesDir,"TestNodeModule" + path.sep + "node_modules" + path.sep,arguments[1],arguments[2]);
554 }
555 if (arguments.length == 2 && arguments[1] == "TestNodeModule") {
556 return _join(resourcesDir,"TestNodeModule" + path.sep + "node_modules" + path.sep,arguments[1]);
557 }
558 return _join.apply(this,arguments);
559 });
560 })();
561
562 var readdirSync = (function() {
563 var originalReaddirSync = fs.readdirSync;
564 var callCount = 0;
565 return sinon.stub(fs,"readdirSync",function(dir) {
566 var result = [];
567 if (callCount == 1) {
568 result = originalReaddirSync(resourcesDir + "TestNodeModule" + path.sep + "node_modules");
569 }
570 callCount++;
571 return result;
572 });
573 })();
574 typeRegistry.init(settingsWithStorage);
575 typeRegistry.load("wontexist",true).then(function(){
576 var list = typeRegistry.getNodeList();
577 list.should.be.an.Array.and.be.empty;
578
579 typeRegistry.addModule("TestNodeModule").then(function(node) {
580 list = typeRegistry.getNodeList();
581 list.should.be.an.Array.and.have.lengthOf(2);
582 list[0].should.have.property("id");
583 list[0].should.have.property("name","TestNodeModule:TestNodeMod1");
584 list[0].should.have.property("types",["test-node-mod-1"]);
585 list[0].should.have.property("enabled",true);
586 list[0].should.not.have.property("err");
587
588 list[1].should.have.property("id");
589 list[1].should.have.property("name","TestNodeModule:TestNodeMod2");
590 list[1].should.have.property("types",["test-node-mod-2"]);
591 list[1].should.have.property("enabled",true);
592 list[1].should.have.property("err");
593
594 node.should.eql(list);
595
596 done();
597 }).catch(function(e) {
598 done(e);
599 });
600
601 }).catch(function(e) {
602 done(e);
603 }).finally(function() {
604 readdirSync.restore();
605 pathJoin.restore();
606 });
607 });
608
609
610 it('rejects adding duplicate node modules', function(done) {
611 var fs = require("fs");
612 var path = require("path");
613
614 var pathJoin = (function() {
615 var _join = path.join;
616 return sinon.stub(path,"join",function() {
617 if (arguments.length == 3 && arguments[2] == "package.json") {
618 return _join(resourcesDir,"TestNodeModule" + path.sep + "node_modules" + path.sep,arguments[1],arguments[2]);
619 }
620 if (arguments.length == 2 && arguments[1] == "TestNodeModule") {
621 return _join(resourcesDir,"TestNodeModule" + path.sep + "node_modules" + path.sep,arguments[1]);
622 }
623 return _join.apply(this,arguments);
624 });
625 })();
626
627 var readdirSync = (function() {
628 var originalReaddirSync = fs.readdirSync;
629 var callCount = 0;
630 return sinon.stub(fs,"readdirSync",function(dir) {
631 var result = [];
632 if (callCount == 1) {
633 result = originalReaddirSync(resourcesDir + "TestNodeModule" + path.sep + "node_modules");
634 }
635 callCount++;
636 return result;
637 });
638 })();
639
640 typeRegistry.init(settingsWithStorage);
641 typeRegistry.load('wontexist',false).then(function(){
642 var list = typeRegistry.getNodeList();
643 list.should.be.an.Array.and.have.lengthOf(2);
644 typeRegistry.addModule("TestNodeModule").then(function(node) {
645 done(new Error("addModule resolved"));
646 }).otherwise(function(err) {
647 done();
648 });
649 }).catch(function(e) {
650 done(e);
651 }).finally(function() {
652 readdirSync.restore();
653 pathJoin.restore();
654 });
655 });
656
657
658 it('fails to add non-existent module name', function(done) {
659 typeRegistry.init(settingsWithStorage);
660 typeRegistry.load("wontexist",true).then(function(){
661 var list = typeRegistry.getNodeList();
662 list.should.be.an.Array.and.be.empty;
663
664 typeRegistry.addModule("DoesNotExistModule").then(function(node) {
665 done(new Error("ENOENT not thrown"));
666 }).otherwise(function(e) {
667 e.code.should.eql("MODULE_NOT_FOUND");
668 done();
669 });
670
671 }).catch(function(e) {
672 done(e);
673 });
674 });
675
676 it('removes nodes from the registry by module', function(done) {
677 var fs = require("fs");
678 var path = require("path");
679
680 var pathJoin = (function() {
681 var _join = path.join;
682 return sinon.stub(path,"join",function() {
683 if (arguments.length == 3 && arguments[2] == "package.json") {
684 return _join(resourcesDir,"TestNodeModule" + path.sep + "node_modules" + path.sep,arguments[1],arguments[2]);
685 }
686 if (arguments.length == 2 && arguments[1] == "TestNodeModule") {
687 return _join(resourcesDir,"TestNodeModule" + path.sep + "node_modules" + path.sep,arguments[1]);
688 }
689 return _join.apply(this,arguments);
690 });
691 })();
692
693 var readdirSync = (function() {
694 var originalReaddirSync = fs.readdirSync;
695 var callCount = 0;
696 return sinon.stub(fs,"readdirSync",function(dir) {
697 var result = [];
698 if (callCount == 1) {
699 result = originalReaddirSync(resourcesDir + "TestNodeModule" + path.sep + "node_modules");
700 }
701 callCount++;
702 return result;
703 });
704 })();
705
706 typeRegistry.init(settingsWithStorage);
707 typeRegistry.load('wontexist',false).then(function(){
708 var list = typeRegistry.getNodeList();
709 list.should.be.an.Array.and.have.lengthOf(2);
710 var res = typeRegistry.removeModule("TestNodeModule");
711
712 res.should.be.an.Array.and.have.lengthOf(2);
713 res[0].should.have.a.property("id",list[0].id);
714 res[1].should.have.a.property("id",list[1].id);
715
716 list = typeRegistry.getNodeList();
717 list.should.be.an.Array.and.be.empty;
718
719 done();
720 }).catch(function(e) {
721 done(e);
722 }).finally(function() {
723 readdirSync.restore();
724 pathJoin.restore();
725 });
726
727 });
728
729 it('fails to remove non-existent module name', function(done) {
730 typeRegistry.init(settings);
731 typeRegistry.load("wontexist",true).then(function(){
732 var list = typeRegistry.getNodeList();
733 list.should.be.an.Array.and.be.empty;
734
735 /*jshint immed: false */
736 (function() {
737 typeRegistry.removeModule("DoesNotExistModule");
738 }).should.throw();
739
740 done();
741
742 }).catch(function(e) {
743 done(e);
744 });
745 });
746
747
748 it('allows nodes to be enabled and disabled', function(done) {
749 typeRegistry.init(settingsWithStorage);
750 typeRegistry.load(resourcesDir+path.sep+"TestNode1",true).then(function() {
751 var list = typeRegistry.getNodeList();
752 list.should.be.an.Array.and.have.lengthOf(1);
753 list[0].should.have.property("id");
754 list[0].should.have.property("name","TestNode1.js");
755 list[0].should.have.property("enabled",true);
756
757 var nodeConfig = typeRegistry.getNodeConfigs();
758 nodeConfig.length.should.be.greaterThan(0);
759
760 var info = typeRegistry.disableNode(list[0].id);
761 info.should.have.property("id",list[0].id);
762 info.should.have.property("enabled",false);
763
764 var list2 = typeRegistry.getNodeList();
765 list2.should.be.an.Array.and.have.lengthOf(1);
766 list2[0].should.have.property("enabled",false);
767
768 typeRegistry.getNodeConfigs().length.should.equal(0);
769
770 var info2 = typeRegistry.enableNode(list[0].id);
771 info2.should.have.property("id",list[0].id);
772 info2.should.have.property("enabled",true);
773
774 var list3 = typeRegistry.getNodeList();
775 list3.should.be.an.Array.and.have.lengthOf(1);
776 list3[0].should.have.property("enabled",true);
777
778 var nodeConfig2 = typeRegistry.getNodeConfigs();
779 nodeConfig2.should.eql(nodeConfig);
780
781 done();
782 }).catch(function(e) {
783 done(e);
784 });
785 });
786
787 it('fails to enable/disable non-existent nodes', function(done) {
788 typeRegistry.init(settings);
789 typeRegistry.load("wontexist",true).then(function() {
790 var list = typeRegistry.getNodeList();
791 list.should.be.an.Array.and.be.empty;
792
793 /*jshint immed: false */
794 (function() {
795 typeRegistry.disableNode("123");
796 }).should.throw();
797
798 /*jshint immed: false */
799 (function() {
800 typeRegistry.enableNode("123");
801 }).should.throw();
802
803 done();
804 }).catch(function(e) {
805 done(e);
806 });
807 });
808});