From 3bd782e62af3ea2f1fb675cdf1187619fc187cd2 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 2 Apr 2024 13:57:19 +0100 Subject: [PATCH] Fix change node handling of replacing with boolean Fixes #4638 --- .../nodes/core/function/15-change.js | 9 +++-- test/nodes/core/function/15-change_spec.js | 39 ++++++++++++++++--- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/function/15-change.js b/packages/node_modules/@node-red/nodes/core/function/15-change.js index 64ce00b88..d10bf657e 100644 --- a/packages/node_modules/@node-red/nodes/core/function/15-change.js +++ b/packages/node_modules/@node-red/nodes/core/function/15-change.js @@ -233,9 +233,12 @@ module.exports = function(RED) { // only replace if they match exactly RED.util.setMessageProperty(msg,property,value); } else { - // if target is boolean then just replace it - if (rule.tot === "bool") { current = value; } - else { current = current.replace(fromRE,value); } + current = current.replace(fromRE,value); + if (rule.tot === "bool" && current === ""+value) { + // If the target type is boolean, and the replace call has resulted in "true"/"false", + // convert to boolean type (which 'value' already is) + current = value + } RED.util.setMessageProperty(msg,property,current); } } else if ((typeof current === 'number' || current instanceof Number) && fromType === 'num') { diff --git a/test/nodes/core/function/15-change_spec.js b/test/nodes/core/function/15-change_spec.js index b23c1994a..1815470fa 100644 --- a/test/nodes/core/function/15-change_spec.js +++ b/test/nodes/core/function/15-change_spec.js @@ -918,7 +918,7 @@ describe('change Node', function() { }); }); - it('changes the value and type of the message property if a complete match', function(done) { + it('changes the value and type of the message property if a complete match - number', function(done) { var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "msg", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]]}, {id:"helperNode1", type:"helper", wires:[]}]; helper.load(changeNode, flow, function() { @@ -938,6 +938,25 @@ describe('change Node', function() { }); }); + it('changes the value and type of the message property if a complete match - boolean', function(done) { + var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload.a", "pt": "msg", "from": "123", "fromt": "str", "to": "true", "tot": "bool" }, { "t": "change", "p": "payload.b", "pt": "msg", "from": "456", "fromt": "str", "to": "false", "tot": "bool" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]}]; + helper.load(changeNode, flow, function() { + var changeNode1 = helper.getNode("changeNode1"); + var helperNode1 = helper.getNode("helperNode1"); + helperNode1.on("input", function(msg) { + try { + msg.payload.a.should.equal(true); + msg.payload.b.should.equal(false); + done(); + } catch(err) { + done(err); + } + }); + changeNode1.receive({payload: { a: "123", b: "456" }}); + }); + }); + it('changes the value of a multi-level message property', function(done) { var flow = [{"id":"changeNode1","type":"change","action":"change","property":"foo.bar","from":"Hello","to":"Goodbye","reg":false,"name":"changeNode","wires":[["helperNode1"]]}, {id:"helperNode1", type:"helper", wires:[]}]; @@ -992,21 +1011,29 @@ describe('change Node', function() { }); }); - it('changes the value of the message property based on a regex', function(done) { - var flow = [{"id":"changeNode1","type":"change","action":"change","property":"payload","from":"\\d+","to":"NUMBER","reg":true,"name":"changeNode","wires":[["helperNode1"]]}, - {id:"helperNode1", type:"helper", wires:[]}]; + it.only('changes the value of the message property based on a regex', function(done) { + const flow = [ + {"id":"changeNode1","type":"change",rules:[ + { "t": "change", "p": "payload.a", "pt": "msg", "from": "\\d+", "fromt": "re", "to": "NUMBER", "tot": "str" }, + { "t": "change", "p": "payload.b", "pt": "msg", "from": "on", "fromt": "re", "to": "true", "tot": "bool" }, + { "t": "change", "p": "payload.c", "pt": "msg", "from": "off", "fromt": "re", "to": "false", "tot": "bool" } + ],"reg":false,"name":"changeNode","wires":[["helperNode1"]]}, + {id:"helperNode1", type:"helper", wires:[]} + ]; helper.load(changeNode, flow, function() { var changeNode1 = helper.getNode("changeNode1"); var helperNode1 = helper.getNode("helperNode1"); helperNode1.on("input", function(msg) { try { - msg.payload.should.equal("Replace all numbers NUMBER and NUMBER"); + msg.payload.a.should.equal("Replace all numbers NUMBER and NUMBER"); + msg.payload.b.should.equal(true) + msg.payload.c.should.equal(false) done(); } catch(err) { done(err); } }); - changeNode1.receive({payload:"Replace all numbers 12 and 14"}); + changeNode1.receive({payload:{ a: "Replace all numbers 12 and 14", b: 'on', c: 'off' } }); }); });