Skip to content

Commit

Permalink
Merge pull request #34 from kwakwaversal/init-settings
Browse files Browse the repository at this point in the history
Add customisable userSettings
  • Loading branch information
knolleary authored Jul 9, 2019
2 parents d6695c2 + 5966ddd commit f7424e9
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 2 deletions.
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ We then have a set of mocha unit tests. These tests check that the node loads c

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.

The helper takes an optional `userSettings` parameter which is merged with the runtime defaults.

```javascript
helper.init(require.resolve('node-red'), {
functionGlobalContext: { os:require('os') }
});
```

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

### settings(userSettings)

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.

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.

```javascript
// functions can now access os via global.get('os')
helper.settings({ functionGlobalContext: { os:require('os') } });

// reset back to defaults
helper.settings({ });
```

### startServer(done)

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

npm run examples

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.
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.
22 changes: 22 additions & 0 deletions examples/function_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,28 @@ describe('function node', function() {
});
});

it('should access functionGlobalContext set via herlp settings()', function(done) {
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('foo');return msg;"},
{id:"n2", type:"helper"}];
helper.settings({
functionGlobalContext: {
foo: (function() {
return 'bar';
})(),
},
});
helper.load(functionNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
msg.should.have.property('payload', 'bar');
done();
});
n1.receive({payload:"replaceme"});
});
helper.settings({});
});

function testNonObjectMessage(functionText,done) {
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:functionText},
{id:"n2", type:"helper"}];
Expand Down
26 changes: 25 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,35 @@ class NodeTestHelper extends EventEmitter {
}
}

init(runtimePath) {
init(runtimePath, userSettings) {
runtimePath = runtimePath || findRuntimePath();
if (runtimePath) {
this._initRuntime(runtimePath);
if (userSettings) {
this.settings(userSettings);
}
}
}

/**
* 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.
*
* 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.
* @example
* helper.settings({ functionGlobalContext: { os:require('os') } });
* @param {Object} userSettings - an object containing the runtime settings
* @return {Object} custom userSettings merged with default RED.settings
*/
settings(userSettings) {
if (userSettings) {
// to prevent unexpected problems, always merge with the default RED.settings
this._settings = Object.assign({}, this._RED.settings, userSettings);
}
return this._settings;
}

load(testNode, testFlow, testCredentials, cb) {
Expand Down
28 changes: 28 additions & 0 deletions test/settings_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var should = require("should");
var NodeTestHelper = require('../index.js').NodeTestHelper;

var helper;
beforeEach(function() {
// .init() is implicitly called on instantiation so not required
helper = new NodeTestHelper();
});

describe('add custom settings on init', function () {
it('should merge custom settings with RED.settings defaults', function () {
helper._settings.should.not.have.property('functionGlobalContext');
helper.init(null, {functionGlobalContext: {}});
helper._settings.should.have.property('functionGlobalContext');
});
});

describe('helper.settings() usage', function() {
it('should return a settings Object', function() {
var settings = helper.settings();
should.exist(settings);
settings.should.have.property('get');
});
it('should not maintain settings state across multiple invocations', function() {
helper.settings({ foo: true }).should.have.property('foo');
helper.settings({ bar: true }).should.not.have.property('foo');
});
});

0 comments on commit f7424e9

Please sign in to comment.