Skip to content

Commit 8a6e0c0

Browse files
committed
Add conditional support for NR 0.20 and its new code layout
1 parent 8fd176e commit 8a6e0c0

3 files changed

Lines changed: 174 additions & 155 deletions

File tree

index.js

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const express = require("express");
2525
const http = require('http');
2626
const stoppable = require('stoppable');
2727
const readPkgUp = require('read-pkg-up');
28+
const semver = require('semver');
2829
const EventEmitter = require('events').EventEmitter;
2930

3031
const PROXY_METHODS = ['log', 'status', 'warn', 'error', 'debug', 'trace', 'send'];
@@ -36,7 +37,11 @@ function findRuntimePath() {
3637
const upPkg = readPkgUp.sync();
3738
// case 1: we're in NR itself
3839
if (upPkg.pkg.name === 'node-red') {
39-
return path.join(path.dirname(upPkg.path), upPkg.pkg.main);
40+
if (semver.ltr(upPkg.pkg.version,"<0.20.0")) {
41+
return path.join(path.dirname(upPkg.path), upPkg.pkg.main);
42+
} else {
43+
return path.join(path.dirname(upPkg.path),"packages","node_modules","node-red");
44+
}
4045
}
4146
// case 2: NR is resolvable from here
4247
try {
@@ -68,34 +73,31 @@ class NodeTestHelper extends EventEmitter {
6873
_initRuntime(requirePath) {
6974
try {
7075
const RED = this._RED = require(requirePath);
71-
7276
// public runtime API
7377
this._redNodes = RED.nodes;
7478
this._events = RED.events;
7579
this._log = RED.log;
76-
7780
// access internal Node-RED runtime methods
7881
const prefix = path.dirname(requirePath);
79-
this._context = require(path.join(prefix, 'runtime', 'nodes', 'context'));
80-
this._comms = require(path.join(prefix, 'api', 'editor', 'comms'));
81-
82-
this.credentials = require(path.join(prefix, 'runtime', 'nodes', 'credentials'));
83-
84-
// proxy the methods on Node.prototype to both be Sinon spies and asynchronously emit
85-
// information about the latest call
86-
const NodePrototype = require(path.join(prefix, 'runtime', 'nodes', 'Node')).prototype;
87-
PROXY_METHODS.forEach(methodName => {
88-
const spy = this._sandbox.spy(NodePrototype, methodName);
89-
NodePrototype[methodName] = new Proxy(spy, {
90-
apply: (target, thisArg, args) => {
91-
const retval = Reflect.apply(target, thisArg, args);
92-
process.nextTick(function(call) { return () => {
93-
NodePrototype.emit.call(thisArg, `call:${methodName}`, call);
94-
}}(spy.lastCall));
95-
return retval;
96-
}
97-
});
98-
});
82+
83+
if (semver.ltr(RED.version(),"<0.20.0")) {
84+
this._context = require(path.join(prefix, 'runtime', 'nodes', 'context'));
85+
this._comms = require(path.join(prefix, 'api', 'editor', 'comms'));
86+
this.credentials = require(path.join(prefix, 'runtime', 'nodes', 'credentials'));
87+
// proxy the methods on Node.prototype to both be Sinon spies and asynchronously emit
88+
// information about the latest call
89+
this._NodePrototype = require(path.join(prefix, 'runtime', 'nodes', 'Node')).prototype;
90+
} else {
91+
// This is good enough for running it within the NR git repository - given the
92+
// code layout changes. But it will need some more work when running in the other
93+
// possible locations
94+
this._context = require(path.join(prefix, '@node-red/runtime/lib/nodes/context'));
95+
this._comms = require(path.join(prefix, '@node-red/editor-api/lib/editor/comms'));
96+
this.credentials = require(path.join(prefix, '@node-red/runtime/lib/nodes/credentials'));
97+
// proxy the methods on Node.prototype to both be Sinon spies and asynchronously emit
98+
// information about the latest call
99+
this._NodePrototype = require(path.join(prefix, '@node-red/runtime/lib/nodes/Node')).prototype;
100+
}
99101
} catch (ignored) {
100102
// ignore, assume init will be called again by a test script supplying the runtime path
101103
}
@@ -119,6 +121,22 @@ class NodeTestHelper extends EventEmitter {
119121
logSpy.TRACE = log.TRACE;
120122
logSpy.METRIC = log.METRIC;
121123

124+
const self = this;
125+
PROXY_METHODS.forEach(methodName => {
126+
const spy = this._sandbox.spy(self._NodePrototype, methodName);
127+
self._NodePrototype[methodName] = new Proxy(spy, {
128+
apply: (target, thisArg, args) => {
129+
const retval = Reflect.apply(target, thisArg, args);
130+
process.nextTick(function(call) { return () => {
131+
self._NodePrototype.emit.call(thisArg, `call:${methodName}`, call);
132+
}}(spy.lastCall));
133+
return retval;
134+
}
135+
});
136+
});
137+
138+
139+
122140
if (typeof testCredentials === 'function') {
123141
cb = testCredentials;
124142
testCredentials = {};
@@ -175,7 +193,7 @@ class NodeTestHelper extends EventEmitter {
175193
// TODO: any other state to remove between tests?
176194
this._redNodes.clearRegistry();
177195
this._logSpy.restore();
178-
this._sandbox.reset();
196+
this._sandbox.restore();
179197

180198
// internal API
181199
this._context.clean({allNodes:[]});
@@ -244,4 +262,4 @@ class NodeTestHelper extends EventEmitter {
244262
}
245263

246264
module.exports = new NodeTestHelper();
247-
module.exports.NodeTestHelper = NodeTestHelper;
265+
module.exports.NodeTestHelper = NodeTestHelper;

0 commit comments

Comments
 (0)