mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
add property choice to xml, sentiment nodes
add tests
This commit is contained in:
parent
a11a279c00
commit
e793a1e1aa
@ -1,20 +1,9 @@
|
|||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<script type="text/x-red" data-template-name="sentiment">
|
<script type="text/x-red" data-template-name="sentiment">
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
||||||
|
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||||
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
@ -22,7 +11,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/x-red" data-help-name="sentiment">
|
<script type="text/x-red" data-help-name="sentiment">
|
||||||
<p>Analyses the <code>payload</code> and adds a <code>sentiment</code> object.</p>
|
<p>Analyses the chosen property, default <code>payload</code>, and adds a <code>sentiment</code> object.</p>
|
||||||
<h3>Outputs</h3>
|
<h3>Outputs</h3>
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
<dt>sentiment <span class="property-type">object</span></dt>
|
<dt>sentiment <span class="property-type">object</span></dt>
|
||||||
@ -47,6 +36,7 @@
|
|||||||
color:"#E6E0F8",
|
color:"#E6E0F8",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
|
property: {value:"payload",required:true}
|
||||||
},
|
},
|
||||||
inputs:1,
|
inputs:1,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
@ -56,6 +46,12 @@
|
|||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
return this.name?"node_label_italic":"";
|
return this.name?"node_label_italic":"";
|
||||||
|
},
|
||||||
|
oneditprepare: function() {
|
||||||
|
if (this.property === undefined) {
|
||||||
|
$("#node-input-property").val("payload");
|
||||||
|
}
|
||||||
|
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -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) {
|
module.exports = function(RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
@ -20,16 +5,18 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
function SentimentNode(n) {
|
function SentimentNode(n) {
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
|
this.property = n.property||"payload";
|
||||||
var node = this;
|
var node = this;
|
||||||
|
|
||||||
this.on("input", function(msg) {
|
this.on("input", function(msg) {
|
||||||
if (msg.hasOwnProperty("payload")) {
|
var value = RED.util.getMessageProperty(msg,node.property);
|
||||||
sentiment(msg.payload, msg.overrides || null, function (err, result) {
|
if (value !== undefined) {
|
||||||
|
sentiment(value, msg.overrides || null, function (err, result) {
|
||||||
msg.sentiment = result;
|
msg.sentiment = result;
|
||||||
node.send(msg);
|
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);
|
RED.nodes.registerType("sentiment",SentimentNode);
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
|
|
||||||
<script type="text/x-red" data-template-name="xml">
|
<script type="text/x-red" data-template-name="xml">
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
||||||
|
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||||
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
@ -58,6 +62,7 @@
|
|||||||
color:"#DEBD5C",
|
color:"#DEBD5C",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
|
property: {value:"payload",required:true},
|
||||||
attr: {value:""},
|
attr: {value:""},
|
||||||
chr: {value:""}
|
chr: {value:""}
|
||||||
},
|
},
|
||||||
@ -69,6 +74,12 @@
|
|||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
return this.name?"node_label_italic":"";
|
return this.name?"node_label_italic":"";
|
||||||
|
},
|
||||||
|
oneditprepare: function() {
|
||||||
|
if (this.property === undefined) {
|
||||||
|
$("#node-input-property").val("payload");
|
||||||
|
}
|
||||||
|
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -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) {
|
module.exports = function(RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
@ -23,35 +8,39 @@ module.exports = function(RED) {
|
|||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
this.attrkey = n.attr;
|
this.attrkey = n.attr;
|
||||||
this.charkey = n.chr;
|
this.charkey = n.chr;
|
||||||
|
this.property = n.property||"payload";
|
||||||
var node = this;
|
var node = this;
|
||||||
this.on("input", function(msg) {
|
this.on("input", function(msg) {
|
||||||
if (msg.hasOwnProperty("payload")) {
|
var value = RED.util.getMessageProperty(msg,node.property);
|
||||||
|
if (value !== undefined) {
|
||||||
var options;
|
var options;
|
||||||
if (typeof msg.payload === "object") {
|
if (typeof value === "object") {
|
||||||
options = {renderOpts:{pretty:false}};
|
options = {renderOpts:{pretty:false}};
|
||||||
if (msg.hasOwnProperty("options") && typeof msg.options === "object") { options = msg.options; }
|
if (msg.hasOwnProperty("options") && typeof msg.options === "object") { options = msg.options; }
|
||||||
options.async = false;
|
options.async = false;
|
||||||
var builder = new xml2js.Builder(options);
|
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);
|
node.send(msg);
|
||||||
}
|
}
|
||||||
else if (typeof msg.payload == "string") {
|
else if (typeof value == "string") {
|
||||||
options = {};
|
options = {};
|
||||||
if (msg.hasOwnProperty("options") && typeof msg.options === "object") { options = msg.options; }
|
if (msg.hasOwnProperty("options") && typeof msg.options === "object") { options = msg.options; }
|
||||||
options.async = true;
|
options.async = true;
|
||||||
options.attrkey = node.attrkey || options.attrkey || '$';
|
options.attrkey = node.attrkey || options.attrkey || '$';
|
||||||
options.charkey = node.charkey || options.charkey || '_';
|
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); }
|
if (err) { node.error(err, msg); }
|
||||||
else {
|
else {
|
||||||
msg.payload = result;
|
value = result;
|
||||||
|
RED.util.setMessageProperty(msg,node.property,value);
|
||||||
node.send(msg);
|
node.send(msg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else { node.warn(RED._("xml.errors.xml_js")); }
|
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);
|
RED.nodes.registerType("xml",XMLNode);
|
||||||
|
@ -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) {
|
it('should add a negative score for bad words', function(done) {
|
||||||
var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]},
|
var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]},
|
||||||
{id:"jn2", type:"helper"}];
|
{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) {
|
it('should allow you to override word scoring', function(done) {
|
||||||
var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]},
|
var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]]},
|
||||||
{id:"jn2", type:"helper"}];
|
{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});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -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 = '<employees><firstName>John</firstName><lastName>Smith</lastName></employees>';
|
||||||
|
n1.receive({foo:string,topic: "bar"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should convert a valid xml string to a javascript object with options', function(done) {
|
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;"},
|
var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"},
|
||||||
{id:"n2", type:"helper"}];
|
{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) {
|
it('should convert a javascript object to an xml string with options - alternative property', function(done) {
|
||||||
var flow = [{id:"n1",type:"xml",wires:[["n2"]],func:"return msg;"},
|
var flow = [{id:"n1",type:"xml",property:"foo",wires:[["n2"]],func:"return msg;"},
|
||||||
{id:"n2", type:"helper"}];
|
{id:"n2", type:"helper"}];
|
||||||
helper.load(xmlNode, flow, function() {
|
helper.load(xmlNode, flow, function() {
|
||||||
var n1 = helper.getNode("n1");
|
var n1 = helper.getNode("n1");
|
||||||
var n2 = helper.getNode("n2");
|
var n2 = helper.getNode("n2");
|
||||||
n2.on("input", function(msg) {
|
n2.on("input", function(msg) {
|
||||||
msg.should.have.property('topic', 'bar');
|
msg.should.have.property('topic', 'bar');
|
||||||
var index = msg.payload.indexOf('<employees>\n <firstName>John</firstName>\n <lastName>Smith</lastName>\n</employees>');
|
var index = msg.foo.indexOf('<employees>\n <firstName>John</firstName>\n <lastName>Smith</lastName>\n</employees>');
|
||||||
index.should.be.above(-1);
|
index.should.be.above(-1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
var obj = {"employees":{"firstName":["John"],"lastName":["Smith"] }};
|
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}});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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) {
|
it('should convert a javascript object to a yaml string', function(done) {
|
||||||
var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"},
|
var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"},
|
||||||
{id:"yn2", type:"helper"}];
|
{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) {
|
it('should convert an array to a yaml string', function(done) {
|
||||||
var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"},
|
var flow = [{id:"yn1",type:"yaml",wires:[["yn2"]],func:"return msg;"},
|
||||||
{id:"yn2", type:"helper"}];
|
{id:"yn2", type:"helper"}];
|
||||||
|
Loading…
Reference in New Issue
Block a user