2014-07-29 13:10:20 +02:00
/ * *
2018-07-26 22:15:32 +02:00
* 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 .
* * /
2014-07-29 13:10:20 +02:00
var should = require ( "should" ) ;
2019-07-10 00:32:22 +02:00
var functionNode = require ( "nr-test-utils" ) . require ( "@node-red/nodes/core/function/10-function.js" ) ;
2018-08-20 17:17:24 +02:00
var Context = require ( "nr-test-utils" ) . require ( "@node-red/runtime/lib/nodes/context" ) ;
2018-03-02 05:41:16 +01:00
var helper = require ( "node-red-node-test-helper" ) ;
2021-03-02 01:12:41 +01:00
var RED = require ( "nr-test-utils" ) . require ( "node-red/lib/red" ) ;
2014-07-29 13:10:20 +02:00
describe ( 'function node' , function ( ) {
before ( function ( done ) {
helper . startServer ( done ) ;
} ) ;
2015-02-28 12:45:23 +01:00
2018-04-23 13:37:26 +02:00
after ( function ( done ) {
helper . stopServer ( done ) ;
} ) ;
2018-07-18 09:43:12 +02:00
function initContext ( done ) {
Context . init ( {
contextStorage : {
memory1 : {
module : "memory"
} ,
memory2 : {
module : "memory"
}
}
} ) ;
Context . load ( ) . then ( function ( ) {
done ( ) ;
} ) ;
}
2014-08-01 23:05:49 +02:00
afterEach ( function ( ) {
2018-07-18 09:43:12 +02:00
helper . unload ( ) . then ( function ( ) {
return Context . clean ( { allNodes : { } } ) ;
} ) . then ( function ( ) {
return Context . close ( ) ;
} ) ;
2014-08-01 23:05:49 +02:00
} ) ;
2014-07-29 13:10:20 +02:00
2021-02-02 14:11:33 +01:00
it ( 'should send returned message using send()' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "node.send(msg);" } ,
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
it ( 'should do something with the catch node' , function ( done ) {
var flow = [ { "id" : "funcNode" , "type" : "function" , "wires" : [ [ "goodNode" ] ] , "func" : "node.error('This is an error', msg);" } , { "id" : "goodNode" , "type" : "helper" } , { "id" : "badNode" , "type" : "helper" } , { "id" : "catchNode" , "type" : "catch" , "scope" : null , "uncaught" : false , "wires" : [ [ "badNode" ] ] } ] ;
var catchNodeModule = require ( "nr-test-utils" ) . require ( "@node-red/nodes/core/common/25-catch.js" )
helper . load ( [ catchNodeModule , functionNode ] , flow , function ( ) {
var funcNode = helper . getNode ( "funcNode" ) ;
var catchNode = helper . getNode ( "catchNode" ) ;
var goodNode = helper . getNode ( "goodNode" ) ;
var badNode = helper . getNode ( "badNode" ) ;
badNode . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
msg . should . have . property ( 'error' ) ;
msg . error . should . have . property ( 'message' , "This is an error" ) ;
msg . error . should . have . property ( 'source' ) ;
msg . error . source . should . have . property ( 'id' , "funcNode" ) ;
done ( ) ;
} ) ;
funcNode . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2014-07-29 13:10:20 +02:00
it ( 'should be loaded' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , name : "function" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
n1 . should . have . property ( 'name' , 'function' ) ;
done ( ) ;
} ) ;
} ) ;
it ( 'should send returned message' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2014-07-29 13:10:20 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should send returned message using send()' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "node.send(msg);" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2021-04-08 15:52:02 +02:00
it ( 'should allow accessing node.id and node.name and node.outputCount' , function ( done ) {
var flow = [ { id : "n1" , name : "test-function" , outputs : 2 , type : "function" , wires : [ [ "n2" ] ] , func : "return [{ topic: node.name, payload:node.id, outputCount: node.outputCount }];" } ,
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
// Use this form of assert as `msg` is created inside
// the sandbox and doesn't get all the should.js monkey patching
should . equal ( msg . payload , n1 . id ) ;
should . equal ( msg . topic , n1 . name ) ;
should . equal ( msg . outputCount , n1 . outputs ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} ) ;
n1 . receive ( { payload : "" } ) ;
} ) ;
} ) ;
2019-09-12 23:08:52 +02:00
function testSendCloning ( args , done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] , [ "n2" ] ] , func : "node.send(" + args + "); msg.payload = 'changed';" } ,
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} ) ;
var origMessage = { payload : "foo" , topic : "bar" } ;
n1 . receive ( origMessage ) ;
} ) ;
}
it ( 'should clone single message sent using send()' , function ( done ) {
testSendCloning ( "msg" , done ) ;
} ) ;
it ( 'should not clone single message sent using send(,false)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "node.send(msg,false); msg.payload = 'changed';" } ,
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'changed' ) ;
done ( ) ;
} ) ;
var origMessage = { payload : "foo" , topic : "bar" } ;
n1 . receive ( origMessage ) ;
} ) ;
} ) ;
it ( 'should clone first message sent using send() - array 1' , function ( done ) {
testSendCloning ( "[msg]" , done ) ;
} ) ;
it ( 'should clone first message sent using send() - array 2' , function ( done ) {
testSendCloning ( "[[msg],[null]]" , done ) ;
} ) ;
it ( 'should clone first message sent using send() - array 3' , function ( done ) {
testSendCloning ( "[null,msg]" , done ) ;
} ) ;
it ( 'should clone first message sent using send() - array 3' , function ( done ) {
testSendCloning ( "[null,[msg]]" , done ) ;
} ) ;
2014-07-30 10:32:17 +02:00
it ( 'should pass through _topic' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2014-07-30 10:32:17 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
msg . should . have . property ( '_topic' , 'baz' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" , _topic : "baz" } ) ;
} ) ;
} ) ;
it ( 'should send to multiple outputs' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] , [ "n3" ] ] ,
2018-07-26 22:15:32 +02:00
func : "return [{payload: '1'},{payload: '2'}];" } ,
{ id : "n2" , type : "helper" } , { id : "n3" , type : "helper" } ] ;
2014-07-30 10:32:17 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
var n3 = helper . getNode ( "n3" ) ;
var count = 0 ;
n2 . on ( "input" , function ( msg ) {
should ( msg ) . have . property ( 'payload' , '1' ) ;
count ++ ;
if ( count == 2 ) {
done ( ) ;
}
} ) ;
n3 . on ( "input" , function ( msg ) {
should ( msg ) . have . property ( 'payload' , '2' ) ;
count ++ ;
if ( count == 2 ) {
done ( ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
it ( 'should send to multiple messages' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] ,
2018-07-26 22:15:32 +02:00
func : "return [[{payload: 1},{payload: 2}]];" } ,
{ id : "n2" , type : "helper" } ] ;
2014-07-30 10:32:17 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
var count = 0 ;
n2 . on ( "input" , function ( msg ) {
count ++ ;
2015-03-17 14:40:12 +01:00
try {
should ( msg ) . have . property ( 'payload' , count ) ;
should ( msg ) . have . property ( '_msgid' , 1234 ) ;
if ( count == 2 ) {
done ( ) ;
}
} catch ( err ) {
done ( err ) ;
2014-07-30 10:32:17 +02:00
}
} ) ;
2015-03-17 14:40:12 +01:00
n1 . receive ( { payload : "foo" , topic : "bar" , _msgid : 1234 } ) ;
2014-07-30 10:32:17 +02:00
} ) ;
} ) ;
2014-07-29 13:10:20 +02:00
it ( 'should allow input to be discarded by returning null' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "return null" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2014-07-29 13:10:20 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
setTimeout ( function ( ) {
done ( ) ;
2017-05-15 14:54:05 +02:00
} , 20 ) ;
2014-07-29 13:10:20 +02:00
n2 . on ( "input" , function ( msg ) {
should . fail ( null , null , "unexpected message" ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2016-06-06 12:40:02 +02:00
it ( 'should handle null amongst valid messages' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "return [[msg,null,msg],null]" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ,
{ id : "n3" , type : "helper" } ] ;
2016-06-06 12:40:02 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
var n3 = helper . getNode ( "n3" ) ;
var n2MsgCount = 0 ;
var n3MsgCount = 0 ;
n2 . on ( "input" , function ( msg ) {
n2MsgCount ++ ;
} ) ;
n3 . on ( "input" , function ( msg ) {
n3MsgCount ++ ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
setTimeout ( function ( ) {
n2MsgCount . should . equal ( 2 ) ;
n3MsgCount . should . equal ( 0 ) ;
done ( ) ;
2017-05-15 14:54:05 +02:00
} , 20 ) ;
2016-06-06 12:40:02 +02:00
} ) ;
} ) ;
2017-05-15 14:54:05 +02:00
2017-10-10 22:13:38 +02:00
it ( 'should get keys in global context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=global.keys();return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-10 22:13:38 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . global . set ( "count" , "0" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , [ 'count' ] ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2017-05-15 14:54:05 +02:00
function testNonObjectMessage ( functionText , done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : functionText } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-05-15 14:54:05 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
var n2MsgCount = 0 ;
n2 . on ( "input" , function ( msg ) {
n2MsgCount ++ ;
} ) ;
n1 . receive ( { } ) ;
setTimeout ( function ( ) {
try {
n2MsgCount . should . equal ( 0 ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
msg . should . have . property ( 'level' , helper . log ( ) . ERROR ) ;
msg . should . have . property ( 'id' , 'n1' ) ;
msg . should . have . property ( 'type' , 'function' ) ;
msg . should . have . property ( 'msg' , 'function.error.non-message-returned' ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} , 20 ) ;
} ) ;
}
it ( 'should drop and log non-object message types - string' , function ( done ) {
testNonObjectMessage ( 'return "foo"' , done )
} ) ;
it ( 'should drop and log non-object message types - buffer' , function ( done ) {
2018-10-24 14:45:34 +02:00
testNonObjectMessage ( 'return Buffer.from("hello")' , done )
2017-05-15 14:54:05 +02:00
} ) ;
it ( 'should drop and log non-object message types - array' , function ( done ) {
testNonObjectMessage ( 'return [[[1,2,3]]]' , done )
} ) ;
it ( 'should drop and log non-object message types - boolean' , function ( done ) {
testNonObjectMessage ( 'return true' , done )
} ) ;
it ( 'should drop and log non-object message types - number' , function ( done ) {
testNonObjectMessage ( 'return 123' , done )
} ) ;
2015-01-29 10:57:09 +01:00
it ( 'should handle and log script error' , function ( done ) {
2018-05-08 12:40:16 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "var a = 1;\nretunr" } ] ;
2015-01-29 10:57:09 +01:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2019-07-09 00:23:33 +02:00
setTimeout ( function ( ) {
try {
helper . log ( ) . called . should . be . true ( ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
msg . should . have . property ( 'level' , helper . log ( ) . ERROR ) ;
msg . should . have . property ( 'id' , 'n1' ) ;
msg . should . have . property ( 'type' , 'function' ) ;
msg . should . have . property ( 'msg' , 'ReferenceError: retunr is not defined (line 2, col 1)' ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} , 50 ) ;
2015-01-29 10:57:09 +01:00
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should handle node.on()' , function ( done ) {
2019-07-09 00:23:33 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "node.on('close',function(){ node.log('closed')});" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2019-07-09 00:23:33 +02:00
setTimeout ( function ( ) {
n1 . close ( ) . then ( function ( ) {
try {
helper . log ( ) . called . should . be . true ( ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
msg . should . have . property ( 'level' , helper . log ( ) . INFO ) ;
msg . should . have . property ( 'id' , 'n1' ) ;
msg . should . have . property ( 'type' , 'function' ) ;
msg . should . have . property ( 'msg' , 'closed' ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
2017-10-12 21:47:52 +02:00
} ) ;
2020-09-25 18:11:10 +02:00
} , 100 ) ;
2017-10-12 21:47:52 +02:00
} ) ;
} ) ;
it ( 'should set node context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.set('count','0');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n1 . context ( ) . get ( "count" ) . should . equal ( "0" ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-07-18 09:43:12 +02:00
it ( 'should set persistable node context (w/o callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.set('count','0','memory1');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n1 . context ( ) . get ( "count" , "memory1" , function ( err , val ) {
val . should . equal ( "0" ) ;
done ( ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should set two persistable node context (w/o callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.set('count','0','memory1');context.set('count','1','memory2');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n1 . context ( ) . get ( "count" , "memory1" , function ( err , val1 ) {
val1 . should . equal ( "0" ) ;
n1 . context ( ) . get ( "count" , "memory2" , function ( err , val2 ) {
val2 . should . equal ( "1" ) ;
done ( ) ;
} ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
2018-07-26 22:15:32 +02:00
it ( 'should set two persistable node context (single call, w/o callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.set(['count1','count2'],['0','1'],'memory1');return msg;" } ,
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n1 . context ( ) . get ( "count1" , "memory1" , function ( err , val1 ) {
val1 . should . equal ( "0" ) ;
n1 . context ( ) . get ( "count2" , "memory1" , function ( err , val2 ) {
val2 . should . equal ( "1" ) ;
done ( ) ;
} ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
} ) ;
2018-07-18 09:43:12 +02:00
it ( 'should set persistable node context (w callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.set('count','0','memory1', function (err) { node.send(msg); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n1 . context ( ) . get ( "count" , "memory1" , function ( err , val ) {
val . should . equal ( "0" ) ;
done ( ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should set two persistable node context (w callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.set('count','0','memory1', function (err) { context.set('count', '1', 'memory2', function (err) { node.send(msg); }); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n1 . context ( ) . get ( "count" , "memory1" , function ( err , val1 ) {
val1 . should . equal ( "0" ) ;
n1 . context ( ) . get ( "count" , "memory1" , function ( err , val2 ) {
val2 . should . equal ( "0" ) ;
done ( ) ;
} ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
} ) ;
it ( 'should set two persistable node context (single call, w callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.set(['count1','count2'],['0','1'],'memory1', function(err) { node.send(msg); });" } ,
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n1 . context ( ) . get ( "count1" , "memory1" , function ( err , val1 ) {
val1 . should . equal ( "0" ) ;
n1 . context ( ) . get ( "count2" , "memory1" , function ( err , val2 ) {
val2 . should . equal ( "1" ) ;
done ( ) ;
} ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
2018-07-26 22:15:32 +02:00
2018-07-18 09:43:12 +02:00
it ( 'should set default persistable node context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.set('count','0');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n1 . context ( ) . get ( "count" , "memory1" , function ( err , val ) {
val . should . equal ( "0" ) ;
done ( ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should get node context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=context.get('count');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . set ( "count" , "0" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-07-18 09:43:12 +02:00
function checkCallbackError ( name , done ) {
2019-07-09 00:23:33 +02:00
setTimeout ( function ( ) {
try {
helper . log ( ) . called . should . be . true ( ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
msg . should . have . property ( 'level' , helper . log ( ) . ERROR ) ;
msg . should . have . property ( 'id' , name ) ;
msg . should . have . property ( 'type' , 'function' ) ;
msg . should . have . property ( 'msg' , 'Error: Callback must be a function' ) ;
done ( ) ;
}
catch ( e ) {
done ( e ) ;
}
} , 50 ) ;
2018-07-18 09:43:12 +02:00
}
2018-07-26 22:15:32 +02:00
2018-07-27 14:33:38 +02:00
it ( 'should get persistable node context (w/o callback)' , function ( done ) {
2018-07-18 09:43:12 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=context.get('count','memory1');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-27 14:33:38 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . set ( "count" , "0" , "memory1" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should get persistable node context (w/ callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.get('count','memory1',function (err, val) { msg.payload=val; node.send(msg); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-27 14:33:38 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . set ( "count" , "0" , "memory1" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should get keys in node context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=context.keys();return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . set ( "count" , "0" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , [ 'count' ] ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-07-27 14:33:38 +02:00
it ( 'should get keys in persistable node context (w/o callback)' , function ( done ) {
2018-07-18 09:43:12 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=context.keys('memory1');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . set ( "count" , "0" , "memory1" ) ;
2018-07-27 14:33:38 +02:00
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , [ 'count' ] ) ;
done ( ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
2018-07-26 22:15:32 +02:00
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should get keys in persistable node context (w/ callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.keys('memory1', function(err, keys) { msg.payload=keys; node.send(msg); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . set ( "count" , "0" , "memory1" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , [ 'count' ] ) ;
done ( ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should get keys in default persistable node context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=context.keys();return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . set ( "count" , "0" , "memory1" ) ;
n1 . context ( ) . set ( "number" , "1" , "memory2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , [ 'count' ] ) ;
done ( ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should set flow context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "flow.set('count','0');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n2 . context ( ) . flow . get ( "count" ) . should . equal ( "0" ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-07-18 09:43:12 +02:00
it ( 'should set persistable flow context (w/o callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "flow.set('count','0','memory1');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n2 . context ( ) . flow . get ( "count" , "memory1" , function ( err , val ) {
val . should . equal ( "0" ) ;
done ( ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should set two persistable flow context (w/o callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "flow.set('count','0','memory1');flow.set('count','1','memory2');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n2 . context ( ) . flow . get ( "count" , "memory1" , function ( err , val1 ) {
val1 . should . equal ( "0" ) ;
n2 . context ( ) . flow . get ( "count" , "memory2" , function ( err , val2 ) {
val2 . should . equal ( "1" ) ;
done ( ) ;
} ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should set persistable flow context (w/ callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "flow.set('count','0','memory1', function (err) { node.send(msg); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n2 . context ( ) . flow . get ( "count" , "memory1" , function ( err , val ) {
val . should . equal ( "0" ) ;
done ( ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should set two persistable flow context (w/ callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "flow.set('count','0','memory1', function (err) { flow.set('count','1','memory2', function (err) { node.send(msg); }); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n2 . context ( ) . flow . get ( "count" , "memory1" , function ( err , val1 ) {
val1 . should . equal ( "0" ) ;
n2 . context ( ) . flow . get ( "count" , "memory2" , function ( err , val2 ) {
val2 . should . equal ( "1" ) ;
done ( ) ;
} ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should get flow context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "msg.payload=flow.get('count');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . flow . set ( "count" , "0" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-07-27 14:33:38 +02:00
it ( 'should get persistable flow context (w/o callback)' , function ( done ) {
2018-07-18 09:43:12 +02:00
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "msg.payload=flow.get('count','memory1');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-27 14:33:38 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . flow . set ( "count" , "0" , "memory1" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should get persistable flow context (w/ callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "flow.get('count','memory1', function(err, val) { msg.payload=val; node.send(msg); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-27 14:33:38 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . flow . set ( "count" , "0" , "memory1" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should get flow context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "msg.payload=context.flow.get('count');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . flow . set ( "count" , "0" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
it ( 'should get keys in flow context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "msg.payload=flow.keys();return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . flow . set ( "count" , "0" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , [ 'count' ] ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-07-27 14:33:38 +02:00
it ( 'should get keys in persistable flow context (w/o callback)' , function ( done ) {
2018-07-18 09:43:12 +02:00
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "msg.payload=flow.keys('memory1');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . flow . set ( "count" , "0" , "memory1" ) ;
2018-07-27 14:33:38 +02:00
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , [ 'count' ] ) ;
done ( ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
2018-07-26 22:15:32 +02:00
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should get keys in persistable flow context (w/ callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "flow.keys('memory1', function (err, val) { msg.payload=val; node.send(msg); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . flow . set ( "count" , "0" , "memory1" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , [ 'count' ] ) ;
done ( ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should set global context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "global.set('count','0');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n2 . context ( ) . global . get ( "count" ) . should . equal ( "0" ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-07-18 09:43:12 +02:00
it ( 'should set persistable global context (w/o callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "global.set('count','0','memory1');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n2 . context ( ) . global . get ( "count" , "memory1" , function ( err , val ) {
val . should . equal ( "0" ) ;
done ( ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should set persistable global context (w/ callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "global.set('count','0','memory1', function (err) { node.send(msg); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
n2 . context ( ) . global . get ( "count" , "memory1" , function ( err , val ) {
val . should . equal ( "0" ) ;
done ( ) ;
} ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should get global context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=global.get('count');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . global . set ( "count" , "0" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-07-27 14:33:38 +02:00
it ( 'should get persistable global context (w/o callback)' , function ( done ) {
2018-07-18 09:43:12 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=global.get('count', 'memory1');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
initContext ( function ( ) {
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . global . set ( "count" , "0" , 'memory1' ) ;
2018-07-27 14:33:38 +02:00
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
2018-07-26 22:15:32 +02:00
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2018-07-18 09:43:12 +02:00
} ) ;
2018-07-26 22:15:32 +02:00
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
it ( 'should get persistable global context (w/ callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "global.get('count', 'memory1', function (err, val) { msg.payload=val; node.send(msg); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
initContext ( function ( ) {
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . global . set ( "count" , "0" , 'memory1' ) ;
n2 . on ( "input" , function ( msg ) {
2018-07-18 09:43:12 +02:00
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
2018-07-26 22:15:32 +02:00
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2018-07-18 09:43:12 +02:00
} ) ;
2018-07-26 22:15:32 +02:00
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should get global context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=context.global.get('count');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . global . set ( "count" , "0" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-07-27 14:33:38 +02:00
it ( 'should get persistable global context (w/o callback)' , function ( done ) {
2018-07-18 09:43:12 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=context.global.get('count','memory1');return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . global . set ( "count" , "0" , "memory1" ) ;
2018-07-27 14:33:38 +02:00
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
2018-07-26 22:15:32 +02:00
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
it ( 'should get persistable global context (w/ callback)' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "context.global.get('count','memory1', function (err, val) { msg.payload = val; node.send(msg); });" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-07-18 09:43:12 +02:00
helper . load ( functionNode , flow , function ( ) {
2018-07-26 22:15:32 +02:00
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . global . set ( "count" , "0" , "memory1" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , '0' ) ;
done ( ) ;
}
catch ( e ) {
done ( e ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
2018-07-18 09:43:12 +02:00
} ) ;
} ) ;
2018-07-27 14:33:38 +02:00
it ( 'should handle error on get persistable context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "msg.payload=context.get('count','memory1','callback');return msg;" } ,
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
helper . load ( functionNode , flow , function ( ) {
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . flow . set ( "count" , "0" , "memory1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
checkCallbackError ( 'n1' , done ) ;
} ) ;
} ) ;
} ) ;
it ( 'should handle error on set persistable context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "msg.payload=context.set('count','0','memory1','callback');return msg;" } ,
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
helper . load ( functionNode , flow , function ( ) {
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
checkCallbackError ( 'n1' , done ) ;
} ) ;
} ) ;
} ) ;
it ( 'should handle error on get keys in persistable context' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , z : "flowA" , wires : [ [ "n2" ] ] , func : "msg.payload=context.keys('memory1','callback');return msg;" } ,
{ id : "n2" , type : "helper" , z : "flowA" } ] ;
helper . load ( functionNode , flow , function ( ) {
initContext ( function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . flow . set ( "count" , "0" , "memory1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
checkCallbackError ( 'n1' , done ) ;
} ) ;
} ) ;
} ) ;
2017-10-12 21:47:52 +02:00
it ( 'should handle setTimeout()' , function ( done ) {
2020-09-25 18:11:10 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "setTimeout(function(){node.send(msg);},700);" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
var endTime = process . hrtime ( startTime ) ;
var nanoTime = endTime [ 0 ] * 1000000000 + endTime [ 1 ] ;
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
2020-09-25 18:11:10 +02:00
if ( 600000000 < nanoTime && nanoTime < 800000000 ) {
2017-10-12 21:47:52 +02:00
done ( ) ;
} else {
try {
should . fail ( null , null , "Delayed time was not between 900 and 1100 ms" ) ;
} catch ( err ) {
done ( err ) ;
}
}
} ) ;
var startTime = process . hrtime ( ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
it ( 'should handle setInterval()' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "setInterval(function(){node.send(msg);},100);" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
var count = 0 ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
count ++ ;
if ( count > 2 ) {
done ( ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
it ( 'should handle clearInterval()' , function ( done ) {
2020-09-25 18:11:10 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "var id=setInterval(null,100);setTimeout(function(){clearInterval(id);node.send(msg);},500);" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2017-10-12 21:47:52 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , 'foo' ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-05-21 12:34:56 +02:00
it ( 'should allow accessing node.id' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload = node.id; return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-05-21 12:34:56 +02:00
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' , n1 . id ) ;
done ( ) ;
} ) ;
2018-08-06 14:14:53 +02:00
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2018-05-21 12:34:56 +02:00
} ) ;
} ) ;
it ( 'should allow accessing node.name' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload = node.name; return msg;" , "name" : "name of node" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-05-21 12:34:56 +02:00
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' , n1 . name ) ;
done ( ) ;
} ) ;
2018-08-06 14:14:53 +02:00
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2018-05-21 12:34:56 +02:00
} ) ;
} ) ;
2018-05-25 11:50:58 +02:00
it ( 'should use the same Date object from outside the sandbox' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload=global.get('typeTest')(new Date());return msg;" } ,
2018-07-26 22:15:32 +02:00
{ id : "n2" , type : "helper" } ] ;
2018-05-25 11:50:58 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n1 . context ( ) . global . set ( "typeTest" , function ( d ) { return d instanceof Date } ) ;
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( 'payload' , true ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2018-08-30 23:42:30 +02:00
it ( 'should allow accessing env vars' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload = env.get('_TEST_FOO_'); return msg;" } ,
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
var count = 0 ;
delete process . env . _TEST _FOO _ ;
n2 . on ( "input" , function ( msg ) {
try {
if ( count === 0 ) {
msg . should . have . property ( 'payload' , undefined ) ;
process . env . _TEST _FOO _ = "hello" ;
count ++ ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} else {
msg . should . have . property ( 'payload' , "hello" ) ;
2019-07-09 00:23:33 +02:00
delete process . env . _TEST _FOO _ ;
2018-08-30 23:42:30 +02:00
done ( ) ;
}
} catch ( err ) {
delete process . env . _TEST _FOO _ ;
2019-07-09 00:23:33 +02:00
done ( err ) ;
2018-08-30 23:42:30 +02:00
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) ;
} ) ;
2020-03-06 17:55:45 +01:00
it ( 'should execute initialization' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload = global.get('X'); return msg;" , initialize : "global.set('X','bar');" } ,
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
2020-05-11 07:37:14 +02:00
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( "payload" , "bar" ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" } ) ;
} ) ;
} ) ;
it ( 'should wait completion of initialization' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload = global.get('X'); return msg;" , initialize : "global.set('X', '-'); return new Promise((resolve, reject) => setTimeout(() => { global.set('X','bar'); resolve(); }, 500));" } ,
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
2020-03-06 17:55:45 +01:00
n2 . on ( "input" , function ( msg ) {
msg . should . have . property ( "payload" , "bar" ) ;
done ( ) ;
} ) ;
n1 . receive ( { payload : "foo" } ) ;
} ) ;
} ) ;
2023-05-22 10:16:37 +02:00
it ( 'should timeout if timeout is set' , function ( done ) {
2023-06-21 15:27:32 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , timeout : "0.010" , func : "while(1==1){};\nreturn msg;" } ] ;
2023-05-22 10:16:37 +02:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
setTimeout ( function ( ) {
try {
helper . log ( ) . called . should . be . true ( ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
msg . should . have . property ( 'level' , helper . log ( ) . ERROR ) ;
msg . should . have . property ( 'id' , 'n1' ) ;
msg . should . have . property ( 'type' , 'function' ) ;
should . equal ( msg . msg . message , 'Script execution timed out after 10ms' ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} , 50 ) ;
} ) ;
} ) ;
2021-04-08 15:52:02 +02:00
2023-08-04 14:20:49 +02:00
it ( 'check if default function timeout settings are recognized' , function ( done ) {
RED . settings . functionTimeout = 0.01 ;
var flow = [ { id : "n1" , type : "function" , timeout : RED . settings . functionTimeout , wires : [ [ "n2" ] ] , func : "while(1==1){};\nreturn msg;" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
setTimeout ( function ( ) {
try {
helper . log ( ) . called . should . be . true ( ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
msg . should . have . property ( 'level' , helper . log ( ) . ERROR ) ;
msg . should . have . property ( 'id' , 'n1' ) ;
msg . should . have . property ( 'type' , 'function' ) ;
should . equal ( RED . settings . functionTimeout , 0.01 ) ;
should . equal ( msg . msg . message , 'Script execution timed out after 10ms' ) ;
delete RED . settings . functionTimeout ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} , 500 ) ;
} ) ;
} ) ;
2021-04-08 15:52:02 +02:00
describe ( "finalize function" , function ( ) {
it ( 'should execute' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ ] , func : "return msg;" , finalize : "global.set('X','bar');" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var ctx = n1 . context ( ) . global ;
helper . unload ( ) . then ( function ( ) {
ctx . get ( 'X' ) . should . equal ( "bar" ) ;
done ( ) ;
} ) ;
} ) ;
} ) ;
it ( 'should allow accessing node.id and node.name and node.outputCount' , function ( done ) {
var flow = [ { id : "n1" , name : "test-function" , outputs : 2 , type : "function" , wires : [ [ "n2" ] ] , finalize : "global.set('finalize-data', { topic: node.name, payload:node.id, outputCount: node.outputCount});" , func : "return msg;" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var ctx = n1 . context ( ) . global ;
helper . unload ( ) . then ( function ( ) {
const finalizeData = ctx . get ( 'finalize-data' ) ;
should . equal ( finalizeData . payload , n1 . id ) ;
should . equal ( finalizeData . topic , n1 . name ) ;
should . equal ( finalizeData . outputCount , n1 . outputs ) ;
done ( ) ;
} ) ;
2020-03-06 17:55:45 +01:00
} ) ;
} ) ;
2021-04-08 15:52:02 +02:00
} )
2020-03-06 17:55:45 +01:00
2021-02-15 21:59:37 +01:00
describe ( 'externalModules' , function ( ) {
2021-03-02 01:12:41 +01:00
afterEach ( function ( ) {
delete RED . settings . functionExternalModules ;
} )
2021-07-15 11:13:21 +02:00
it ( 'should fail if using OS module with functionExternalModules set to false' , function ( done ) {
2021-03-01 22:34:37 +01:00
var flow = [
{ id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload = os.type(); return msg;" , "libs" : [ { var : "os" , module : "os" } ] } ,
{ id : "n2" , type : "helper" }
] ;
2021-07-15 11:13:21 +02:00
RED . settings . functionExternalModules = false ;
2021-03-01 22:34:37 +01:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
should . not . exist ( n1 ) ;
done ( ) ;
} ) . catch ( err => done ( err ) ) ;
} )
2021-02-15 21:59:37 +01:00
it ( 'should fail if using OS module without it listed in libs' , function ( done ) {
var flow = [
{ id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload = os.type(); return msg;" } ,
{ id : "n2" , type : "helper" }
] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
var messageReceived = false ;
n2 . on ( "input" , function ( msg ) {
messageReceived = true ;
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
setTimeout ( function ( ) {
try {
messageReceived . should . be . false ( ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} , 20 ) ;
} ) . catch ( err => done ( err ) ) ;
} )
it ( 'should require the OS module' , function ( done ) {
var flow = [
{ id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload = os.type(); return msg;" , "libs" : [ { var : "os" , module : "os" } ] } ,
{ id : "n2" , type : "helper" }
] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
msg . should . have . property ( 'topic' , 'bar' ) ;
msg . should . have . property ( 'payload' , require ( 'os' ) . type ( ) ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
} ) . catch ( err => done ( err ) ) ;
} )
2021-02-16 14:58:59 +01:00
it ( 'should fail if module variable name clashes with sandbox builtin' , function ( done ) {
var flow = [
{ id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "msg.payload = os.type(); return msg;" , "libs" : [ { var : "flow" , module : "os" } ] } ,
{ id : "n2" , type : "helper" }
] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
should . not . exist ( n1 ) ;
done ( ) ;
} ) . catch ( err => done ( err ) ) ;
} )
2021-02-15 21:59:37 +01:00
} )
2015-02-28 12:45:23 +01:00
describe ( 'Logger' , function ( ) {
2020-09-25 18:11:10 +02:00
function testLog ( initCode , funcCode , expectedLevel , done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : funcCode , initialize : initCode } ] ;
2015-02-28 12:45:23 +01:00
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2019-07-09 00:23:33 +02:00
setTimeout ( function ( ) {
try {
helper . log ( ) . called . should . be . true ( ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
2020-09-25 18:11:10 +02:00
msg . should . have . property ( 'level' , helper . log ( ) [ expectedLevel ] ) ;
2019-07-09 00:23:33 +02:00
msg . should . have . property ( 'id' , 'n1' ) ;
msg . should . have . property ( 'type' , 'function' ) ;
msg . should . have . property ( 'msg' , 'test' ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
2020-09-25 18:11:10 +02:00
} , 10 ) ;
2015-02-28 12:45:23 +01:00
} ) ;
2020-09-25 18:11:10 +02:00
}
it ( 'should log an Info Message' , function ( done ) {
testLog ( "" , "node.log('test');" , "INFO" , done ) ;
2015-02-28 12:45:23 +01:00
} ) ;
2018-03-20 21:40:36 +01:00
it ( 'should log a Debug Message' , function ( done ) {
2020-09-25 18:11:10 +02:00
testLog ( "" , "node.debug('test');" , "DEBUG" , done ) ;
2018-03-20 21:40:36 +01:00
} ) ;
it ( 'should log a Trace Message' , function ( done ) {
2020-09-25 18:11:10 +02:00
testLog ( "" , "node.trace('test');" , "TRACE" , done ) ;
2018-03-20 21:40:36 +01:00
} ) ;
2015-02-28 12:45:23 +01:00
it ( 'should log a Warning Message' , function ( done ) {
2020-09-25 18:11:10 +02:00
testLog ( "" , "node.warn('test');" , "WARN" , done ) ;
2015-02-28 12:45:23 +01:00
} ) ;
it ( 'should log an Error Message' , function ( done ) {
2020-09-25 18:11:10 +02:00
testLog ( "" , "node.error('test');" , "ERROR" , done ) ;
} ) ;
it ( 'should log an Info Message - initialise' , function ( done ) {
testLog ( "node.log('test');" , "" , "INFO" , done ) ;
2015-02-28 12:45:23 +01:00
} ) ;
2020-09-25 18:11:10 +02:00
it ( 'should log a Debug Message - initialise' , function ( done ) {
testLog ( "node.debug('test');" , "" , "DEBUG" , done ) ;
} ) ;
it ( 'should log a Trace Message - initialise' , function ( done ) {
testLog ( "node.trace('test');" , "" , "TRACE" , done ) ;
} ) ;
it ( 'should log a Warning Message - initialise' , function ( done ) {
testLog ( "node.warn('test');" , "" , "WARN" , done ) ;
} ) ;
it ( 'should log an Error Message - initialise' , function ( done ) {
testLog ( "node.error('test');" , "" , "ERROR" , done ) ;
} ) ;
2019-08-19 11:42:14 +02:00
it ( 'should catch thrown string' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "throw \"small mistake\";" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2019-08-21 12:39:34 +02:00
setTimeout ( function ( ) {
try {
helper . log ( ) . called . should . be . true ( ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
msg . should . have . property ( 'level' , helper . log ( ) . ERROR ) ;
msg . should . have . property ( 'id' , 'n1' ) ;
msg . should . have . property ( 'type' , 'function' ) ;
msg . should . have . property ( 'msg' , 'small mistake' ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} , 50 ) ;
2019-08-19 11:42:14 +02:00
} ) ;
} ) ;
it ( 'should catch thrown number' , function ( done ) {
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "throw 99;" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2019-08-21 12:39:34 +02:00
setTimeout ( function ( ) {
try {
helper . log ( ) . called . should . be . true ( ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
msg . should . have . property ( 'level' , helper . log ( ) . ERROR ) ;
msg . should . have . property ( 'id' , 'n1' ) ;
msg . should . have . property ( 'type' , 'function' ) ;
msg . should . have . property ( 'msg' , '99' ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} , 50 ) ;
2019-08-19 11:42:14 +02:00
} ) ;
} ) ;
2019-08-21 12:39:34 +02:00
it ( 'should catch thrown object (bad practice)' , function ( done ) {
2019-08-19 11:42:14 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , func : "throw {a:1};" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
n1 . receive ( { payload : "foo" , topic : "bar" } ) ;
2019-08-21 12:39:34 +02:00
setTimeout ( function ( ) {
try {
helper . log ( ) . called . should . be . true ( ) ;
var logEvents = helper . log ( ) . args . filter ( function ( evt ) {
return evt [ 0 ] . type == "function" ;
} ) ;
logEvents . should . have . length ( 1 ) ;
var msg = logEvents [ 0 ] [ 0 ] ;
msg . should . have . property ( 'level' , helper . log ( ) . ERROR ) ;
msg . should . have . property ( 'id' , 'n1' ) ;
msg . should . have . property ( 'type' , 'function' ) ;
msg . should . have . property ( 'msg' , '{"a":1}' ) ;
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} , 50 ) ;
2019-08-19 11:42:14 +02:00
} ) ;
} ) ;
2015-02-28 12:45:23 +01:00
} ) ;
2014-07-30 10:32:17 +02:00
2020-09-25 18:11:10 +02:00
describe ( "init function" , function ( ) {
it ( 'should delay handling messages until init completes' , function ( done ) {
2023-09-25 18:53:11 +02:00
const timeoutMS = 200 ;
2023-09-24 18:01:27 +02:00
// Since helper.load uses process.nextTick timers might occasionally finish
// a couple of milliseconds too early, so give some leeway to the check.
2023-09-25 18:53:11 +02:00
const timeoutCheckMargin = 5 ;
2020-09-25 18:11:10 +02:00
var flow = [ { id : "n1" , type : "function" , wires : [ [ "n2" ] ] , initialize : `
return new Promise ( ( resolve , reject ) => {
2023-09-25 18:53:11 +02:00
setTimeout ( resolve , $ { timeoutMS } ) ;
2020-09-25 18:11:10 +02:00
} ) ` ,
func : "return msg;"
} ,
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
var receivedMsgs = [ ] ;
n2 . on ( "input" , function ( msg ) {
msg . delta = Date . now ( ) - msg . payload ;
receivedMsgs . push ( msg )
if ( receivedMsgs . length === 5 ) {
2023-09-23 22:05:37 +02:00
let deltas = receivedMsgs . map ( msg => msg . delta ) ;
2023-09-25 18:53:11 +02:00
var errors = deltas . filter ( delta => delta < ( timeoutMS - timeoutCheckMargin ) )
2020-09-25 18:11:10 +02:00
if ( errors . length > 0 ) {
2023-09-25 18:53:11 +02:00
done ( new Error ( ` Message received before init completed - delta values ${ JSON . stringify ( deltas ) } expected to be > ${ timeoutMS - timeoutCheckMargin } ` ) )
2020-09-25 18:11:10 +02:00
} else {
done ( ) ;
}
}
} ) ;
for ( var i = 0 ; i < 5 ; i ++ ) {
n1 . receive ( { payload : Date . now ( ) , topic : "msg" + i } ) ;
}
} ) ;
} ) ;
2021-04-08 15:52:02 +02:00
it ( 'should allow accessing node.id and node.name and node.outputCount and sending message' , function ( done ) {
var flow = [ { id : "n1" , name : "test-function" , outputs : 1 , type : "function" , wires : [ [ "n2" ] ] , initialize : "setTimeout(function() { node.send({ topic: node.name, payload:node.id, outputCount: node.outputCount})},10)" , func : "" } ,
2020-09-25 18:11:10 +02:00
{ id : "n2" , type : "helper" } ] ;
helper . load ( functionNode , flow , function ( ) {
var n1 = helper . getNode ( "n1" ) ;
var n2 = helper . getNode ( "n2" ) ;
n2 . on ( "input" , function ( msg ) {
try {
// Use this form of assert as `msg` is created inside
// the sandbox and doesn't get all the should.js monkey patching
should . equal ( msg . payload , n1 . id ) ;
should . equal ( msg . topic , n1 . name ) ;
2021-04-08 15:52:02 +02:00
should . equal ( msg . outputCount , n1 . outputs ) ;
2020-09-25 18:11:10 +02:00
done ( ) ;
} catch ( err ) {
done ( err ) ;
}
} ) ;
} ) ;
} ) ;
2021-04-08 15:52:02 +02:00
} ) ;
2014-07-29 13:10:20 +02:00
} ) ;