From 312e3611b1b2fd8db760ada7fe26e028d62e4bf5 Mon Sep 17 00:00:00 2001 From: Hiroyasu Nishiyama Date: Mon, 16 Jul 2018 13:45:59 +0900 Subject: [PATCH] allow environment variable as reduce init value --- nodes/core/logic/17-split.html | 2 +- nodes/core/logic/17-split.js | 51 +++---------- test/nodes/core/logic/17-split_spec.js | 102 +++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 42 deletions(-) diff --git a/nodes/core/logic/17-split.html b/nodes/core/logic/17-split.html index 4c2b9313e..9c2866b9c 100644 --- a/nodes/core/logic/17-split.html +++ b/nodes/core/logic/17-split.html @@ -415,7 +415,7 @@ $("#node-input-reduceExp").typedInput({types:[jsonata_or_empty]}); $("#node-input-reduceInit").typedInput({ default: 'num', - types:['flow','global','str','num','bool','json','bin','date','jsonata'], + types:['flow','global','str','num','bool','json','bin','date','jsonata','env'], typeField: $("#node-input-reduceInitType") }); $("#node-input-reduceFixup").typedInput({types:[jsonata_or_empty]}); diff --git a/nodes/core/logic/17-split.js b/nodes/core/logic/17-split.js index 09743f40c..666938e13 100644 --- a/nodes/core/logic/17-split.js +++ b/nodes/core/logic/17-split.js @@ -359,47 +359,16 @@ module.exports = function(RED) { } function getInitialReduceValue(node, exp, exp_type) { - return new Promise((resolve,reject) => { - if(exp_type === "flow" || exp_type === "global") { - node.context()[exp_type].get(exp,(err,value) => { - if (err) { - reject(err); - } else { - resolve(value); - } - }); - return; - } else if(exp_type === "jsonata") { - var jexp = RED.util.prepareJSONataExpression(exp, node); - RED.util.evaluateJSONataExpression(jexp, {},(err,value) => { - if (err) { - reject(err); - } else { - resolve(value); - } - }); - return; - } - var result; - if(exp_type === "str") { - result = exp; - } else if(exp_type === "num") { - result = Number(exp); - } else if(exp_type === "bool") { - if (exp === 'true') { - result = true; - } else if (exp === 'false') { - result = false; - } - } else if ((exp_type === "bin") || (exp_type === "json")) { - result = JSON.parse(exp); - } else if(exp_type === "date") { - result = Date.now(); - } else { - reject(new Error("unexpected initial value type")); - return; - } - resolve(result); + return new Promise((resolve, reject) => { + RED.util.evaluateNodeProperty(exp, exp_type, node, {}, + (err, result) => { + if(err) { + return reject(err); + } + else { + return resolve(result); + } + }); }); } diff --git a/test/nodes/core/logic/17-split_spec.js b/test/nodes/core/logic/17-split_spec.js index 70ea9b26e..a4470465e 100644 --- a/test/nodes/core/logic/17-split_spec.js +++ b/test/nodes/core/logic/17-split_spec.js @@ -940,6 +940,108 @@ describe('JOIN node', function() { }); }); + function checkInitTypes(itype, ival, rval, initializer, checker, done) { + var flow = [{id:"n1", z:"f0", type:"join", mode:"reduce", + reduceRight:false, + reduceExp:"$A", + reduceInit:ival, + reduceInitType:itype, + reduceFixup:undefined, + wires:[["n2"]]}, + {id:"n2", type:"helper"}]; + if (!initializer) { + initializer = (node, cb) => { + cb(); + }; + } + helper.load(joinNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + initializer(n1, function () { + n2.on("input", function(msg) { + try { + msg.should.have.property("payload"); + checker(msg.payload, rval); + done(); + } + catch(e) { done(e); } + }); + n1.receive({payload:3, parts:{index:2, count:4, id:222}}); + n1.receive({payload:2, parts:{index:1, count:4, id:222}}); + n1.receive({payload:4, parts:{index:3, count:4, id:222}}); + n1.receive({payload:1, parts:{index:0, count:4, id:222}}); + }); + }); + } + + function checkInitTypesSimple(itype, val, done) { + checkInitTypes(itype, val, val, undefined, should.equal, done); + } + + function checkInitTypesComplex(itype, ival, rval, done) { + checkInitTypes(itype, ival, rval, undefined, should.deepEqual, done); + } + + it('should reduce messages with init types (str)', function(done) { + checkInitTypesSimple('str', "xyz", done); + }); + + it('should reduce messages with init types (num)', function(done) { + checkInitTypesSimple('num', 10, done); + }); + + it('should reduce messages with init types (bool)', function(done) { + checkInitTypesSimple('bool', true, done); + }); + + it('should reduce messages with init types (json)', function(done) { + var ival = '{"x":"vx", "y":"vy", "z":"vz"}'; + var rval = JSON.parse(ival); + checkInitTypesComplex('json', ival, rval, done); + }); + + it('should reduce messages with init types (bin)', function(done) { + var ival = "[1,2,3]"; + var rval = Buffer.from(JSON.parse(ival)); + checkInitTypesComplex('bin', ival, rval, done); + }); + + it('should reduce messages with init types (JSONata)', function(done) { + var ival = "1+2+3"; + var rval = 6; + checkInitTypesComplex('jsonata', ival, rval, done); + }); + + it('should reduce messages with init types (env)', function(done) { + function init(node, cb) { + process.env.NR_XYZ = "nr_xyz"; + cb(); + } + function fin(err) { + delete process.env.NR_XYZ; + done(err); + } + checkInitTypes('env', "NR_XYZ", "nr_xyz", init, should.equal, fin); + }); + + it('should reduce messages with init types (flow.name)', function(done) { + function init(node, cb) { + var context = node.context(); + context.flow.set("foo", "bar"); + cb(); + } + checkInitTypes('flow', "foo", "bar", init, should.equal, done); + }); + + it('should reduce messages with init types (global.name)', function(done) { + function init(node, cb) { + var context = node.context(); + context.global.set("foo", "bar"); + cb(); + } + checkInitTypes('global', "foo", "bar", init, should.equal, done); + }); + it('should reduce messages using $I', function(done) { var flow = [{id:"n1", type:"join", mode:"reduce", reduceRight:false,