Skip to content

Commit f7424e9

Browse files
authored
Merge pull request #34 from kwakwaversal/init-settings
Add customisable userSettings
2 parents d6695c2 + 5966ddd commit f7424e9

File tree

4 files changed

+98
-2
lines changed

4 files changed

+98
-2
lines changed

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ We then have a set of mocha unit tests. These tests check that the node loads c
104104

105105
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.
106106

107+
The helper takes an optional `userSettings` parameter which is merged with the runtime defaults.
108+
109+
```javascript
110+
helper.init(require.resolve('node-red'), {
111+
functionGlobalContext: { os:require('os') }
112+
});
113+
```
114+
107115
## Getting nodes in the runtime
108116

109117
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.
@@ -320,6 +328,20 @@ Example:
320328
helper.request().post('/inject/invalid').expect(404).end(done);
321329
```
322330

331+
### settings(userSettings)
332+
333+
Merges any userSettings with the defaults returned by `RED.settings`. Each invocation of this method will overwrite the previous userSettings to prevent unexpected problems in your tests.
334+
335+
This will enable you to replicate your production environment within your tests, for example where you're using the `functionGlobalContext` to enable extra node modules within your functions.
336+
337+
```javascript
338+
// functions can now access os via global.get('os')
339+
helper.settings({ functionGlobalContext: { os:require('os') } });
340+
341+
// reset back to defaults
342+
helper.settings({ });
343+
```
344+
323345
### startServer(done)
324346

325347
Starts a Node-RED server for testing nodes that depend on http or web sockets endpoints like the debug node.
@@ -361,4 +383,4 @@ var logEvents = helper.log().args.filter(function(evt {
361383

362384
npm run examples
363385

364-
This runs tests on an included lower-case node (as above) as well as snaphots of some of the core nodes' Javascript files to ensure the helper is working as expected.
386+
This runs tests on an included lower-case node (as above) as well as snaphots of some of the core nodes' Javascript files to ensure the helper is working as expected.

examples/function_spec.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,28 @@ describe('function node', function() {
197197
});
198198
});
199199

200+
it('should access functionGlobalContext set via herlp settings()', function(done) {
201+
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('foo');return msg;"},
202+
{id:"n2", type:"helper"}];
203+
helper.settings({
204+
functionGlobalContext: {
205+
foo: (function() {
206+
return 'bar';
207+
})(),
208+
},
209+
});
210+
helper.load(functionNode, flow, function() {
211+
var n1 = helper.getNode("n1");
212+
var n2 = helper.getNode("n2");
213+
n2.on("input", function(msg) {
214+
msg.should.have.property('payload', 'bar');
215+
done();
216+
});
217+
n1.receive({payload:"replaceme"});
218+
});
219+
helper.settings({});
220+
});
221+
200222
function testNonObjectMessage(functionText,done) {
201223
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:functionText},
202224
{id:"n2", type:"helper"}];

index.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,35 @@ class NodeTestHelper extends EventEmitter {
128128
}
129129
}
130130

131-
init(runtimePath) {
131+
init(runtimePath, userSettings) {
132132
runtimePath = runtimePath || findRuntimePath();
133133
if (runtimePath) {
134134
this._initRuntime(runtimePath);
135+
if (userSettings) {
136+
this.settings(userSettings);
137+
}
138+
}
139+
}
140+
141+
/**
142+
* Merges any userSettings with the defaults returned by `RED.settings`. Each
143+
* invocation of this method will overwrite the previous userSettings to prevent
144+
* unexpected problems in your tests.
145+
*
146+
* This will enable you to replicate your production environment within your tests,
147+
* for example where you're using the `functionGlobalContext` to enable extra node
148+
* modules within your functions.
149+
* @example
150+
* helper.settings({ functionGlobalContext: { os:require('os') } });
151+
* @param {Object} userSettings - an object containing the runtime settings
152+
* @return {Object} custom userSettings merged with default RED.settings
153+
*/
154+
settings(userSettings) {
155+
if (userSettings) {
156+
// to prevent unexpected problems, always merge with the default RED.settings
157+
this._settings = Object.assign({}, this._RED.settings, userSettings);
135158
}
159+
return this._settings;
136160
}
137161

138162
load(testNode, testFlow, testCredentials, cb) {

test/settings_spec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
var should = require("should");
2+
var NodeTestHelper = require('../index.js').NodeTestHelper;
3+
4+
var helper;
5+
beforeEach(function() {
6+
// .init() is implicitly called on instantiation so not required
7+
helper = new NodeTestHelper();
8+
});
9+
10+
describe('add custom settings on init', function () {
11+
it('should merge custom settings with RED.settings defaults', function () {
12+
helper._settings.should.not.have.property('functionGlobalContext');
13+
helper.init(null, {functionGlobalContext: {}});
14+
helper._settings.should.have.property('functionGlobalContext');
15+
});
16+
});
17+
18+
describe('helper.settings() usage', function() {
19+
it('should return a settings Object', function() {
20+
var settings = helper.settings();
21+
should.exist(settings);
22+
settings.should.have.property('get');
23+
});
24+
it('should not maintain settings state across multiple invocations', function() {
25+
helper.settings({ foo: true }).should.have.property('foo');
26+
helper.settings({ bar: true }).should.not.have.property('foo');
27+
});
28+
});

0 commit comments

Comments
 (0)