From 4215be7a6dac3b2f53c92ebdf0ff96e3b5145b79 Mon Sep 17 00:00:00 2001 From: mblackstock Date: Wed, 21 Mar 2018 19:40:19 -0700 Subject: [PATCH 1/5] add helper.init() call to supply NR runtime path --- README.md | 10 ++++++-- examples/comment_spec.js | 2 ++ examples/function_spec.js | 1 + examples/lower-case_spec.js | 2 ++ index.js | 51 ++++++++++++++++++++++++------------- 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index dc23086..f820abd 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This will add the helper module to your `package.json` file as a development dep ... ``` -The test-helper requires the node-red runtime to run its tests, but Node-RED is **not** installed as a dependency. The reason for this is that test-helper is (or will be) used in Node-RED core tests, and Node-RED itself has a large number of dependencies that you may not want to download if you already have it installed. +The test-helper requires the node-red runtime, but Node-RED is **not** installed as a dependency. The reason for this is that test-helper is (or will be) used in Node-RED core tests, and Node-RED itself has a large number of dependencies that you may not want to download if you already have it installed. You can install the Node-RED runtime available for your unit tests one of two ways: @@ -30,7 +30,7 @@ You can install the Node-RED runtime available for your unit tests one of two wa npm install node-red --save-dev ``` -2. or link to Node-RED installed globally (recommended) using: +2. or link to Node-RED installed globally using: ``` npm install -g node-red @@ -84,6 +84,8 @@ var should = require("should"); var helper = require("node-red-node-test-helper"); var lowerNode = require("../lower-case.js"); +helper.init(require.resolve('node-red')); + describe('lower-case Node', function () { afterEach(function () { @@ -121,6 +123,10 @@ In this example, we require `should` for assertions, this helper module, as well We then have a set of mocha unit tests. These tests check that the node loads correctly, and ensures it makes the payload string lower case as expected. +## Initializing helper + +To get started, we need to tell the helper where to find the node-red runtime. this is done by calling `helper.init(require.resolve('node-red'))` as shown. + ## Getting nodes in the runtime The asynchronous `helper.load()` method calls the supplied callback function once the Node-RED server and runtime is ready. We can then call the `helper.getNode(id)` method to get a reference to nodes in the runtime. For more information on these methods see the API section below. diff --git a/examples/comment_spec.js b/examples/comment_spec.js index d891b70..78f9b0c 100644 --- a/examples/comment_spec.js +++ b/examples/comment_spec.js @@ -16,6 +16,8 @@ var should = require("should"); var helper = require("../index.js"); +helper.init(require.resolve('node-red')); + var commentNode = require("./nodes/90-comment.js"); describe('comment Node', function() { diff --git a/examples/function_spec.js b/examples/function_spec.js index c9baf1b..1b817a1 100644 --- a/examples/function_spec.js +++ b/examples/function_spec.js @@ -16,6 +16,7 @@ var should = require("should"); var helper = require("../index.js"); +helper.init(require.resolve('node-red')); var functionNode = require("./nodes/80-function.js"); diff --git a/examples/lower-case_spec.js b/examples/lower-case_spec.js index 00819f9..b846b89 100644 --- a/examples/lower-case_spec.js +++ b/examples/lower-case_spec.js @@ -2,6 +2,8 @@ var should = require("should"); var helper = require("../index.js"); var lowerNode = require("./nodes/lower-case.js"); +helper.init(require.resolve('node-red')); + describe('lower-case Node', function () { afterEach(function () { diff --git a/index.js b/index.js index edb6901..8092e21 100644 --- a/index.js +++ b/index.js @@ -22,28 +22,42 @@ var express = require("express"); var http = require('http'); var stoppable = require('stoppable'); +var RED; +var redNodes; +var flows; +var credentials; +var comms; +var log; +var context; +var events; + +function initRuntime(requirePath) { + + try { + RED = require(requirePath); + var prefix = requirePath.substring(0, requirePath.indexOf('/red.js')); + redNodes = require(prefix+"/runtime/nodes"); + flows = require(prefix+"/runtime/nodes/flows"); + credentials = require(prefix+"/runtime/nodes/credentials"); + comms = require(prefix+"/api/editor/comms"); + log = require(prefix+"/runtime/log"); + context = require(prefix+"/runtime/nodes/context"); + events = require(prefix+"/runtime/events"); + } catch (err) { + // ignore, assume init will be called again by a test script supplying the runtime path + } +} + +// assume we have node red as a dependency try { - var RED = require('node-red'); - var redNodes = require("node-red/red/runtime/nodes"); - var flows = require("node-red/red/runtime/nodes/flows"); - var credentials = require("node-red/red/runtime/nodes/credentials"); - var comms = require("node-red/red/api/editor/comms.js"); - var log = require("node-red/red/runtime/log.js"); - var context = require("node-red/red/runtime/nodes/context.js"); - var events = require('node-red/red/runtime/events'); + var runtimePath = require.resolve('node-red'); } catch (err) { - // no node-red in helper-test dependencies so assume we're testing node-red - var nrPath = process.cwd(); - var RED = require(nrPath+"/red/red.js"); - var redNodes = require(nrPath+"/red/runtime/nodes"); - var flows = require(nrPath+"/red/runtime/nodes/flows"); - var credentials = require(nrPath+"/red/runtime/nodes/credentials"); - var comms = require(nrPath+"/red/api/editor/comms.js"); - var log = require(nrPath+"/red/runtime/log.js"); - var context = require(nrPath+"/red/runtime/nodes/context.js"); - var events = require(nrPath+"/red/runtime/events.js"); + // if not, we are running in the core + runtimePath = process.cwd()+"/red/red.js"; } +initRuntime(runtimePath); + var app = express(); var address = '127.0.0.1'; @@ -58,6 +72,7 @@ function helperNode(n) { } module.exports = { + init: initRuntime, load: function(testNode, testFlow, testCredentials, cb) { var i; From 8ac9de2be0afe81e8f6d887fc06be1f6232db068 Mon Sep 17 00:00:00 2001 From: mblackstock Date: Fri, 23 Mar 2018 15:55:38 -0700 Subject: [PATCH 2/5] =?UTF-8?q?address=20review=20comments:=20Use=20`read-?= =?UTF-8?q?pkg-up`=20to=20get=20whether=20we=20are=20running=20in=20node-r?= =?UTF-8?q?ed,=20and=20get=20the=20package=20=E2=80=9Cmain=E2=80=9D=20path?= =?UTF-8?q?.=20README=20mention=20node-red=20is=20a=20peer=20dependency,?= =?UTF-8?q?=20remove=20info=20on=20why=20as=20suggested.=20Remove=20creden?= =?UTF-8?q?tials=20object=20from=20interface=20since=20not=20used=20by=20a?= =?UTF-8?q?ny=20existing=20tests.=20Use=20public=20API=20objects=20where?= =?UTF-8?q?=20possible,=20clarify=20internal=20API=20hooks=20used=20relate?= =?UTF-8?q?d=20to=20issue=20#9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 44 +++++------------------------------------- index.js | 54 ++++++++++++++++++++++++++++++++-------------------- package.json | 3 ++- 3 files changed, 40 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index f820abd..cf10244 100644 --- a/README.md +++ b/README.md @@ -6,55 +6,21 @@ Using the test-helper, your tests can start the Node-RED runtime, load a test fl ## Adding to your node project dependencies -To add unit tests your node project test dependencies, add this test helper as follows: +Node-RED is required by the helper as a peer dependency, meaning it must be installed along with the helper itself. To create unit tests for your node project, add this test helper and Node-RED as follows: - npm install node-red-node-test-helper --save-dev + npm install node-red-node-test-helper node-red --save-dev -This will add the helper module to your `package.json` file as a development dependency: +This will add and the helper module to your `package.json` file: ```json ... "devDependencies": { + "node-red":"^0.18.4", "node-red-node-test-helper": "^0.1.6" } ... ``` -The test-helper requires the node-red runtime, but Node-RED is **not** installed as a dependency. The reason for this is that test-helper is (or will be) used in Node-RED core tests, and Node-RED itself has a large number of dependencies that you may not want to download if you already have it installed. - -You can install the Node-RED runtime available for your unit tests one of two ways: - -1. as a dev dependency in your project: - -``` -npm install node-red --save-dev -``` - -2. or link to Node-RED installed globally using: - -``` -npm install -g node-red -npm link node-red -``` - -Both [Mocha](https://mochajs.org/) and [Should](https://shouldjs.github.io/) will be pulled in with the test helper. Mocha is a unit test framework for Javascript; Should is an assertion library. For more information on these frameworks, see their associated documentation. - -## Linking to additional test dependencies - -To reduce disk use further, you can install the test-helper and additional dev dependencies globally and then link them to your node project. This may be a better option especially if you are developing more than one node. - -See the `package.json` file for the additional dependencies used by test-helper. - -For example to install express globally: - - npm install -g express - -Then link to it in your project: - - npm link express - -Depending on the nodes in your test flow, you may also want to link to other global packages. If a test indicates that a package cannot be found, and you expect to need it for testing other nodes, consider installing the package globally and then linking it to your node project the same way. - ## Adding test script to `package.json` To run your tests you can add a test script to your `package.json` file in the `scripts` section. To run all of the files with the `_spec.js` prefix in the test directory for example: @@ -123,7 +89,7 @@ In this example, we require `should` for assertions, this helper module, as well We then have a set of mocha unit tests. These tests check that the node loads correctly, and ensures it makes the payload string lower case as expected. -## Initializing helper +## Initializing Helper To get started, we need to tell the helper where to find the node-red runtime. this is done by calling `helper.init(require.resolve('node-red'))` as shown. diff --git a/index.js b/index.js index 8092e21..e5e9131 100644 --- a/index.js +++ b/index.js @@ -14,6 +14,7 @@ * limitations under the License. **/ +var path = require("path"); var should = require("should"); var sinon = require("sinon"); var when = require("when"); @@ -21,41 +22,50 @@ var request = require('supertest'); var express = require("express"); var http = require('http'); var stoppable = require('stoppable'); +const readPkgUp = require('read-pkg-up'); var RED; var redNodes; var flows; -var credentials; var comms; var log; var context; var events; +var runtimePath; +var package = readPkgUp.sync(); +if (package.pkg.name === 'node-red') { + runtimePath = path.join(process.cwd(),package.pkg.main); + initRuntime(runtimePath); +} else { + try { + runtimePath = require.resolve('node-red'); + initRuntime(runtimePath); + } catch (err) { + // no runtime path - init must be called from test + } +} + function initRuntime(requirePath) { try { RED = require(requirePath); + + // public runtime API + redNodes = RED.nodes; + events = RED.events; + log = RED.log; + + // access internal Node-RED runtime methods var prefix = requirePath.substring(0, requirePath.indexOf('/red.js')); - redNodes = require(prefix+"/runtime/nodes"); flows = require(prefix+"/runtime/nodes/flows"); - credentials = require(prefix+"/runtime/nodes/credentials"); - comms = require(prefix+"/api/editor/comms"); - log = require(prefix+"/runtime/log"); context = require(prefix+"/runtime/nodes/context"); - events = require(prefix+"/runtime/events"); + comms = require(prefix+"/api/editor/comms"); } catch (err) { // ignore, assume init will be called again by a test script supplying the runtime path } } -// assume we have node red as a dependency -try { - var runtimePath = require.resolve('node-red'); -} catch (err) { - // if not, we are running in the core - runtimePath = process.cwd()+"/red/red.js"; -} - initRuntime(runtimePath); var app = express(); @@ -121,9 +131,9 @@ module.exports = { } else { testNode(red); } - flows.load().then(function() { - flows.startFlows(); - should.deepEqual(testFlow, flows.getFlows().flows); + redNodes.loadFlows().then(function() { + redNodes.startFlows(); + should.deepEqual(testFlow, redNodes.getFlows().flows); cb(); }); }, @@ -132,18 +142,18 @@ module.exports = { // TODO: any other state to remove between tests? redNodes.clearRegistry(); logSpy.restore(); + // internal API context.clean({allNodes:[]}); - return flows.stopFlows(); + return redNodes.stopFlows(); }, getNode: function(id) { + // internal API return flows.get(id); }, - credentials: credentials, - clearFlows: function() { - return flows.stopFlows(); + return redNodes.stopFlows(); }, request: function() { @@ -161,6 +171,7 @@ module.exports = { server.on('listening', function() { port = server.address().port; url = 'http://' + address + ':' + port; + // internal API comms.start(); done(); }); @@ -170,6 +181,7 @@ module.exports = { stopServer: function(done) { if (server) { try { + // internal API comms.stop(); server.stop(done); } catch(e) { diff --git a/package.json b/package.json index 9e24282..407f9c2 100644 --- a/package.json +++ b/package.json @@ -14,10 +14,11 @@ }, "dependencies": { "express": "4.16.2", + "read-pkg-up": "^3.0.0", "should": "^8.4.0", "sinon": "1.17.7", - "supertest": "3.0.0", "stoppable": "boneskull/stoppable#boneskull-patch-1", + "supertest": "3.0.0", "when": "3.7.8" }, "peerDependencies": { From 6f53c32b8d3d581e2ed432ec05687cdba7cd2b5b Mon Sep 17 00:00:00 2001 From: mblackstock Date: Fri, 23 Mar 2018 16:16:35 -0700 Subject: [PATCH 3/5] change `flows.get(id)` to use public API `nodes.getNode(id)` --- index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/index.js b/index.js index e5e9131..56667a7 100644 --- a/index.js +++ b/index.js @@ -58,7 +58,6 @@ function initRuntime(requirePath) { // access internal Node-RED runtime methods var prefix = requirePath.substring(0, requirePath.indexOf('/red.js')); - flows = require(prefix+"/runtime/nodes/flows"); context = require(prefix+"/runtime/nodes/context"); comms = require(prefix+"/api/editor/comms"); } catch (err) { @@ -148,8 +147,7 @@ module.exports = { }, getNode: function(id) { - // internal API - return flows.get(id); + return redNodes.getNode(id); }, clearFlows: function() { From 2564e650e543d2bf36f536bf43239f28cb870d6d Mon Sep 17 00:00:00 2001 From: mblackstock Date: Thu, 12 Apr 2018 12:52:55 -0700 Subject: [PATCH 4/5] use new stoppable, fix package.json --- index.js | 2 +- package.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 56667a7..d4df09f 100644 --- a/index.js +++ b/index.js @@ -122,7 +122,7 @@ module.exports = { }; redNodes.init({events:events,settings:settings, storage:storage,log:log,}); - RED.nodes.registerType("helper", helperNode); + redNodes.registerType("helper", helperNode); if (Array.isArray(testNode)) { for (i = 0; i < testNode.length; i++) { testNode[i](red); diff --git a/package.json b/package.json index 407f9c2..ef2baa0 100644 --- a/package.json +++ b/package.json @@ -14,15 +14,15 @@ }, "dependencies": { "express": "4.16.2", - "read-pkg-up": "^3.0.0", - "should": "^8.4.0", + "read-pkg-up": "3.0.0", + "should": "8.4.0", "sinon": "1.17.7", - "stoppable": "boneskull/stoppable#boneskull-patch-1", + "stoppable": "1.0.6", "supertest": "3.0.0", "when": "3.7.8" }, "peerDependencies": { - "node-red": "0.18.x" + "node-red": "~0.18.4" }, "devDependencies": { "mocha": "~5.0.4" From e960c2df6d51240972443ba030f38264762bf784 Mon Sep 17 00:00:00 2001 From: mblackstock Date: Thu, 12 Apr 2018 15:09:31 -0700 Subject: [PATCH 5/5] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf10244..524afb4 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Node-RED is required by the helper as a peer dependency, meaning it must be inst npm install node-red-node-test-helper node-red --save-dev -This will add and the helper module to your `package.json` file: +This will add the helper module to your `package.json` file: ```json ...