From a11a279c007b32a68c5f5fd9b2527ad2b0af5c17 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Tue, 16 Jan 2018 10:59:44 +0000 Subject: [PATCH 1/2] add msg. select to range and yaml nodes, re-order son node (name to bottom) add common.label.property to messages list --- nodes/core/locales/en-US/messages.json | 5 +++-- nodes/core/logic/16-range.html | 11 +++++++++++ nodes/core/logic/16-range.js | 13 ++++++++----- nodes/core/parsers/70-JSON.html | 17 +++++++---------- nodes/core/parsers/70-YAML.html | 11 +++++++++++ nodes/core/parsers/70-YAML.js | 16 ++++++++++------ 6 files changed, 50 insertions(+), 23 deletions(-) diff --git a/nodes/core/locales/en-US/messages.json b/nodes/core/locales/en-US/messages.json index 6665387ae..62339d81a 100644 --- a/nodes/core/locales/en-US/messages.json +++ b/nodes/core/locales/en-US/messages.json @@ -5,7 +5,8 @@ "topic": "Topic", "name": "Name", "username": "Username", - "password": "Password" + "password": "Password", + "property": "Property" }, "status": { "connected": "connected", @@ -602,7 +603,7 @@ "maxout": "e.g. 255" }, "scale": { - "payload": "Scale msg.payload", + "payload": "Scale the message property", "limit": "Scale and limit to the target range", "wrap": "Scale and wrap within the target range" }, diff --git a/nodes/core/logic/16-range.html b/nodes/core/logic/16-range.html index 321bec7e4..37d35fb85 100644 --- a/nodes/core/logic/16-range.html +++ b/nodes/core/logic/16-range.html @@ -1,5 +1,9 @@ diff --git a/nodes/core/logic/16-range.js b/nodes/core/logic/16-range.js index 1de073fee..b92b155ed 100644 --- a/nodes/core/logic/16-range.js +++ b/nodes/core/logic/16-range.js @@ -24,11 +24,13 @@ module.exports = function(RED) { this.maxin = Number(n.maxin); this.minout = Number(n.minout); this.maxout = Number(n.maxout); + this.property = n.property||"payload"; var node = this; this.on('input', function (msg) { - if (msg.hasOwnProperty("payload")) { - var n = Number(msg.payload); + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { + var n = Number(value); if (!isNaN(n)) { if (node.action == "clamp") { if (n < node.minin) { n = node.minin; } @@ -38,11 +40,12 @@ module.exports = function(RED) { var divisor = node.maxin - node.minin; n = ((n - node.minin) % divisor + divisor) % divisor + node.minin; } - msg.payload = ((n - node.minin) / (node.maxin - node.minin) * (node.maxout - node.minout)) + node.minout; - if (node.round) { msg.payload = Math.round(msg.payload); } + value = ((n - node.minin) / (node.maxin - node.minin) * (node.maxout - node.minout)) + node.minout; + if (node.round) { value = Math.round(value); } + RED.util.setMessageProperty(msg,node.property,value); node.send(msg); } - else { node.log(RED._("range.errors.notnumber")+": "+msg.payload); } + else { node.log(RED._("range.errors.notnumber")+": "+value); } } else { node.send(msg); } // If no payload - just pass it on. }); diff --git a/nodes/core/parsers/70-JSON.html b/nodes/core/parsers/70-JSON.html index f473c6039..01ffe42b3 100644 --- a/nodes/core/parsers/70-JSON.html +++ b/nodes/core/parsers/70-JSON.html @@ -1,9 +1,5 @@ diff --git a/nodes/core/parsers/70-YAML.js b/nodes/core/parsers/70-YAML.js index ae4ca1a8c..1a34fdd57 100644 --- a/nodes/core/parsers/70-YAML.js +++ b/nodes/core/parsers/70-YAML.js @@ -4,20 +4,24 @@ module.exports = function(RED) { var yaml = require('js-yaml'); function YAMLNode(n) { RED.nodes.createNode(this,n); + this.property = n.property||"payload"; var node = this; this.on("input", function(msg) { - if (msg.hasOwnProperty("payload")) { - if (typeof msg.payload === "string") { + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { + if (typeof value === "string") { try { - msg.payload = yaml.load(msg.payload); + value = yaml.load(value); + RED.util.setMessageProperty(msg,node.property,value); node.send(msg); } catch(e) { node.error(e.message,msg); } } - else if (typeof msg.payload === "object") { - if (!Buffer.isBuffer(msg.payload)) { + else if (typeof value === "object") { + if (!Buffer.isBuffer(value)) { try { - msg.payload = yaml.dump(msg.payload); + value = yaml.dump(value); + RED.util.setMessageProperty(msg,node.property,value); node.send(msg); } catch(e) { From e793a1e1aab506bcdad36e17c34e43b6f61f8abe Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Tue, 16 Jan 2018 21:43:37 +0000 Subject: [PATCH 2/2] add property choice to xml, sentiment nodes add tests --- nodes/core/analysis/72-sentiment.html | 28 ++++----- nodes/core/analysis/72-sentiment.js | 23 ++------ nodes/core/parsers/70-XML.html | 11 ++++ nodes/core/parsers/70-XML.js | 33 ++++------- test/nodes/core/analysis/72-sentiment_spec.js | 59 +++++++++++++++++++ test/nodes/core/parsers/70-XML_spec.js | 30 ++++++++-- test/nodes/core/parsers/70-YAML_spec.js | 33 +++++++++++ 7 files changed, 156 insertions(+), 61 deletions(-) diff --git a/nodes/core/analysis/72-sentiment.html b/nodes/core/analysis/72-sentiment.html index aa35ffb05..0ba1ccade 100644 --- a/nodes/core/analysis/72-sentiment.html +++ b/nodes/core/analysis/72-sentiment.html @@ -1,20 +1,9 @@ - diff --git a/nodes/core/analysis/72-sentiment.js b/nodes/core/analysis/72-sentiment.js index 43a800e2a..ff0cf33e8 100644 --- a/nodes/core/analysis/72-sentiment.js +++ b/nodes/core/analysis/72-sentiment.js @@ -1,18 +1,3 @@ -/** - * 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. - **/ module.exports = function(RED) { "use strict"; @@ -20,16 +5,18 @@ module.exports = function(RED) { function SentimentNode(n) { RED.nodes.createNode(this,n); + this.property = n.property||"payload"; var node = this; this.on("input", function(msg) { - if (msg.hasOwnProperty("payload")) { - sentiment(msg.payload, msg.overrides || null, function (err, result) { + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { + sentiment(value, msg.overrides || null, function (err, result) { msg.sentiment = result; node.send(msg); }); } - else { node.send(msg); } // If no payload - just pass it on. + else { node.send(msg); } // If no matching property - just pass it on. }); } RED.nodes.registerType("sentiment",SentimentNode); diff --git a/nodes/core/parsers/70-XML.html b/nodes/core/parsers/70-XML.html index f33ef6811..25d17998c 100644 --- a/nodes/core/parsers/70-XML.html +++ b/nodes/core/parsers/70-XML.html @@ -1,5 +1,9 @@ diff --git a/nodes/core/parsers/70-XML.js b/nodes/core/parsers/70-XML.js index 32991f07d..3bfd38101 100644 --- a/nodes/core/parsers/70-XML.js +++ b/nodes/core/parsers/70-XML.js @@ -1,18 +1,3 @@ -/** - * 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. - **/ module.exports = function(RED) { "use strict"; @@ -23,35 +8,39 @@ module.exports = function(RED) { RED.nodes.createNode(this,n); this.attrkey = n.attr; this.charkey = n.chr; + this.property = n.property||"payload"; var node = this; this.on("input", function(msg) { - if (msg.hasOwnProperty("payload")) { + var value = RED.util.getMessageProperty(msg,node.property); + if (value !== undefined) { var options; - if (typeof msg.payload === "object") { + if (typeof value === "object") { options = {renderOpts:{pretty:false}}; if (msg.hasOwnProperty("options") && typeof msg.options === "object") { options = msg.options; } options.async = false; var builder = new xml2js.Builder(options); - msg.payload = builder.buildObject(msg.payload, options); + value = builder.buildObject(value, options); + RED.util.setMessageProperty(msg,node.property,value); node.send(msg); } - else if (typeof msg.payload == "string") { + else if (typeof value == "string") { options = {}; if (msg.hasOwnProperty("options") && typeof msg.options === "object") { options = msg.options; } options.async = true; options.attrkey = node.attrkey || options.attrkey || '$'; options.charkey = node.charkey || options.charkey || '_'; - parseString(msg.payload, options, function (err, result) { + parseString(value, options, function (err, result) { if (err) { node.error(err, msg); } else { - msg.payload = result; + value = result; + RED.util.setMessageProperty(msg,node.property,value); node.send(msg); } }); } else { node.warn(RED._("xml.errors.xml_js")); } } - else { node.send(msg); } // If no payload - just pass it on. + else { node.send(msg); } // If no property - just pass it on. }); } RED.nodes.registerType("xml",XMLNode); diff --git a/test/nodes/core/analysis/72-sentiment_spec.js b/test/nodes/core/analysis/72-sentiment_spec.js index 51f06abff..3a6ae07b1 100644 --- a/test/nodes/core/analysis/72-sentiment_spec.js +++ b/test/nodes/core/analysis/72-sentiment_spec.js @@ -75,6 +75,28 @@ describe('sentiment Node', function() { }); }); + it('should add a positive score for good words - alternative property', function(done) { + var flow = [{id:"jn1",type:"sentiment",property:"foo",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(sentimentNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + try { + msg.should.have.property('sentiment'); + msg.sentiment.should.have.property('score'); + msg.sentiment.score.should.be.a.Number(); + msg.sentiment.score.should.be.above(10); + done(); + } catch(err) { + done(err); + } + }); + var testString = 'good, great, best, brilliant'; + jn1.receive({foo:testString}); + }); + }); + it('should add a negative score for bad words', function(done) { var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]}, {id:"jn2", type:"helper"}]; @@ -93,6 +115,24 @@ describe('sentiment Node', function() { }); }); + it('should add a negative score for bad words - alternative property', function(done) { + var flow = [{id:"jn1",type:"sentiment",property:"foo",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(sentimentNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + msg.should.have.property('sentiment'); + msg.sentiment.should.have.property('score'); + msg.sentiment.score.should.be.a.Number(); + msg.sentiment.score.should.be.below(-10); + done(); + }); + var testString = 'bad, horrible, negative, awful'; + jn1.receive({foo:testString}); + }); + }); + it('should allow you to override word scoring', function(done) { var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]}, {id:"jn2", type:"helper"}]; @@ -112,4 +152,23 @@ describe('sentiment Node', function() { }); }); + it('should allow you to override word scoring - alternative property', function(done) { + var flow = [{id:"jn1",type:"sentiment",property:"foo",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(sentimentNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + msg.should.have.property('sentiment'); + msg.sentiment.should.have.property('score'); + msg.sentiment.score.should.be.a.Number(); + msg.sentiment.score.should.equal(20); + done(); + }); + var testString = 'sick, wicked'; + var overrides = {'sick': 10, 'wicked': 10 }; + jn1.receive({foo:testString,overrides:overrides}); + }); + }); + }); diff --git a/test/nodes/core/parsers/70-XML_spec.js b/test/nodes/core/parsers/70-XML_spec.js index 68e3ddd52..79c1de30f 100644 --- a/test/nodes/core/parsers/70-XML_spec.js +++ b/test/nodes/core/parsers/70-XML_spec.js @@ -57,6 +57,26 @@ describe('XML node', function() { }); }); + it('should convert a valid xml string to a javascript object - alternative property', function(done) { + var flow = [{id:"n1",type:"xml",property:"foo",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(xmlNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.foo.should.have.property('employees'); + msg.foo.employees.should.have.property('firstName'); + should.equal(msg.foo.employees.firstName[0], 'John'); + msg.foo.employees.should.have.property('lastName'); + should.equal(msg.foo.employees.lastName[0], 'Smith'); + done(); + }); + var string = 'JohnSmith'; + n1.receive({foo:string,topic: "bar"}); + }); + }); + it('should convert a valid xml string to a javascript object with options', function(done) { var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"}, {id:"n2", type:"helper"}]; @@ -94,20 +114,20 @@ describe('XML node', function() { }); }); - it('should convert a javascript object to an xml string with options', function(done) { - var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"}, + it('should convert a javascript object to an xml string with options - alternative property', function(done) { + var flow = [{id:"n1",type:"xml",property:"foo",wires:[["n2"]],func:"return msg;"}, {id:"n2", type:"helper"}]; helper.load(xmlNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); n2.on("input", function(msg) { msg.should.have.property('topic', 'bar'); - var index = msg.payload.indexOf('\n John\n Smith\n'); + var index = msg.foo.indexOf('\n John\n Smith\n'); index.should.be.above(-1); done(); }); var obj = {"employees":{"firstName":["John"],"lastName":["Smith"] }}; - n1.receive({payload:obj, topic:"bar", options:{headless:true}}); + n1.receive({foo:obj, topic:"bar", options:{headless:true}}); }); }); @@ -133,7 +153,7 @@ describe('XML node', function() { },200); }); }); - + it('should log an error if asked to parse something thats not xml or js', function(done) { var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"}, {id:"n2", type:"helper"}]; diff --git a/test/nodes/core/parsers/70-YAML_spec.js b/test/nodes/core/parsers/70-YAML_spec.js index 9055efa3d..9f2fa7ec5 100644 --- a/test/nodes/core/parsers/70-YAML_spec.js +++ b/test/nodes/core/parsers/70-YAML_spec.js @@ -55,6 +55,24 @@ describe('YAML node', function() { }); }); + it('should convert a valid yaml string to a javascript object - using another property', function(done) { + var flow = [{id:"yn1",type:"yaml",property:"foo",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + yn2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.foo.should.have.property('employees'); + msg.foo.employees[0].should.have.property('firstName', 'John'); + msg.foo.employees[0].should.have.property('lastName', 'Smith'); + done(); + }); + var yamlString = "employees:\n - firstName: John\n lastName: Smith\n"; + yn1.receive({foo:yamlString,topic: "bar"}); + }); + }); + it('should convert a javascript object to a yaml string', function(done) { var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, {id:"yn2", type:"helper"}]; @@ -70,6 +88,21 @@ describe('YAML node', function() { }); }); + it('should convert a javascript object to a yaml string - using another property', function(done) { + var flow = [{id:"yn1",type:"yaml",property:"foo",wires:[["yn2"]],func:"return msg;"}, + {id:"yn2", type:"helper"}]; + helper.load(yamlNode, flow, function() { + var yn1 = helper.getNode("yn1"); + var yn2 = helper.getNode("yn2"); + yn2.on("input", function(msg) { + should.equal(msg.foo, "employees:\n - firstName: John\n lastName: Smith\n"); + done(); + }); + var obj = {employees:[{firstName:"John", lastName:"Smith"}]}; + yn1.receive({foo:obj}); + }); + }); + it('should convert an array to a yaml string', function(done) { var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"}, {id:"yn2", type:"helper"}];