Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 0198254
Showing
16 changed files
with
2,853 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
.vscode/launch.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# Node Test Helper | ||
|
||
This project pulls out the node helper module from the Node-RED core so that it can used for node contributors. | ||
|
||
For examples on how to use this helper, see the Node-RED core node test code and some node .js files supplied in the `test/examples` folder. | ||
|
||
## Adding to node project | ||
|
||
To add to your node project test dependencies: | ||
|
||
npm install node-red-test-helper --save-dev | ||
|
||
Inside your node test code: | ||
|
||
```javascript | ||
var helper = require('node-red-test-helper'); | ||
``` | ||
|
||
## Testing the helper | ||
|
||
npm run test | ||
|
||
This runs tests on a snapshot of some of the core nodes' Javascript files to ensure the helper works. | ||
|
||
## Example test | ||
|
||
This is an example test for testing the lower-case node in the [Node-RED documentation](https://nodered.org/docs/creating-nodes/first-node). | ||
|
||
```javascript | ||
var should = require("should"); | ||
var helper = require("node-red-contrib-lower-case"); | ||
var lowerNode = require("../lower-case.js"); | ||
|
||
describe('lower-case Node', function () { | ||
|
||
afterEach(function () { | ||
helper.unload(); | ||
}); | ||
|
||
it('should be loaded', function (done) { | ||
var flow = [{ id: "n1", type: "lower-case", name: "lower-case" }]; | ||
helper.load(lowerNode, flow, function () { | ||
var n1 = helper.getNode("n1"); | ||
n1.should.have.property('name', 'lower-case'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should make payload lower case', function (done) { | ||
var flow = [ | ||
{ id: "n1", type: "lower-case", name: "lower-case",wires:[["n2"]] }, | ||
{ id: "n2", type: "helper" } | ||
]; | ||
helper.load(lowerNode, flow, function () { | ||
var n2 = helper.getNode("n2"); | ||
var n1 = helper.getNode("n1"); | ||
n2.on("input", function (msg) { | ||
msg.should.have.property('payload', 'uppercase'); | ||
done(); | ||
}); | ||
n1.receive({ payload: "UpperCase" }); | ||
}); | ||
}); | ||
}); | ||
``` | ||
|
||
## API | ||
|
||
### load(testNode, testFlows, testCredentials, cb) | ||
|
||
Load the test node, flows and credentials. | ||
|
||
### unload() | ||
|
||
Return promise to stop all flows, clean up test runtime and log spy. | ||
|
||
### getNode(id) | ||
|
||
Get the node from the runtime. | ||
|
||
### credentials | ||
|
||
TODO | ||
|
||
### clearFlows() | ||
|
||
Calls RED.flows.stopFlows() to stop all flows. | ||
|
||
### request: function() | ||
|
||
Create http (supertest) request to the editor/admin url. | ||
|
||
Example: | ||
|
||
```javascript | ||
helper.request().post('/inject/invalid').expect(404).end(done); | ||
``` | ||
|
||
### startServer(done) | ||
|
||
Start a Node-RED test server; `done()` when complete. | ||
|
||
### stopServer(done) | ||
|
||
Stop server. Generally called after unload() complete | ||
|
||
### url() | ||
|
||
Return the URL of the helper server. | ||
|
||
### log() | ||
|
||
Return a spy on the logs to look for events from the node under test. For example: | ||
|
||
```javascript | ||
var logEvents = helper.log().args.filter(function(evt { | ||
return evt[0].type == "batch"; | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
/** | ||
* Copyright JS Foundation and other contributors, http://js.foundation | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
**/ | ||
|
||
var should = require("should"); | ||
var sinon = require("sinon"); | ||
var when = require("when"); | ||
var request = require('supertest'); | ||
var express = require("express"); | ||
var http = require('http'); | ||
|
||
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 app = express(); | ||
|
||
var address = '127.0.0.1'; | ||
var listenPort = 0; // use ephemeral port | ||
var port; | ||
var url; | ||
var logSpy; | ||
var server; | ||
|
||
function helperNode(n) { | ||
RED.nodes.createNode(this, n); | ||
} | ||
|
||
module.exports = { | ||
load: function(testNode, testFlows, testCredentials, cb) { | ||
var i; | ||
|
||
logSpy = sinon.spy(log,"log"); | ||
logSpy.FATAL = log.FATAL; | ||
logSpy.ERROR = log.ERROR; | ||
logSpy.WARN = log.WARN; | ||
logSpy.INFO = log.INFO; | ||
logSpy.DEBUG = log.DEBUG; | ||
logSpy.TRACE = log.TRACE; | ||
logSpy.METRIC = log.METRIC; | ||
|
||
if (typeof testCredentials === 'function') { | ||
cb = testCredentials; | ||
testCredentials = {}; | ||
} | ||
|
||
var storage = { | ||
getFlows: function() { | ||
return when.resolve({flows:testFlows,credentials:testCredentials}); | ||
} | ||
}; | ||
|
||
var settings = { | ||
available: function() { return false; } | ||
}; | ||
|
||
var red = {}; | ||
for (i in RED) { | ||
if (RED.hasOwnProperty(i) && !/^(init|start|stop)$/.test(i)) { | ||
var propDescriptor = Object.getOwnPropertyDescriptor(RED,i); | ||
Object.defineProperty(red,i,propDescriptor); | ||
} | ||
} | ||
|
||
red["_"] = function(messageId) { | ||
return messageId; | ||
}; | ||
|
||
redNodes.init({events:events,settings:settings, storage:storage,log:log,}); | ||
RED.nodes.registerType("helper", helperNode); | ||
if (Array.isArray(testNode)) { | ||
for (i = 0; i < testNode.length; i++) { | ||
testNode[i](red); | ||
} | ||
} else { | ||
testNode(red); | ||
} | ||
flows.load().then(function() { | ||
flows.startFlows(); | ||
should.deepEqual(testFlows, flows.getFlows().flows); | ||
cb(); | ||
}); | ||
}, | ||
|
||
unload: function() { | ||
// TODO: any other state to remove between tests? | ||
redNodes.clearRegistry(); | ||
logSpy.restore(); | ||
context.clean({allNodes:[]}); | ||
return flows.stopFlows(); | ||
}, | ||
|
||
getNode: function(id) { | ||
return flows.get(id); | ||
}, | ||
|
||
credentials: credentials, | ||
|
||
clearFlows: function() { | ||
return flows.stopFlows(); | ||
}, | ||
|
||
request: function() { | ||
return request(RED.httpAdmin); | ||
}, | ||
|
||
startServer: function(done) { | ||
server = http.createServer(function(req,res) { app(req,res); }); | ||
RED.init(server, { | ||
SKIP_BUILD_CHECK: true, | ||
logging:{console:{level:'off'}} | ||
}); | ||
server.listen(listenPort, address); | ||
server.on('listening', function() { | ||
port = server.address().port; | ||
url = 'http://' + address + ':' + port; | ||
comms.start(); | ||
done(); | ||
}); | ||
}, | ||
|
||
//TODO consider saving TCP handshake/server reinit on start/stop/start sequences | ||
stopServer: function(done) { | ||
if (server) { | ||
try { | ||
server.on('close', function() { | ||
comms.stop(); | ||
}); | ||
server.close(done); | ||
} catch(e) { | ||
done(); | ||
} | ||
} | ||
}, | ||
|
||
url: function() { return url; }, | ||
|
||
log: function() { return logSpy;} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "node-red-contrib-test-helper", | ||
"version": "0.1.0", | ||
"description": "Helper module for testing nodes", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha 'test/**/*_spec.js'" | ||
}, | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"express": "4.16.2", | ||
"node-red": "^0.18.2", | ||
"mocha": "~3.4.2", | ||
"should": "^8.4.0", | ||
"sinon": "1.17.7", | ||
"supertest": "3.0.0" | ||
}, | ||
"devDependencies": { | ||
"hash-sum": "1.0.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
var helper = require('../index.js'); | ||
|
||
describe('_spec.js', function() { | ||
console.log('todo'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/** | ||
* Copyright JS Foundation and other contributors, http://js.foundation | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
**/ | ||
|
||
var should = require("should"); | ||
var helper = require("../index.js"); | ||
var commentNode = require("./examples/90-comment.js"); | ||
|
||
describe('comment Node', function() { | ||
|
||
afterEach(function() { | ||
helper.unload(); | ||
}); | ||
|
||
it('should be loaded', function(done) { | ||
var flow = [{id:"n1", type:"comment", name: "comment" }]; | ||
helper.load(commentNode, flow, function() { | ||
var n1 = helper.getNode("n1"); | ||
n1.should.have.property('name', 'comment'); | ||
done(); | ||
}); | ||
}); | ||
|
||
}); |
Oops, something went wrong.