1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Add test cases for setMessageProperty with non-object properties

This commit is contained in:
Nick O'Leary 2020-06-01 13:13:14 +01:00
parent 132254b3a5
commit 4b54a81dfd
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
4 changed files with 84 additions and 28 deletions

View File

@ -216,7 +216,7 @@ module.exports = function(RED) {
RED.util.setMessageProperty(msg,property,undefined); RED.util.setMessageProperty(msg,property,undefined);
} else if (rule.t === 'set') { } else if (rule.t === 'set') {
if (!RED.util.setMessageProperty(msg,property,value)) { if (!RED.util.setMessageProperty(msg,property,value)) {
node.warn(RED._("change.errors.no-override",{prop:property})); node.warn(RED._("change.errors.no-override",{property:property}));
} }
} else if (rule.t === 'change') { } else if (rule.t === 'change') {
current = RED.util.getMessageProperty(msg,property); current = RED.util.getMessageProperty(msg,property);

View File

@ -672,7 +672,7 @@
"invalid-from": "Invalid 'from' property: __error__", "invalid-from": "Invalid 'from' property: __error__",
"invalid-json": "Invalid 'to' JSON property", "invalid-json": "Invalid 'to' JSON property",
"invalid-expr": "Invalid JSONata expression: __error__", "invalid-expr": "Invalid JSONata expression: __error__",
"no-override": "Can't overwrite primitive type with object __prop__." "no-override": "Cannot set property of non-object type: __property__"
} }
}, },
"range": { "range": {

View File

@ -371,14 +371,14 @@ function setObjectProperty(msg,prop,value,createMissing) {
var length = msgPropParts.length; var length = msgPropParts.length;
var obj = msg; var obj = msg;
var key; var key;
var flag = true;
for (var i=0;i<length-1;i++) { for (var i=0;i<length-1;i++) {
key = msgPropParts[i]; key = msgPropParts[i];
if (typeof key === 'string' || (typeof key === 'number' && !Array.isArray(obj))) { if (typeof key === 'string' || (typeof key === 'number' && !Array.isArray(obj))) {
if (obj.hasOwnProperty(key)) { if (obj.hasOwnProperty(key)) {
if (length > 1 && ((typeof obj[key] !== "object" && typeof obj[key] !== "function") || obj[key] === null)) { if (length > 1 && ((typeof obj[key] !== "object" && typeof obj[key] !== "function") || obj[key] === null)) {
//console.log("Can't override primitive type with object."); // Break out early as we cannot create a property beneath
flag = false; // this type of value
return false;
} }
obj = obj[key]; obj = obj[key];
} else if (createMissing) { } else if (createMissing) {
@ -389,7 +389,7 @@ function setObjectProperty(msg,prop,value,createMissing) {
} }
obj = obj[key]; obj = obj[key];
} else { } else {
return null; return false;
} }
} else if (typeof key === 'number') { } else if (typeof key === 'number') {
// obj is an array // obj is an array
@ -402,7 +402,7 @@ function setObjectProperty(msg,prop,value,createMissing) {
} }
obj = obj[key]; obj = obj[key];
} else { } else {
return null; return false;
} }
} else { } else {
obj = obj[key]; obj = obj[key];
@ -420,11 +420,11 @@ function setObjectProperty(msg,prop,value,createMissing) {
if (typeof obj === "object" && obj !== null) { if (typeof obj === "object" && obj !== null) {
obj[key] = value; obj[key] = value;
} else { } else {
//console.log("Can't override primitive type with object."); // Cannot set a property of a non-object/array
flag = false; return false;
} }
} }
return flag; return true;
} }
/*! /*!

View File

@ -189,7 +189,8 @@ describe("@node-red/util/util", function() {
// setMessageProperty strips off `msg.` prefixes. // setMessageProperty strips off `msg.` prefixes.
// setObjectProperty does not // setObjectProperty does not
var obj = {}; var obj = {};
util.setObjectProperty(obj,"msg.a","bar"); var result = util.setObjectProperty(obj,"msg.a","bar");
result.should.be.true();
obj.should.have.property("msg"); obj.should.have.property("msg");
obj.msg.should.have.property("a","bar"); obj.msg.should.have.property("a","bar");
}) })
@ -197,59 +198,111 @@ describe("@node-red/util/util", function() {
describe('setMessageProperty', function() { describe('setMessageProperty', function() {
it('sets a property', function() { it('sets a property', function() {
var msg = {a:"foo"}; var msg = {a:"foo"};
util.setMessageProperty(msg,"msg.a","bar"); var result = util.setMessageProperty(msg,"msg.a","bar");
result.should.be.true();
msg.a.should.eql('bar'); msg.a.should.eql('bar');
}); });
it('sets a deep level property', function() { it('sets a deep level property', function() {
var msg = {a:{b:{c:"foo"}}}; var msg = {a:{b:{c:"foo"}}};
util.setMessageProperty(msg,"msg.a.b.c","bar"); var result = util.setMessageProperty(msg,"msg.a.b.c","bar");
result.should.be.true();
msg.a.b.c.should.eql('bar'); msg.a.b.c.should.eql('bar');
}); });
it('creates missing parent properties by default', function() { it('creates missing parent properties by default', function() {
var msg = {a:{}}; var msg = {a:{}};
util.setMessageProperty(msg,"msg.a.b.c","bar"); var result = util.setMessageProperty(msg,"msg.a.b.c","bar");
result.should.be.true();
msg.a.b.c.should.eql('bar'); msg.a.b.c.should.eql('bar');
}) })
it('does not create missing parent properties', function() { it('does not create missing parent properties', function() {
var msg = {a:{}}; var msg = {a:{}};
util.setMessageProperty(msg,"msg.a.b.c","bar",false); var result = util.setMessageProperty(msg,"msg.a.b.c","bar",false);
result.should.be.false();
should.not.exist(msg.a.b); should.not.exist(msg.a.b);
}) })
it('does not create missing parent properties with array', function () { it('does not create missing parent properties of array', function () {
var msg = {a:{}}; var msg = {a:{}};
util.setMessageProperty(msg, "msg.a.b[1].c", "bar", false); var result = util.setMessageProperty(msg, "msg.a.b[1].c", "bar", false);
result.should.be.false();
should.not.exist(msg.a.b); should.not.exist(msg.a.b);
}) })
it('does not create missing parent properties of string', function() {
var msg = {a:"foo"};
var result = util.setMessageProperty(msg, "msg.a.b.c", "bar", false);
result.should.be.false();
should.not.exist(msg.a.b);
})
it('does not set property of existing string property', function() {
var msg = {a:"foo"};
var result = util.setMessageProperty(msg, "msg.a.b", "bar", false);
result.should.be.false();
should.not.exist(msg.a.b);
})
it('does not set property of existing number property', function() {
var msg = {a:123};
var result = util.setMessageProperty(msg, "msg.a.b", "bar", false);
result.should.be.false();
should.not.exist(msg.a.b);
})
it('does not create missing parent properties of number', function() {
var msg = {a:123};
var result = util.setMessageProperty(msg, "msg.a.b.c", "bar", false);
result.should.be.false();
should.not.exist(msg.a.b);
})
it('does not set property of existing boolean property', function() {
var msg = {a:true};
var result = util.setMessageProperty(msg, "msg.a.b", "bar", false);
result.should.be.false();
should.not.exist(msg.a.b);
})
it('does not create missing parent properties of boolean', function() {
var msg = {a:true};
var result = util.setMessageProperty(msg, "msg.a.b.c", "bar", false);
result.should.be.false();
should.not.exist(msg.a.b);
})
it('deletes property if value is undefined', function() { it('deletes property if value is undefined', function() {
var msg = {a:{b:{c:"foo"}}}; var msg = {a:{b:{c:"foo"}}};
util.setMessageProperty(msg,"msg.a.b.c",undefined); var result = util.setMessageProperty(msg,"msg.a.b.c",undefined);
result.should.be.true();
should.not.exist(msg.a.b.c); should.not.exist(msg.a.b.c);
}) })
it('does not create missing parent properties if value is undefined', function() { it('does not create missing parent properties if value is undefined', function() {
var msg = {a:{}}; var msg = {a:{}};
util.setMessageProperty(msg,"msg.a.b.c",undefined); var result = util.setMessageProperty(msg,"msg.a.b.c",undefined);
result.should.be.false();
should.not.exist(msg.a.b); should.not.exist(msg.a.b);
}); });
it('sets a property with array syntax', function() { it('sets a property with array syntax', function() {
var msg = {a:{b:["foo",{c:["",""]}]}}; var msg = {a:{b:["foo",{c:["",""]}]}};
util.setMessageProperty(msg,"msg.a.b[1].c[1]","bar"); var result = util.setMessageProperty(msg,"msg.a.b[1].c[1]","bar");
result.should.be.true();
msg.a.b[1].c[1].should.eql('bar'); msg.a.b[1].c[1].should.eql('bar');
}); });
it('creates missing array elements - final property', function() { it('creates missing array elements - final property', function() {
var msg = {a:[]}; var msg = {a:[]};
util.setMessageProperty(msg,"msg.a[2]","bar"); var result = util.setMessageProperty(msg,"msg.a[2]","bar");
result.should.be.true();
msg.a.should.have.length(3); msg.a.should.have.length(3);
msg.a[2].should.eql("bar"); msg.a[2].should.eql("bar");
}); });
it('creates missing array elements - mid property', function() { it('creates missing array elements - mid property', function() {
var msg = {}; var msg = {};
util.setMessageProperty(msg,"msg.a[2].b","bar"); var result = util.setMessageProperty(msg,"msg.a[2].b","bar");
result.should.be.true();
msg.a.should.have.length(3); msg.a.should.have.length(3);
msg.a[2].b.should.eql("bar"); msg.a[2].b.should.eql("bar");
}); });
it('creates missing array elements - multi-arrays', function() { it('creates missing array elements - multi-arrays', function() {
var msg = {}; var msg = {};
util.setMessageProperty(msg,"msg.a[2][2]","bar"); var result = util.setMessageProperty(msg,"msg.a[2][2]","bar");
result.should.be.true();
msg.a.should.have.length(3); msg.a.should.have.length(3);
msg.a.should.be.instanceOf(Array); msg.a.should.be.instanceOf(Array);
msg.a[2].should.have.length(3); msg.a[2].should.have.length(3);
@ -258,19 +311,22 @@ describe("@node-red/util/util", function() {
}); });
it('does not create missing array elements - mid property', function () { it('does not create missing array elements - mid property', function () {
var msg = {a:[]}; var msg = {a:[]};
util.setMessageProperty(msg, "msg.a[1][1]", "bar", false); var result = util.setMessageProperty(msg, "msg.a[1][1]", "bar", false);
result.should.be.false();
msg.a.should.empty(); msg.a.should.empty();
}); });
it('does not create missing array elements - final property', function() { it('does not create missing array elements - final property', function() {
var msg = {a:{}}; var msg = {a:{}};
util.setMessageProperty(msg,"msg.a.b[2]","bar",false); var result = util.setMessageProperty(msg,"msg.a.b[2]","bar",false);
result.should.be.false();
should.not.exist(msg.a.b); should.not.exist(msg.a.b);
// check it has not been misinterpreted // check it has not been misinterpreted
msg.a.should.not.have.property("b[2]"); msg.a.should.not.have.property("b[2]");
}); });
it('deletes property inside array if value is undefined', function() { it('deletes property inside array if value is undefined', function() {
var msg = {a:[1,2,3]}; var msg = {a:[1,2,3]};
util.setMessageProperty(msg,"msg.a[1]",undefined); var result = util.setMessageProperty(msg,"msg.a[1]",undefined);
result.should.be.true();
msg.a.should.have.length(2); msg.a.should.have.length(2);
msg.a[0].should.eql(1); msg.a[0].should.eql(1);
msg.a[1].should.eql(3); msg.a[1].should.eql(3);
@ -511,7 +567,7 @@ describe("@node-red/util/util", function() {
result.should.eql('foo'); result.should.eql('foo');
}); });
it('accesses moment from an expression', function() { it('accesses moment from an expression', function() {
var expr = util.prepareJSONataExpression('$moment("2020-05-27", "YYYY-MM-DD").add("days", 7).add("months", 1).format("YYYY-MM-DD")',{}); var expr = util.prepareJSONataExpression('$moment("2020-05-27", "YYYY-MM-DD").add(7, "days").add(1, "months").format("YYYY-MM-DD")',{});
var result = util.evaluateJSONataExpression(expr,{}); var result = util.evaluateJSONataExpression(expr,{});
result.should.eql('2020-07-03'); result.should.eql('2020-07-03');
}); });