mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
29 Commits
Handle-Rea
...
0.19.3
Author | SHA1 | Date | |
---|---|---|---|
|
6fa8b7f5f1 | ||
|
a2d03c14ae | ||
|
c667a0e74c | ||
|
8123828113 | ||
|
72b8dbb45b | ||
|
7703875740 | ||
|
6442bb8a13 | ||
|
f29d7c9252 | ||
|
2f7f53ed96 | ||
|
94031a52a5 | ||
|
d67f91e7ed | ||
|
f37697c4fb | ||
|
69448c7329 | ||
|
8e9815fb91 | ||
|
4cdd7978cf | ||
|
40d81358f4 | ||
|
c7b62aed91 | ||
|
c0e7d6d826 | ||
|
f809377de8 | ||
|
9767bd9697 | ||
|
3a55528552 | ||
|
56197ffe3a | ||
|
0f0d0c046c | ||
|
ecc4973645 | ||
|
df161ce672 | ||
|
72fe30892e | ||
|
695873d35a | ||
|
15da19dcea | ||
|
d5bdc1600b |
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,3 +1,19 @@
|
||||
#### 0.19.3: Maintenance Release
|
||||
|
||||
- Split node - fix complete to send msg for k/v object
|
||||
- Remove unused Join node merged object key typed input
|
||||
- Set the JavaScript editor to full-screen
|
||||
- Filter global modules installed locally
|
||||
- Add svg to permitted icon extension list
|
||||
- Debug node - indicate status all the time if selected to do so
|
||||
- pi nodes - increase test coverage slightly
|
||||
- TCP-request node - only write payload
|
||||
- JSON schema: perform validation when obj -> obj or str -> str
|
||||
- JSON schema: add draft-06 support (via $schema keyword)
|
||||
- Mqtt proxy configuration for websocket connection, #1651.
|
||||
- Allows MQTT Shared Subscriptions for MQTT-In core node
|
||||
- Fix use of HTML tag or CSS class specification as icon of typedInput
|
||||
|
||||
#### 0.19.2: Maintenance Release
|
||||
|
||||
- Ensure node default colour is used if palette.theme has no match
|
||||
|
@@ -522,10 +522,18 @@
|
||||
this.selectLabel.empty();
|
||||
var image;
|
||||
if (opt.icon) {
|
||||
image = new Image();
|
||||
image.name = opt.icon;
|
||||
image.src = opt.icon;
|
||||
$('<img>',{src:opt.icon,style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel);
|
||||
if (opt.icon.indexOf("<") === 0) {
|
||||
$(opt.icon).prependTo(this.selectLabel);
|
||||
}
|
||||
else if (opt.icon.indexOf("/") !== -1) {
|
||||
image = new Image();
|
||||
image.name = opt.icon;
|
||||
image.src = opt.icon;
|
||||
$('<img>',{src:opt.icon,style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel);
|
||||
}
|
||||
else {
|
||||
$('<i>',{class:"red-ui-typedInput-icon "+opt.icon}).prependTo(this.selectLabel);
|
||||
}
|
||||
} else {
|
||||
this.selectLabel.text(opt.label);
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ RED.editor.types._js = (function() {
|
||||
|
||||
var trayOptions = {
|
||||
title: options.title,
|
||||
width: "inherit",
|
||||
width: options.width||"inherit",
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
|
@@ -19,7 +19,11 @@ module.exports = function(RED) {
|
||||
if (this.tosidebar === undefined) { this.tosidebar = true; }
|
||||
this.severity = n.severity || 40;
|
||||
this.active = (n.active === null || typeof n.active === "undefined") || n.active;
|
||||
this.status({});
|
||||
if (this.tostatus) {
|
||||
this.oldStatus = {fill:"grey", shape:"ring"};
|
||||
this.status(this.oldStatus);
|
||||
}
|
||||
else { this.status({}); }
|
||||
|
||||
var node = this;
|
||||
var levels = {
|
||||
@@ -122,12 +126,12 @@ module.exports = function(RED) {
|
||||
if (state === "enable") {
|
||||
node.active = true;
|
||||
res.sendStatus(200);
|
||||
if (node.tostatus) { node.status({}); }
|
||||
if (node.tostatus) { node.status({fill:"grey", shape:"dot"}); }
|
||||
} else if (state === "disable") {
|
||||
node.active = false;
|
||||
res.sendStatus(201);
|
||||
if (node.tostatus && node.hasOwnProperty("oldStatus")) {
|
||||
node.oldStatus.shape = "ring";
|
||||
node.oldStatus.shape = "dot";
|
||||
node.status(node.oldStatus);
|
||||
}
|
||||
} else {
|
||||
|
@@ -126,6 +126,7 @@
|
||||
var value = that.editor.getValue();
|
||||
RED.editor.editJavaScript({
|
||||
value: value,
|
||||
width: "Infinity",
|
||||
cursor: that.editor.getCursorPosition(),
|
||||
complete: function(v,cursor) {
|
||||
that.editor.setValue(v, -1);
|
||||
|
@@ -42,7 +42,7 @@ module.exports = function(RED) {
|
||||
if (type === 'object') {
|
||||
type = Buffer.isBuffer(msg)?'Buffer':(util.isArray(msg)?'Array':'Date');
|
||||
}
|
||||
node.error(RED._("function.error.non-message-returned",{ type: type }))
|
||||
node.error(RED._("function.error.non-message-returned",{ type: type }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,9 +203,9 @@ module.exports = function(RED) {
|
||||
if (util.hasOwnProperty('promisify')) {
|
||||
sandbox.setTimeout[util.promisify.custom] = function(after, value) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
sandbox.setTimeout(function(){ resolve(value) }, after);
|
||||
sandbox.setTimeout(function(){ resolve(value); }, after);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
var context = vm.createContext(sandbox);
|
||||
try {
|
||||
@@ -241,7 +241,6 @@ module.exports = function(RED) {
|
||||
|
||||
var line = 0;
|
||||
var errorMessage;
|
||||
var stack = err.stack.split(/\r?\n/);
|
||||
if (stack.length > 0) {
|
||||
while (line < stack.length && stack[line].indexOf("ReferenceError") !== 0) {
|
||||
line++;
|
||||
@@ -265,13 +264,13 @@ module.exports = function(RED) {
|
||||
});
|
||||
this.on("close", function() {
|
||||
while (node.outstandingTimers.length > 0) {
|
||||
clearTimeout(node.outstandingTimers.pop())
|
||||
clearTimeout(node.outstandingTimers.pop());
|
||||
}
|
||||
while (node.outstandingIntervals.length > 0) {
|
||||
clearInterval(node.outstandingIntervals.pop())
|
||||
clearInterval(node.outstandingIntervals.pop());
|
||||
}
|
||||
this.status({});
|
||||
})
|
||||
});
|
||||
} catch(err) {
|
||||
// eg SyntaxError - which v8 doesn't include line number information
|
||||
// so we can't do better than this
|
||||
@@ -280,4 +279,4 @@ module.exports = function(RED) {
|
||||
}
|
||||
RED.nodes.registerType("function",FunctionNode);
|
||||
RED.library.register("functions");
|
||||
}
|
||||
};
|
||||
|
@@ -19,11 +19,26 @@ module.exports = function(RED) {
|
||||
var mqtt = require("mqtt");
|
||||
var util = require("util");
|
||||
var isUtf8 = require('is-utf8');
|
||||
var HttpsProxyAgent = require('https-proxy-agent');
|
||||
var url = require('url');
|
||||
|
||||
function matchTopic(ts,t) {
|
||||
if (ts == "#") {
|
||||
return true;
|
||||
}
|
||||
/* The following allows shared subscriptions (as in MQTT v5)
|
||||
http://docs.oasis-open.org/mqtt/mqtt/v5.0/cs02/mqtt-v5.0-cs02.html#_Toc514345522
|
||||
|
||||
4.8.2 describes shares like:
|
||||
$share/{ShareName}/{filter}
|
||||
$share is a literal string that marks the Topic Filter as being a Shared Subscription Topic Filter.
|
||||
{ShareName} is a character string that does not include "/", "+" or "#"
|
||||
{filter} The remainder of the string has the same syntax and semantics as a Topic Filter in a non-shared subscription. Refer to section 4.7.
|
||||
*/
|
||||
else if(ts.startsWith("$share")){
|
||||
ts = ts.replace(/^\$share\/[^#+/]+\/(.*)/g,"$1");
|
||||
|
||||
}
|
||||
var re = new RegExp("^"+ts.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
|
||||
return re.test(t);
|
||||
}
|
||||
@@ -96,12 +111,29 @@ module.exports = function(RED) {
|
||||
if (typeof this.cleansession === 'undefined') {
|
||||
this.cleansession = true;
|
||||
}
|
||||
var prox;
|
||||
if (process.env.http_proxy != null) { prox = process.env.http_proxy; }
|
||||
if (process.env.HTTP_PROXY != null) { prox = process.env.HTTP_PROXY; }
|
||||
|
||||
// Create the URL to pass in to the MQTT.js library
|
||||
if (this.brokerurl === "") {
|
||||
// if the broker may be ws:// or wss:// or even tcp://
|
||||
if (this.broker.indexOf("://") > -1) {
|
||||
this.brokerurl = this.broker;
|
||||
// Only for ws or wss, check if proxy env var for additional configuration
|
||||
if (this.brokerurl.indexOf("wss://") > -1 || this.brokerurl.indexOf("ws://") > -1 )
|
||||
// check if proxy is set in env
|
||||
if (prox) {
|
||||
var parsedUrl = url.parse(this.brokerurl);
|
||||
var proxyOpts = url.parse(prox);
|
||||
// true for wss
|
||||
proxyOpts.secureEndpoint = parsedUrl.protocol ? parsedUrl.protocol === 'wss:' : true;
|
||||
// Set Agent for wsOption in MQTT
|
||||
var agent = new HttpsProxyAgent(proxyOpts);
|
||||
this.options.wsOptions = {
|
||||
agent: agent
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// construct the std mqtt:// url
|
||||
if (this.usetls) {
|
||||
@@ -435,4 +467,4 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("mqtt out",MQTTOutNode);
|
||||
};
|
||||
};
|
@@ -33,9 +33,7 @@ module.exports = function(RED) {
|
||||
*/
|
||||
const enqueue = (queue, item) => {
|
||||
// drop msgs from front of queue if size is going to be exceeded
|
||||
if (queue.size() === msgQueueSize) {
|
||||
queue.shift();
|
||||
}
|
||||
if (queue.size() === msgQueueSize) { queue.shift(); }
|
||||
queue.push(item);
|
||||
return queue;
|
||||
};
|
||||
@@ -646,7 +644,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
else if (!clients[connection_id].connecting && clients[connection_id].connected) {
|
||||
if (clients[connection_id] && clients[connection_id].client) {
|
||||
clients[connection_id].client.write(dequeue(clients[connection_id].msgQueue));
|
||||
clients[connection_id].client.write(dequeue(clients[connection_id].msgQueue).payload);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -295,7 +295,8 @@
|
||||
For object outputs, once this count has been reached, the node can be configured to send a message for each subsequent message
|
||||
received.</p>
|
||||
<p>A <i>timeout</i> can be set to trigger sending the new message using whatever has been received so far.</p>
|
||||
<p>If a message is received with the <b>msg.complete</b> property set, the output message is sent.</p>
|
||||
<p>If a message is received with the <b>msg.complete</b> property set, the output message is finalised and sent.
|
||||
This resets any part counts.</p>
|
||||
|
||||
<h4>Reduce Sequence mode</h4>
|
||||
<p>When configured to join in reduce mode, an expression is applied to each
|
||||
@@ -439,10 +440,7 @@
|
||||
$("#node-input-joiner").typedInput({
|
||||
default: 'str',
|
||||
typeField: $("#node-input-joinerType"),
|
||||
types:[
|
||||
'str',
|
||||
'bin'
|
||||
]
|
||||
types:['str', 'bin']
|
||||
});
|
||||
|
||||
$("#node-input-property").typedInput({
|
||||
@@ -451,7 +449,7 @@
|
||||
});
|
||||
|
||||
$("#node-input-key").typedInput({
|
||||
types:['msg', {value:"merge", label:"", hasValue:false}]
|
||||
types:['msg']
|
||||
});
|
||||
|
||||
$("#node-input-build").change();
|
||||
|
@@ -586,7 +586,10 @@ module.exports = function(RED) {
|
||||
}
|
||||
else {
|
||||
if (msg.hasOwnProperty('complete')) {
|
||||
completeSend(partId);
|
||||
if (inflight[partId]) {
|
||||
inflight[partId].msg.complete = msg.complete;
|
||||
completeSend(partId);
|
||||
}
|
||||
}
|
||||
else {
|
||||
node.warn("Message missing key property 'msg."+node.key+"' - cannot add to object")
|
||||
@@ -594,6 +597,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inflight.hasOwnProperty(partId)) {
|
||||
if (payloadType === 'object' || payloadType === 'merged') {
|
||||
inflight[partId] = {
|
||||
@@ -604,19 +608,6 @@ module.exports = function(RED) {
|
||||
msg:RED.util.cloneMessage(msg)
|
||||
};
|
||||
}
|
||||
else if (node.accumulate === true) {
|
||||
if (msg.hasOwnProperty("reset")) { delete inflight[partId]; }
|
||||
inflight[partId] = inflight[partId] || {
|
||||
currentCount:0,
|
||||
payload:{},
|
||||
targetCount:targetCount,
|
||||
type:payloadType,
|
||||
msg:RED.util.cloneMessage(msg)
|
||||
}
|
||||
if (payloadType === 'string' || payloadType === 'array' || payloadType === 'buffer') {
|
||||
inflight[partId].payload = [];
|
||||
}
|
||||
}
|
||||
else {
|
||||
inflight[partId] = {
|
||||
currentCount:0,
|
||||
|
@@ -196,9 +196,10 @@ module.exports = function(RED) {
|
||||
}).catch(err => {
|
||||
node.error(err,msg);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var parts = msg.parts;
|
||||
if (!parts.hasOwnProperty("id") || !parts.hasOwnProperty("index")) {
|
||||
if (!parts || !parts.hasOwnProperty("id") || !parts.hasOwnProperty("index")) {
|
||||
return;
|
||||
}
|
||||
var gid = parts.id;
|
||||
@@ -242,7 +243,8 @@ module.exports = function(RED) {
|
||||
delete pending[key];
|
||||
}
|
||||
}
|
||||
pending_count = 0; })
|
||||
pending_count = 0;
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("sort", SortNode);
|
||||
|
@@ -19,6 +19,7 @@ module.exports = function(RED) {
|
||||
const Ajv = require('ajv');
|
||||
const ajv = new Ajv({allErrors: true, schemaId: 'auto'});
|
||||
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));
|
||||
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));
|
||||
|
||||
function JSONNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
@@ -29,6 +30,7 @@ module.exports = function(RED) {
|
||||
this.compiledSchema = null;
|
||||
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
var validate = false;
|
||||
if (msg.schema) {
|
||||
@@ -65,7 +67,17 @@ module.exports = function(RED) {
|
||||
}
|
||||
catch(e) { node.error(e.message,msg); }
|
||||
} else {
|
||||
node.send(msg);
|
||||
// If node.action is str and value is str
|
||||
if (validate) {
|
||||
if (this.compiledSchema(JSON.parse(msg[node.property]))) {
|
||||
node.send(msg);
|
||||
} else {
|
||||
msg.schemaError = this.compiledSchema.errors;
|
||||
node.error(`${RED._("json.errors.schema-error")}: ${ajv.errorsText(this.compiledSchema.errors)}`, msg);
|
||||
}
|
||||
} else {
|
||||
node.send(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof value === "object") {
|
||||
@@ -84,13 +96,22 @@ module.exports = function(RED) {
|
||||
RED.util.setMessageProperty(msg,node.property,JSON.stringify(value,null,node.indent));
|
||||
node.send(msg);
|
||||
}
|
||||
|
||||
}
|
||||
catch(e) { node.error(RED._("json.errors.dropped-error")); }
|
||||
}
|
||||
else { node.warn(RED._("json.errors.dropped-object")); }
|
||||
} else {
|
||||
node.send(msg);
|
||||
// If node.action is obj and value is object
|
||||
if (validate) {
|
||||
if (this.compiledSchema(value)) {
|
||||
node.send(msg);
|
||||
} else {
|
||||
msg.schemaError = this.compiledSchema.errors;
|
||||
node.error(`${RED._("json.errors.schema-error")}: ${ajv.errorsText(this.compiledSchema.errors)}`, msg);
|
||||
}
|
||||
} else {
|
||||
node.send(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { node.warn(RED._("json.errors.dropped")); }
|
||||
|
13
package.json
13
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-red",
|
||||
"version": "0.19.2",
|
||||
"version": "0.19.3",
|
||||
"description": "A visual tool for wiring the Internet of Things",
|
||||
"homepage": "http://nodered.org",
|
||||
"license": "Apache-2.0",
|
||||
@@ -42,13 +42,14 @@
|
||||
"cookie": "0.3.1",
|
||||
"cookie-parser": "1.4.3",
|
||||
"cors": "2.8.4",
|
||||
"cron": "1.3.0",
|
||||
"cron": "1.4.1",
|
||||
"denque": "1.3.0",
|
||||
"express": "4.16.3",
|
||||
"express-session": "1.15.6",
|
||||
"fs-extra": "5.0.0",
|
||||
"fs.notify": "0.0.4",
|
||||
"hash-sum": "1.0.2",
|
||||
"https-proxy-agent": "2.2.1",
|
||||
"i18next": "11.6.0",
|
||||
"is-utf8": "0.2.1",
|
||||
"js-yaml": "3.12.0",
|
||||
@@ -56,9 +57,9 @@
|
||||
"jsonata": "1.5.4",
|
||||
"media-typer": "0.3.0",
|
||||
"memorystore": "1.6.0",
|
||||
"mqtt": "2.18.5",
|
||||
"mqtt": "2.18.8",
|
||||
"multer": "1.3.1",
|
||||
"mustache": "2.3.1",
|
||||
"mustache": "2.3.2",
|
||||
"node-red-node-email": "0.1.*",
|
||||
"node-red-node-feedparser": "^0.1.12",
|
||||
"node-red-node-rbe": "0.2.*",
|
||||
@@ -73,7 +74,7 @@
|
||||
"request": "2.88.0",
|
||||
"semver": "5.5.1",
|
||||
"sentiment": "2.1.0",
|
||||
"uglify-js": "3.4.8",
|
||||
"uglify-js": "3.4.9",
|
||||
"when": "3.7.8",
|
||||
"ws": "1.1.5",
|
||||
"xml2js": "0.4.19"
|
||||
@@ -85,7 +86,7 @@
|
||||
"chromedriver": "^2.41.0",
|
||||
"grunt": "~1.0.3",
|
||||
"grunt-chmod": "~1.1.1",
|
||||
"grunt-cli": "~1.2.0",
|
||||
"grunt-cli": "~1.3.1",
|
||||
"grunt-concurrent": "~2.3.1",
|
||||
"grunt-contrib-clean": "~1.1.0",
|
||||
"grunt-contrib-compress": "~1.4.0",
|
||||
|
@@ -23,7 +23,7 @@ var i18n;
|
||||
|
||||
var settings;
|
||||
var disableNodePathScan = false;
|
||||
var iconFileExtensions = [".png", ".gif"];
|
||||
var iconFileExtensions = [".png", ".gif", ".svg"];
|
||||
|
||||
function init(runtime) {
|
||||
settings = runtime.settings;
|
||||
@@ -290,6 +290,33 @@ function getNodeFiles(disableNodePathScan) {
|
||||
|
||||
if (!disableNodePathScan) {
|
||||
var moduleFiles = scanTreeForNodesModules();
|
||||
|
||||
// Filter the module list to ignore global modules
|
||||
// that have also been installed locally - allowing the user to
|
||||
// update a module they may not otherwise be able to touch
|
||||
|
||||
moduleFiles.sort(function(A,B) {
|
||||
if (A.local && !B.local) {
|
||||
return -1
|
||||
} else if (!A.local && B.local) {
|
||||
return 1
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
var knownModules = {};
|
||||
moduleFiles = moduleFiles.filter(function(mod) {
|
||||
var result;
|
||||
if (!knownModules[mod.package.name]) {
|
||||
knownModules[mod.package.name] = true;
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
log.debug("Module: "+mod.package.name+" "+mod.package.version+(result?"":" *ignored due to local copy*"));
|
||||
log.debug(" "+mod.dir);
|
||||
return result;
|
||||
});
|
||||
|
||||
moduleFiles.forEach(function(moduleFile) {
|
||||
var nodeModuleFiles = getModuleNodeFiles(moduleFile);
|
||||
nodeList[moduleFile.package.name] = {
|
||||
|
@@ -24,7 +24,7 @@ function injectNode(id) {
|
||||
|
||||
util.inherits(injectNode, nodePage);
|
||||
|
||||
var payloadType = {
|
||||
var payloadTypeList = {
|
||||
"flow": 1,
|
||||
"global": 2,
|
||||
"str": 3,
|
||||
@@ -36,54 +36,43 @@ var payloadType = {
|
||||
"env": 9,
|
||||
};
|
||||
|
||||
var timeType = {
|
||||
var repeatTypeList = {
|
||||
"none": 1,
|
||||
"interval": 2,
|
||||
"intervalBetweenTimes": 3,
|
||||
"atASpecificTime": 4,
|
||||
};
|
||||
|
||||
var timeType = {
|
||||
"none": 1,
|
||||
"interval": 2,
|
||||
"intervalBetweenTimes": 3,
|
||||
"atASpecificTime": 4,
|
||||
};
|
||||
|
||||
var timeType = {
|
||||
"none": 1,
|
||||
"interval": 2,
|
||||
"intervalBetweenTimes": 3,
|
||||
"atASpecificTime": 4,
|
||||
};
|
||||
|
||||
injectNode.prototype.setPayload = function(type, value) {
|
||||
injectNode.prototype.setPayload = function(payloadType, payload) {
|
||||
// Open a payload type list.
|
||||
browser.clickWithWait('//*[contains(@class, "red-ui-typedInput-container")]');
|
||||
// Select a payload type.
|
||||
var payloadTypeXPath = '//*[@class="red-ui-typedInput-options"]/a[' + payloadType[type] + ']';
|
||||
var payloadTypeXPath = '//*[@class="red-ui-typedInput-options"]/a[' + payloadTypeList[payloadType] + ']';
|
||||
browser.clickWithWait(payloadTypeXPath);
|
||||
if (value) {
|
||||
if (payload) {
|
||||
// Input a value.
|
||||
browser.setValue('//*[@class="red-ui-typedInput-input"]/input', value);
|
||||
browser.setValue('//*[@class="red-ui-typedInput-input"]/input', payload);
|
||||
}
|
||||
}
|
||||
|
||||
injectNode.prototype.setTopic = function(value) {
|
||||
browser.setValue('#node-input-topic', value);
|
||||
injectNode.prototype.setTopic = function(topic) {
|
||||
browser.setValue('#node-input-topic', topic);
|
||||
}
|
||||
|
||||
injectNode.prototype.setOnce = function(value) {
|
||||
browser.clickWithWait('#node-input-once');
|
||||
injectNode.prototype.setOnce = function(once) {
|
||||
var isChecked = browser.isSelected('#node-input-once');
|
||||
if (isChecked !== once) {
|
||||
browser.clickWithWait('#node-input-once');
|
||||
}
|
||||
}
|
||||
|
||||
injectNode.prototype.setTimeType = function(type) {
|
||||
var timeTypeXPath = '//*[@id="inject-time-type-select"]/option[' + timeType[type] + ']';
|
||||
browser.clickWithWait(timeTypeXPath);
|
||||
injectNode.prototype.setRepeat = function(repeatType) {
|
||||
var repeatTypeXPath = '//*[@id="inject-time-type-select"]/option[' + repeatTypeList[repeatType] + ']';
|
||||
browser.clickWithWait(repeatTypeXPath);
|
||||
}
|
||||
|
||||
injectNode.prototype.setRepeat = function(sec) {
|
||||
browser.setValue('#inject-time-interval-count', sec);
|
||||
injectNode.prototype.setRepeatInterval = function(repeat) {
|
||||
browser.setValue('#inject-time-interval-count', repeat);
|
||||
}
|
||||
|
||||
module.exports = injectNode;
|
||||
|
@@ -24,22 +24,20 @@ function debugNode(id) {
|
||||
|
||||
util.inherits(debugNode, nodePage);
|
||||
|
||||
var target = {
|
||||
"msg": 1,
|
||||
"full": 2
|
||||
};
|
||||
|
||||
debugNode.prototype.setTarget = function(type, value) {
|
||||
debugNode.prototype.setOutput = function(complete) {
|
||||
// Open a payload type list.
|
||||
browser.clickWithWait('//*[contains(@class, "red-ui-typedInput-container")]/button');
|
||||
// Select a payload type.
|
||||
var xPath = '/html/body/div[11]/a[' + target[type] + ']';
|
||||
browser.clickWithWait(xPath);
|
||||
if (value) {
|
||||
if (complete !== 'true') {
|
||||
// Select the "msg" type.
|
||||
browser.clickWithWait('/html/body/div[11]/a[1]');
|
||||
// Input the path in msg.
|
||||
browser.clickWithWait('//*[contains(@class, "red-ui-typedInput-input")]/input');
|
||||
browser.keys(['Control', 'a', 'Control']);
|
||||
browser.keys(['Delete']);
|
||||
browser.setValue('//*[contains(@class, "red-ui-typedInput-input")]/input', value);
|
||||
browser.setValue('//*[contains(@class, "red-ui-typedInput-input")]/input', complete);
|
||||
} else {
|
||||
// Select the "complete msg object" type.
|
||||
browser.clickWithWait('/html/body/div[11]/a[2]');
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -24,12 +24,17 @@ function functionNode(id) {
|
||||
|
||||
util.inherits(functionNode, nodePage);
|
||||
|
||||
functionNode.prototype.setCode = function(value) {
|
||||
functionNode.prototype.setFunction = function(func) {
|
||||
browser.click('#node-input-func-editor');
|
||||
browser.keys(['Control', 'Home', 'Control']);
|
||||
for (var i=0; i<value.length; i++) {
|
||||
browser.keys([value.substr(i, 1)]);
|
||||
for (var i = 0; i < func.length; i++) {
|
||||
browser.keys([func.charAt(i)]);
|
||||
}
|
||||
// Delete the unnecessary code that ace editor does the autocompletion.
|
||||
browser.keys(['Control', 'Shift', 'End', 'Shift', 'Control']);
|
||||
browser.keys(['Delete']);
|
||||
// Need to wait until ace editor correctly checks the syntax.
|
||||
browser.pause(50);
|
||||
}
|
||||
|
||||
module.exports = functionNode;
|
||||
|
@@ -24,29 +24,20 @@ function templateNode(id) {
|
||||
|
||||
util.inherits(templateNode, nodePage);
|
||||
|
||||
var syntaxType = {
|
||||
"mustache": 1,
|
||||
"plain": 2
|
||||
};
|
||||
|
||||
templateNode.prototype.setSyntax = function(type) {
|
||||
// Open a method type list.
|
||||
browser.clickWithWait('#node-input-syntax');
|
||||
// Select a method type.
|
||||
var syntaxTypeXPath = '//*[@id="node-input-syntax"]/option[' + syntaxType[type] + ']';
|
||||
browser.clickWithWait(syntaxTypeXPath);
|
||||
templateNode.prototype.setSyntax = function(syntax) {
|
||||
browser.selectWithWait('#node-input-syntax', syntax);
|
||||
}
|
||||
|
||||
templateNode.prototype.setFormat = function(type) {
|
||||
browser.selectByValue('#node-input-format', type);
|
||||
templateNode.prototype.setFormat = function(format) {
|
||||
browser.selectWithWait('#node-input-format', format);
|
||||
}
|
||||
|
||||
templateNode.prototype.setTemplate = function(value) {
|
||||
templateNode.prototype.setTemplate = function(template) {
|
||||
browser.click('#node-input-template-editor');
|
||||
browser.keys(['Control', 'a', 'Control']); // call twice to release the keys.
|
||||
// Need to add a character one by one since some words such as 'Control' are treated as a special word.
|
||||
for (var i=0; i<value.length; i++) {
|
||||
browser.keys([value.charAt(i)]);
|
||||
for (var i = 0; i < template.length; i++) {
|
||||
browser.keys([template.charAt(i)]);
|
||||
}
|
||||
browser.keys(['Control', 'Shift', 'End', 'Shift', 'Control']);
|
||||
browser.keys(['Delete']);
|
||||
|
@@ -22,30 +22,14 @@ function httpinNode(id) {
|
||||
nodePage.call(this, id);
|
||||
}
|
||||
|
||||
function setMethod(type) {
|
||||
browser.selectByValue('#node-input-method', type);
|
||||
}
|
||||
|
||||
util.inherits(httpinNode, nodePage);
|
||||
|
||||
var methodType = {
|
||||
"get": 1,
|
||||
"post": 2,
|
||||
"put": 3,
|
||||
"delete": 4,
|
||||
"patch": 5,
|
||||
};
|
||||
|
||||
httpinNode.prototype.setMethod = function(type) {
|
||||
// Open a method type list.
|
||||
browser.clickWithWait('#node-input-method');
|
||||
// Select a method type.
|
||||
var methodTypeXPath = '//*[@id="node-input-method"]/option[' + methodType[type] + ']';
|
||||
browser.clickWithWait(methodTypeXPath);
|
||||
httpinNode.prototype.setMethod = function(method) {
|
||||
browser.selectWithWait('#node-input-method', method);
|
||||
}
|
||||
|
||||
httpinNode.prototype.setUrl = function(value) {
|
||||
browser.setValue('#node-input-url', value);
|
||||
httpinNode.prototype.setUrl = function(url) {
|
||||
browser.setValue('#node-input-url', url);
|
||||
}
|
||||
|
||||
module.exports = httpinNode;
|
||||
|
@@ -24,36 +24,16 @@ function httpRequestNode(id) {
|
||||
|
||||
util.inherits(httpRequestNode, nodePage);
|
||||
|
||||
var methodType = {
|
||||
"get": 1,
|
||||
"post": 2,
|
||||
"put": 3,
|
||||
"delete": 4,
|
||||
"setByMsgMethod": 5,
|
||||
};
|
||||
|
||||
var retType = {
|
||||
"txt": 1,
|
||||
"bin": 2,
|
||||
"obj": 3,
|
||||
};
|
||||
|
||||
httpRequestNode.prototype.setUrl = function(value) {
|
||||
browser.setValue('#node-input-url', value);
|
||||
httpRequestNode.prototype.setUrl = function(url) {
|
||||
browser.setValue('#node-input-url', url);
|
||||
}
|
||||
|
||||
httpRequestNode.prototype.setMethod = function(type) {
|
||||
// Open a method type list.
|
||||
browser.clickWithWait('#node-input-method');
|
||||
// Select a method type.
|
||||
var methodTypeXPath = '//*[@id="node-input-method"]/option[' + methodType[type] + ']';
|
||||
browser.clickWithWait(methodTypeXPath);
|
||||
httpRequestNode.prototype.setMethod = function(method) {
|
||||
browser.selectWithWait('#node-input-method', method);
|
||||
}
|
||||
|
||||
httpRequestNode.prototype.setRet = function(type) {
|
||||
browser.clickWithWait('#node-input-ret');
|
||||
var retTypeXPath = '//*[@id="node-input-ret"]/option[' + retType[type] + ']';
|
||||
browser.clickWithWait(retTypeXPath);
|
||||
httpRequestNode.prototype.setReturn = function(ret) {
|
||||
browser.selectWithWait('#node-input-ret', ret);
|
||||
}
|
||||
|
||||
module.exports = httpRequestNode;
|
||||
|
@@ -24,13 +24,6 @@ function changeNode(id) {
|
||||
|
||||
util.inherits(changeNode, nodePage);
|
||||
|
||||
var tType = {
|
||||
"set": 1,
|
||||
"change": 2,
|
||||
"delete": 3,
|
||||
"move": 4,
|
||||
};
|
||||
|
||||
var totType = {
|
||||
"msg": 1,
|
||||
"flow": 2,
|
||||
@@ -42,6 +35,7 @@ var totType = {
|
||||
"bin": 8,
|
||||
"date": 9,
|
||||
"jsonata": 10,
|
||||
"env": 11,
|
||||
};
|
||||
|
||||
var ptType = {
|
||||
@@ -50,8 +44,8 @@ var ptType = {
|
||||
"global": 3,
|
||||
};
|
||||
|
||||
function setT(rule, index) {
|
||||
browser.selectByValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/select', rule);
|
||||
function setT(t, index) {
|
||||
browser.selectWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/select', t);
|
||||
}
|
||||
|
||||
// It is better to create a function whose input value is the object type in the future,
|
||||
|
@@ -24,8 +24,8 @@ function rangeNode(id) {
|
||||
|
||||
util.inherits(rangeNode, nodePage);
|
||||
|
||||
rangeNode.prototype.setAction = function(value) {
|
||||
browser.selectByValue('#node-input-action', value);
|
||||
rangeNode.prototype.setAction = function(action) {
|
||||
browser.selectWithWait('#node-input-action', action);
|
||||
}
|
||||
|
||||
rangeNode.prototype.setRange = function(minin, maxin, minout, maxout) {
|
||||
|
@@ -24,8 +24,8 @@ function htmlNode(id) {
|
||||
|
||||
util.inherits(htmlNode, nodePage);
|
||||
|
||||
htmlNode.prototype.setTag = function(value) {
|
||||
browser.setValue('#node-input-tag', value);
|
||||
htmlNode.prototype.setSelector = function(tag) {
|
||||
browser.setValue('#node-input-tag', tag);
|
||||
}
|
||||
|
||||
module.exports = htmlNode;
|
||||
|
@@ -31,13 +31,13 @@ var formatType = {
|
||||
"stream": 4
|
||||
};
|
||||
|
||||
fileinNode.prototype.setFilename = function(value) {
|
||||
browser.setValue('#node-input-filename', value);
|
||||
fileinNode.prototype.setFilename = function(filename) {
|
||||
browser.setValue('#node-input-filename', filename);
|
||||
}
|
||||
|
||||
fileinNode.prototype.setFormat = function(type) {
|
||||
fileinNode.prototype.setOutput = function(format) {
|
||||
browser.clickWithWait('#node-input-format');
|
||||
var formatTypeXPath = '//*[@id="node-input-format"]/option[' + formatType[type] + ']';
|
||||
var formatTypeXPath = '//*[@id="node-input-format"]/option[' + formatType[format] + ']';
|
||||
browser.clickWithWait(formatTypeXPath);
|
||||
}
|
||||
|
||||
|
@@ -38,6 +38,12 @@ function init() {
|
||||
var ret = browser.getText(selector);
|
||||
return ret;
|
||||
}, false);
|
||||
|
||||
browser.addCommand("selectWithWait", function(selector, value) {
|
||||
browser.waitForVisible(selector, 5000);
|
||||
var ret = browser.selectByValue(selector, value);
|
||||
return ret;
|
||||
}, false);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@@ -19,8 +19,8 @@ var should = require("should");
|
||||
var fs = require('fs-extra');
|
||||
|
||||
var helper = require("../../editor_helper");
|
||||
var debugTab = require('../../pageobjects/workspace/debugTab_page');
|
||||
var workspace = require('../../pageobjects/workspace/workspace_page');
|
||||
var debugTab = require('../../pageobjects/editor/debugTab_page');
|
||||
var workspace = require('../../pageobjects/editor/workspace_page');
|
||||
|
||||
var nodeWidth = 200;
|
||||
|
@@ -17,8 +17,8 @@
|
||||
var should = require("should");
|
||||
|
||||
var helper = require("../../editor_helper");
|
||||
var debugTab = require('../../pageobjects/workspace/debugTab_page');
|
||||
var workspace = require('../../pageobjects/workspace/workspace_page');
|
||||
var debugTab = require('../../pageobjects/editor/debugTab_page');
|
||||
var workspace = require('../../pageobjects/editor/workspace_page');
|
||||
|
||||
var nodeWidth = 200;
|
||||
var nodeHeight = 100;
|
||||
@@ -65,7 +65,7 @@ describe('cookbook', function() {
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.setMethod("GET");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
@@ -105,7 +105,7 @@ describe('cookbook', function() {
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-query?name=Nick');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.setMethod("GET");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
@@ -145,7 +145,7 @@ describe('cookbook', function() {
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-param/Dave');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.setMethod("GET");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
@@ -185,12 +185,12 @@ describe('cookbook', function() {
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3, nodeHeight);
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("headers", "msg", "{\"user-agent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64)\"}", "json");
|
||||
changeNode.ruleSet("headers", "msg", '{"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}', "json");
|
||||
changeNode.clickOk();
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-headers');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.setMethod("GET");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
@@ -249,7 +249,7 @@ describe('cookbook', function() {
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2, nodeHeight * 2);
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.setMethod("GET");
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-data');
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
@@ -280,7 +280,7 @@ describe('cookbook', function() {
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("{ \"Hello\": \"World\" }");
|
||||
templateNode.setTemplate('{ "Hello": "World" }');
|
||||
templateNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
@@ -299,12 +299,12 @@ describe('cookbook', function() {
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2, nodeHeight);
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.setMethod("GET");
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-json');
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
debugNode.edit();
|
||||
debugNode.setTarget("msg", "headers");
|
||||
debugNode.setOutput("headers");
|
||||
debugNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
@@ -332,7 +332,7 @@ describe('cookbook', function() {
|
||||
|
||||
fileinNode.edit();
|
||||
fileinNode.setFilename("test/resources/file-in-node/test.txt");
|
||||
fileinNode.setFormat("");
|
||||
fileinNode.setOutput("");
|
||||
fileinNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
@@ -352,7 +352,7 @@ describe('cookbook', function() {
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-file');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.setMethod("GET");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
@@ -396,7 +396,7 @@ describe('cookbook', function() {
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-raw');
|
||||
httpRequestNode.setMethod("post");
|
||||
httpRequestNode.setMethod("POST");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
@@ -440,12 +440,12 @@ describe('cookbook', function() {
|
||||
injectNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("headers", "msg", "{\"content-type\":\"application/x-www-form-urlencoded\"}", "json");
|
||||
changeNode.ruleSet("headers", "msg", '{"content-type":"application/x-www-form-urlencoded"}', "json");
|
||||
changeNode.clickOk();
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-form');
|
||||
httpRequestNode.setMethod("post");
|
||||
httpRequestNode.setMethod("POST");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
@@ -486,16 +486,16 @@ describe('cookbook', function() {
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3, nodeHeight);
|
||||
|
||||
injectNode.edit()
|
||||
injectNode.setPayload("json", "{\"name\":\"Nick\"}");
|
||||
injectNode.setPayload("json", '{"name":"Nick"}');
|
||||
injectNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("headers", "msg", "{\"content-type\":\"application/json\"}", "json");
|
||||
changeNode.ruleSet("headers", "msg", '{"content-type":"application/json"}', "json");
|
||||
changeNode.clickOk();
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-json');
|
||||
httpRequestNode.setMethod("post");
|
||||
httpRequestNode.setMethod("POST");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
@@ -531,13 +531,13 @@ describe('cookbook', function() {
|
||||
httpinNodeFormat.clickOk();
|
||||
|
||||
functionNodeFormat.edit();
|
||||
functionNodeFormat.setCode("msg.payload = JSON.stringify(msg.req.cookies,null,4);");
|
||||
functionNodeFormat.setFunction("msg.payload = JSON.stringify(msg.req.cookies,null,4);\nreturn msg;");
|
||||
functionNodeFormat.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Cookies</h1>\n<p></p><a href=\"hello-cookie/add\">Add a cookie</a> • <a href=\"hello-cookie/clear\">Clear cookies</a></p>\n<pre>{{ payload }}</pre>\n</body>\n</html>");
|
||||
templateNode.setTemplate('<html>\n<head></head>\n<body>\n<h1>Cookies</h1>\n<p></p><a href="hello-cookie/add">Add a cookie</a> • <a href="hello-cookie/clear">Clear cookies</a></p>\n<pre>{{ payload }}</pre>\n</body>\n</html>');
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNodeFormat.connect(functionNodeFormat);
|
||||
@@ -550,7 +550,7 @@ describe('cookbook', function() {
|
||||
httpinNodeAdd.clickOk();
|
||||
|
||||
functionNodeAdd.edit();
|
||||
functionNodeAdd.setCode("msg.cookies = { };\n msg.cookies[\"demo-\"+(Math.floor(Math.random()*1000))] = Date.now();");
|
||||
functionNodeAdd.setFunction('msg.cookies = { };\n msg.cookies["demo-"+(Math.floor(Math.random()*1000))] = Date.now();\nreturn msg;');
|
||||
functionNodeAdd.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
@@ -571,7 +571,7 @@ describe('cookbook', function() {
|
||||
httpinNodeClear.clickOk();
|
||||
|
||||
functionNodeClear.edit();
|
||||
functionNodeClear.setCode("var cookieNames = Object.keys(msg.req.cookies).filter(function(cookieName) { return /^demo-/.test(cookieName);});\nmsg.cookies = {};\n\ncookieNames.forEach(function(cookieName) {\n msg.cookies[cookieName] = null;\n});\n\n");
|
||||
functionNodeClear.setFunction("var cookieNames = Object.keys(msg.req.cookies).filter(function(cookieName) { return /^demo-/.test(cookieName);});\nmsg.cookies = {};\n\ncookieNames.forEach(function(cookieName) {\n msg.cookies[cookieName] = null;\n});\nreturn msg;\n");
|
||||
functionNodeClear.clickOk();
|
||||
|
||||
httpinNodeClear.connect(functionNodeClear);
|
||||
|
@@ -19,8 +19,8 @@ var should = require("should");
|
||||
var fs = require('fs-extra');
|
||||
|
||||
var helper = require("../../editor_helper");
|
||||
var debugTab = require('../../pageobjects/workspace/debugTab_page');
|
||||
var workspace = require('../../pageobjects/workspace/workspace_page');
|
||||
var debugTab = require('../../pageobjects/editor/debugTab_page');
|
||||
var workspace = require('../../pageobjects/editor/workspace_page');
|
||||
var specUtil = require('../../pageobjects/util/spec_util_page');
|
||||
|
||||
var nodeWidth = 200;
|
||||
@@ -168,8 +168,8 @@ describe('cookbook', function() {
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2);
|
||||
|
||||
injectNode.edit();
|
||||
injectNode.setTimeType("interval");
|
||||
injectNode.setRepeat(1);
|
||||
injectNode.setRepeat("interval");
|
||||
injectNode.setRepeatInterval(1);
|
||||
injectNode.clickOk();
|
||||
injectNode.connect(debugNode);
|
||||
|
||||
@@ -196,12 +196,12 @@ describe('cookbook', function() {
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3);
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setMethod("get");
|
||||
httpRequetNode.setMethod("GET");
|
||||
httpRequetNode.setUrl(helper.url());
|
||||
httpRequetNode.clickOk();
|
||||
|
||||
htmlNode.edit();
|
||||
htmlNode.setTag("title");
|
||||
htmlNode.setSelector("title");
|
||||
htmlNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequetNode);
|
||||
@@ -336,14 +336,14 @@ describe('cookbook', function() {
|
||||
changeNodeSetPost.clickOk();
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setMethod("get");
|
||||
httpRequetNode.setMethod("GET");
|
||||
var url = helper.url() + httpNodeRoot + "/{{post}}";
|
||||
httpRequetNode.setUrl(url);
|
||||
httpRequetNode.setRet("obj");
|
||||
httpRequetNode.setReturn("obj");
|
||||
httpRequetNode.clickOk();
|
||||
|
||||
debugNode.edit();
|
||||
debugNode.setTarget("msg", "payload.title");
|
||||
debugNode.setOutput("payload.title");
|
||||
debugNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNodeSetPost);
|
||||
@@ -364,11 +364,11 @@ describe('cookbook', function() {
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("{\"title\": \"Hello\"}");
|
||||
templateNode.setTemplate('{"title": "Hello"}');
|
||||
templateNode.clickOk();
|
||||
|
||||
changeNodeSetHeader.edit();
|
||||
changeNodeSetHeader.ruleSet("headers", "msg", "{\"content-type\":\"application/json\"}", "json");
|
||||
changeNodeSetHeader.ruleSet("headers", "msg", '{"content-type":"application/json"}', "json");
|
||||
changeNodeSetHeader.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
@@ -389,9 +389,9 @@ describe('cookbook', function() {
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2);
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setMethod("get");
|
||||
httpRequetNode.setMethod("GET");
|
||||
httpRequetNode.setUrl(helper.url() + "/settings");
|
||||
httpRequetNode.setRet("bin");
|
||||
httpRequetNode.setReturn("bin");
|
||||
httpRequetNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequetNode);
|
||||
@@ -413,11 +413,11 @@ describe('cookbook', function() {
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3);
|
||||
|
||||
functionNode.edit();
|
||||
functionNode.setCode("msg.payload = \"data to post\";");
|
||||
functionNode.setFunction('msg.payload = "data to post";\nreturn msg;');
|
||||
functionNode.clickOk();
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setMethod("post");
|
||||
httpRequetNode.setMethod("POST");
|
||||
var url = helper.url() + httpNodeRoot + "/set-header";
|
||||
httpRequetNode.setUrl(url);
|
||||
httpRequetNode.clickOk();
|
||||
|
@@ -1216,7 +1216,7 @@ describe('function node', function() {
|
||||
msg.should.have.property('payload', n1.id);
|
||||
done();
|
||||
});
|
||||
n1.receive({payload:"foo",topicb: "bar"});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1230,7 +1230,7 @@ describe('function node', function() {
|
||||
msg.should.have.property('payload', n1.name);
|
||||
done();
|
||||
});
|
||||
n1.receive({payload:"foo",topicb: "bar"});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -15,7 +15,8 @@
|
||||
**/
|
||||
|
||||
var should = require("should");
|
||||
var rpi = require("../../../../nodes/core/hardware/36-rpi-gpio.js");
|
||||
var rpiNode = require("../../../../nodes/core/hardware/36-rpi-gpio.js");
|
||||
var statusNode = require("../../../../nodes/core/core/25-status.js");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
var fs = require("fs");
|
||||
|
||||
@@ -50,7 +51,7 @@ describe('RPI GPIO Node', function() {
|
||||
|
||||
it('should load Input node', function(done) {
|
||||
var flow = [{id:"n1", type:"rpi-gpio in", name:"rpi-gpio in" }];
|
||||
helper.load(rpi, flow, function() {
|
||||
helper.load(rpiNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
n1.should.have.property('name', 'rpi-gpio in');
|
||||
try {
|
||||
@@ -69,7 +70,7 @@ describe('RPI GPIO Node', function() {
|
||||
|
||||
it('should load Output node', function(done) {
|
||||
var flow = [{id:"n1", type:"rpi-gpio out", name:"rpi-gpio out" }];
|
||||
helper.load(rpi, flow, function() {
|
||||
helper.load(rpiNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
n1.should.have.property('name', 'rpi-gpio out');
|
||||
try {
|
||||
@@ -86,4 +87,62 @@ describe('RPI GPIO Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should read a dummy value high (not on Pi)', function(done) {
|
||||
var flow = [{id:"n1", type:"rpi-gpio in", pin:"7", intype:"up", debounce:"25", read:true, wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(rpiNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'pi/7');
|
||||
msg.should.have.property('payload', 1);
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should read a dummy value low (not on Pi)', function(done) {
|
||||
var flow = [{id:"n1", type:"rpi-gpio in", pin:"11", intype:"down", debounce:"25", read:true, wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(rpiNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'pi/11');
|
||||
msg.should.have.property('payload', 0);
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able preset out to a dummy value (not on Pi)', function(done) {
|
||||
var flow = [{id:"n1", type:"rpi-gpio out", pin:"7", out:"out", level:"0", set:true, freq:"", wires:[], z:"1"},
|
||||
{id:"n2", type:"status", scope:null, wires:[["n3"]], z:"1"},
|
||||
{id:"n3", type:"helper", z:"1"}];
|
||||
helper.load([rpiNode,statusNode], flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var n3 = helper.getNode("n3");
|
||||
n3.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('status');
|
||||
msg.status.should.have.property('text', "rpi-gpio.status.na");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"1"});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -603,14 +603,14 @@ describe('JOIN node', function() {
|
||||
});
|
||||
|
||||
it('should accumulate a merged object', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"merged",mode:"custom",accumulate:true, count:1},
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"merged",mode:"custom",accumulate:true, count:3},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var c = 0;
|
||||
n2.on("input", function(msg) {
|
||||
if (c === 5) {
|
||||
if (c === 3) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.have.property("a",3);
|
||||
@@ -632,14 +632,14 @@ describe('JOIN node', function() {
|
||||
});
|
||||
|
||||
it('should be able to reset an accumulation', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"merged",accumulate:true,mode:"custom", count:1},
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], build:"merged",accumulate:true,mode:"custom", count:3},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var c = 0;
|
||||
n2.on("input", function(msg) {
|
||||
if (c === 3) {
|
||||
if (c === 1) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.have.property("a",1);
|
||||
@@ -649,11 +649,20 @@ describe('JOIN node', function() {
|
||||
}
|
||||
catch(e) { done(e) }
|
||||
}
|
||||
if (c === 5) {
|
||||
if (c === 2) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.have.property("b",2);
|
||||
msg.payload.should.have.property("c",1);
|
||||
msg.payload.should.have.property("e",2);
|
||||
msg.payload.should.have.property("f",1);
|
||||
}
|
||||
catch(e) { done(e) }
|
||||
}
|
||||
if (c === 3) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.have.property("g",2);
|
||||
msg.payload.should.have.property("h",1);
|
||||
msg.payload.should.have.property("i",3);
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e) }
|
||||
@@ -664,8 +673,11 @@ describe('JOIN node', function() {
|
||||
n1.receive({payload:{b:2}, topic:"b"});
|
||||
n1.receive({payload:{c:3}, topic:"c"});
|
||||
n1.receive({payload:{d:4}, topic:"d", complete:true});
|
||||
n1.receive({payload:{b:2}, topic:"e"});
|
||||
n1.receive({payload:{c:1}, topic:"f"});
|
||||
n1.receive({payload:{e:2}, topic:"e"});
|
||||
n1.receive({payload:{f:1}, topic:"f", complete:true});
|
||||
n1.receive({payload:{g:2}, topic:"g"});
|
||||
n1.receive({payload:{h:1}, topic:"h"});
|
||||
n1.receive({payload:{i:3}, topic:"i"});
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -66,13 +66,25 @@ describe('SORT node', function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property(target);
|
||||
var data = msg[target];
|
||||
data.length.should.equal(data_out.length);
|
||||
for(var i = 0; i < data_out.length; i++) {
|
||||
data[i].should.equal(data_out[i]);
|
||||
try {
|
||||
msg.should.have.property(target);
|
||||
var data = msg[target];
|
||||
data.length.should.equal(data_out.length);
|
||||
for(var i = 0; i < data_out.length; i++) {
|
||||
var data0 = data[i];
|
||||
var data1 = data_out[i];
|
||||
if (typeof data0 === "object") {
|
||||
data0.should.deepEqual(data1);
|
||||
}
|
||||
else {
|
||||
data0.should.equal(data1);
|
||||
}
|
||||
}
|
||||
done();
|
||||
}
|
||||
catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
done();
|
||||
});
|
||||
var msg = {};
|
||||
msg[target] = data_in;
|
||||
@@ -93,6 +105,34 @@ describe('SORT node', function() {
|
||||
}
|
||||
|
||||
function check_sort1(flow, key, key_type, data_in, data_out, done) {
|
||||
function equals(v0, v1) {
|
||||
var k0 = Object.keys(v0);
|
||||
var k1 = Object.keys(v1);
|
||||
|
||||
if (k0.length === k1.length) {
|
||||
for (var i = 0; i < k0.length; i++) {
|
||||
var k = k0[i];
|
||||
if (!v1.hasOwnProperty(k) ||
|
||||
(v0[k] !== v1[k])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function indexOf(a, v) {
|
||||
for(var i = 0; i < a.length; i++) {
|
||||
var av = a[i];
|
||||
if ((typeof v === 'object') && equals(v, av)) {
|
||||
return i;
|
||||
}
|
||||
else if (v === av) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
var sort = flow[0];
|
||||
var prop = (key_type === "msg") ? key : "payload";
|
||||
sort.targetType = "seq";
|
||||
@@ -107,7 +147,7 @@ describe('SORT node', function() {
|
||||
msg.should.have.property("parts");
|
||||
msg.parts.should.have.property("count", data_out.length);
|
||||
var data = msg[prop];
|
||||
var index = data_out.indexOf(data);
|
||||
var index = indexOf(data_out, data);
|
||||
msg.parts.should.have.property("index", index);
|
||||
count++;
|
||||
if (count === data_out.length) {
|
||||
@@ -136,7 +176,6 @@ describe('SORT node', function() {
|
||||
check_sort1(flow, exp, "jsonata", data_in, data_out, done);
|
||||
}
|
||||
|
||||
|
||||
(function() {
|
||||
var flow = [{id:"n1", type:"sort", order:"ascending", as_num:false, wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
@@ -239,6 +278,19 @@ describe('SORT node', function() {
|
||||
});
|
||||
})();
|
||||
|
||||
(function() {
|
||||
var flow = [{id:"n1", type:"sort", order:"ascending", as_num:true, wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
var conv = function(x) {
|
||||
return x.map(function(v) { return { val:v }; });
|
||||
};
|
||||
var data_in = conv([ "200", "4", "30", "1000" ]);
|
||||
var data_out = conv([ "4", "30", "200", "1000" ]);
|
||||
it('should sort payload of objects', function(done) {
|
||||
check_sort0C(flow, "val", data_in, data_out, done);
|
||||
});
|
||||
})();
|
||||
|
||||
it('should sort payload by context (exp, not number, ascending)', function(done) {
|
||||
var flow = [{id:"n1", type:"sort", target:"data", targetType:"msg", msgKey:"$flowContext($)", msgKeyType:"jsonata", order:"ascending", as_num:false, wires:[["n2"]],z:"flow"},
|
||||
{id:"n2", type:"helper",z:"flow"},
|
||||
@@ -268,7 +320,7 @@ describe('SORT node', function() {
|
||||
});
|
||||
|
||||
it('should sort message group by context (exp, not number, ascending)', function(done) {
|
||||
var flow = [{id:"n1", type:"sort", target:"data", targetType:"msg", msgKey:"$globalContext(payload)", msgKeyType:"jsonata", order:"ascending", as_num:false, wires:[["n2"]],z:"flow"},
|
||||
var flow = [{id:"n1", type:"sort", target:"data", targetType:"seq", seqKey:"$globalContext(payload)", seqKeyType:"jsonata", order:"ascending", as_num:false, wires:[["n2"]],z:"flow"},
|
||||
{id:"n2", type:"helper",z:"flow"},
|
||||
{id:"flow", type:"tab"}];
|
||||
var data_in = [ "first", "second", "third", "fourth" ];
|
||||
@@ -282,15 +334,20 @@ describe('SORT node', function() {
|
||||
n1.context()["global"].set("third","3");
|
||||
n1.context()["global"].set("fourth","2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property("payload");
|
||||
msg.should.have.property("parts");
|
||||
msg.parts.should.have.property("count", data_out.length);
|
||||
var data = msg["payload"];
|
||||
var index = data_out.indexOf(data);
|
||||
msg.parts.should.have.property("index", index);
|
||||
count++;
|
||||
if (count === data_out.length) {
|
||||
done();
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.should.have.property("parts");
|
||||
msg.parts.should.have.property("count", data_out.length);
|
||||
var data = msg["payload"];
|
||||
var index = data_out.indexOf(data);
|
||||
msg.parts.should.have.property("index", index);
|
||||
count++;
|
||||
if (count === data_out.length) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
var len = data_in.length;
|
||||
@@ -332,7 +389,7 @@ describe('SORT node', function() {
|
||||
});
|
||||
|
||||
it('should sort message group by persistable context (exp, not number, descending)', function(done) {
|
||||
var flow = [{id:"n1", type:"sort", target:"data", targetType:"msg", msgKey:"$flowContext(payload,\"memory\")", msgKeyType:"jsonata", order:"descending", as_num:false, wires:[["n2"]],z:"flow"},
|
||||
var flow = [{id:"n1", type:"sort", target:"data", targetType:"seq", seqKey:"$flowContext(payload,\"memory\")", seqKeyType:"jsonata", order:"descending", as_num:false, wires:[["n2"]],z:"flow"},
|
||||
{id:"n2", type:"helper",z:"flow"},
|
||||
{id:"flow", type:"tab"}];
|
||||
var data_in = [ "first", "second", "third", "fourth" ];
|
||||
|
@@ -265,6 +265,23 @@ describe('JSON node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass an object if provided a valid object and schema and action is object', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",action:"obj",wires:[["jn2"]]},
|
||||
{id:"jn2", type:"helper"}];
|
||||
helper.load(jsonNode, flow, function() {
|
||||
var jn1 = helper.getNode("jn1");
|
||||
var jn2 = helper.getNode("jn2");
|
||||
jn2.on("input", function(msg) {
|
||||
should.equal(msg.payload.number, 3);
|
||||
should.equal(msg.payload.string, "allo");
|
||||
done();
|
||||
});
|
||||
var obj = {"number": 3, "string": "allo"};
|
||||
var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}};
|
||||
jn1.receive({payload:obj, schema:schema});
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass a string if provided a valid object and schema', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
||||
{id:"jn2", type:"helper"}];
|
||||
@@ -281,6 +298,22 @@ describe('JSON node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass a string if provided a valid JSON string and schema and action is string', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",action:"str",wires:[["jn2"]]},
|
||||
{id:"jn2", type:"helper"}];
|
||||
helper.load(jsonNode, flow, function() {
|
||||
var jn1 = helper.getNode("jn1");
|
||||
var jn2 = helper.getNode("jn2");
|
||||
jn2.on("input", function(msg) {
|
||||
should.equal(msg.payload, '{"number":3,"string":"allo"}');
|
||||
done();
|
||||
});
|
||||
var jsonString = '{"number":3,"string":"allo"}';
|
||||
var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}};
|
||||
jn1.receive({payload:jsonString, schema:schema});
|
||||
});
|
||||
});
|
||||
|
||||
it('should log an error if passed an invalid object and valid schema', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
||||
{id:"jn2", type:"helper"}];
|
||||
@@ -305,6 +338,78 @@ describe('JSON node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should log an error if passed an invalid object and valid schema and action is object', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",action:"obj",wires:[["jn2"]]},
|
||||
{id:"jn2", type:"helper"}];
|
||||
helper.load(jsonNode, flow, function() {
|
||||
try {
|
||||
var jn1 = helper.getNode("jn1");
|
||||
var jn2 = helper.getNode("jn2");
|
||||
var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}};
|
||||
var obj = {"number": "foo", "string": 3};
|
||||
jn1.receive({payload:obj, schema:schema});
|
||||
var logEvents = helper.log().args.filter(function(evt) {
|
||||
return evt[0].type == "json";
|
||||
});
|
||||
logEvents.should.have.length(1);
|
||||
logEvents[0][0].should.have.a.property('msg');
|
||||
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
|
||||
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should log an error if passed an invalid JSON string and valid schema', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
||||
{id:"jn2", type:"helper"}];
|
||||
helper.load(jsonNode, flow, function() {
|
||||
try {
|
||||
var jn1 = helper.getNode("jn1");
|
||||
var jn2 = helper.getNode("jn2");
|
||||
var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}};
|
||||
var jsonString = '{"number":"Hello","string":3}';
|
||||
jn1.receive({payload:jsonString, schema:schema});
|
||||
var logEvents = helper.log().args.filter(function(evt) {
|
||||
return evt[0].type == "json";
|
||||
});
|
||||
logEvents.should.have.length(1);
|
||||
logEvents[0][0].should.have.a.property('msg');
|
||||
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
|
||||
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should log an error if passed an invalid JSON string and valid schema and action is string', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",action:"str",wires:[["jn2"]]},
|
||||
{id:"jn2", type:"helper"}];
|
||||
helper.load(jsonNode, flow, function() {
|
||||
try {
|
||||
var jn1 = helper.getNode("jn1");
|
||||
var jn2 = helper.getNode("jn2");
|
||||
var schema = {title: "testSchema", type: "object", properties: {number: {type: "number"}, string: {type: "string" }}};
|
||||
var jsonString = '{"number":"Hello","string":3}';
|
||||
jn1.receive({payload:jsonString, schema:schema});
|
||||
var logEvents = helper.log().args.filter(function(evt) {
|
||||
return evt[0].type == "json";
|
||||
});
|
||||
logEvents.should.have.length(1);
|
||||
logEvents[0][0].should.have.a.property('msg');
|
||||
logEvents[0][0].msg.should.equal("json.errors.schema-error: data.number should be number, data.string should be string");
|
||||
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should log an error if passed a valid object and invalid schema', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",wires:[["jn2"]]},
|
||||
{id:"jn2", type:"helper"}];
|
||||
|
@@ -128,7 +128,7 @@ describe("red/nodes/registry/localfilesystem",function() {
|
||||
}
|
||||
return _join.apply(null,arguments);
|
||||
}));
|
||||
localfilesystem.init({i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{coreNodesDir:moduleDir}});
|
||||
localfilesystem.init({log:{debug:function(){}},i18n:{registerMessageCatalog:function(){}},events:{emit:function(){}},settings:{coreNodesDir:moduleDir}});
|
||||
var nodeList = localfilesystem.getNodeFiles();
|
||||
nodeList.should.have.a.property("node-red");
|
||||
var nm = nodeList['node-red'];
|
||||
|
Reference in New Issue
Block a user