@@ -25,6 +25,7 @@ const express = require("express");
2525const http = require ( 'http' ) ;
2626const stoppable = require ( 'stoppable' ) ;
2727const readPkgUp = require ( 'read-pkg-up' ) ;
28+ const semver = require ( 'semver' ) ;
2829const EventEmitter = require ( 'events' ) . EventEmitter ;
2930
3031const 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
246264module . exports = new NodeTestHelper ( ) ;
247- module . exports . NodeTestHelper = NodeTestHelper ;
265+ module . exports . NodeTestHelper = NodeTestHelper ;
0 commit comments