mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge branch 'master' into runtime-api
This commit is contained in:
@@ -27,12 +27,34 @@ util.inherits(injectNode, nodePage);
|
||||
var payloadType = {
|
||||
"flow": 1,
|
||||
"global": 2,
|
||||
"string": 3,
|
||||
"str": 3,
|
||||
"num": 4,
|
||||
"bool": 5,
|
||||
"json": 6,
|
||||
"bin": 7,
|
||||
"date": 8,
|
||||
"env": 9,
|
||||
};
|
||||
|
||||
var timeType = {
|
||||
"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) {
|
||||
@@ -41,12 +63,27 @@ injectNode.prototype.setPayload = function(type, value) {
|
||||
// Select a payload type.
|
||||
var payloadTypeXPath = '//*[@class="red-ui-typedInput-options"]/a[' + payloadType[type] + ']';
|
||||
browser.clickWithWait(payloadTypeXPath);
|
||||
// Input a value.
|
||||
browser.setValue('#node-input-payload', value);
|
||||
if (value) {
|
||||
// Input a value.
|
||||
browser.setValue('//*[@class="red-ui-typedInput-input"]/input', value);
|
||||
}
|
||||
}
|
||||
|
||||
injectNode.prototype.setTopic = function(value) {
|
||||
browser.setValue('#node-input-topic', value);
|
||||
}
|
||||
|
||||
injectNode.prototype.setOnce = function(value) {
|
||||
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(sec) {
|
||||
browser.setValue('#inject-time-interval-count', sec);
|
||||
}
|
||||
|
||||
module.exports = injectNode;
|
||||
|
@@ -24,4 +24,23 @@ function debugNode(id) {
|
||||
|
||||
util.inherits(debugNode, nodePage);
|
||||
|
||||
var target = {
|
||||
"msg": 1,
|
||||
"full": 2
|
||||
};
|
||||
|
||||
debugNode.prototype.setTarget = function(type, value) {
|
||||
// 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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = debugNode;
|
||||
|
35
test/editor/pageobjects/nodes/core/core/80-function_page.js
Normal file
35
test/editor/pageobjects/nodes/core/core/80-function_page.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var util = require("util");
|
||||
|
||||
var nodePage = require("../../node_page");
|
||||
|
||||
function functionNode(id) {
|
||||
nodePage.call(this, id);
|
||||
}
|
||||
|
||||
util.inherits(functionNode, nodePage);
|
||||
|
||||
functionNode.prototype.setCode = function(value) {
|
||||
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)]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = functionNode;
|
55
test/editor/pageobjects/nodes/core/core/80-template_page.js
Normal file
55
test/editor/pageobjects/nodes/core/core/80-template_page.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var util = require("util");
|
||||
|
||||
var nodePage = require("../../node_page");
|
||||
|
||||
function templateNode(id) {
|
||||
nodePage.call(this, 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.setFormat = function(type) {
|
||||
browser.selectByValue('#node-input-format', type);
|
||||
}
|
||||
|
||||
templateNode.prototype.setTemplate = function(value) {
|
||||
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)]);
|
||||
}
|
||||
browser.keys(['Control', 'Shift', 'End', 'Shift', 'Control']);
|
||||
browser.keys(['Delete']);
|
||||
}
|
||||
|
||||
module.exports = templateNode;
|
51
test/editor/pageobjects/nodes/core/io/21-httpin_page.js
Normal file
51
test/editor/pageobjects/nodes/core/io/21-httpin_page.js
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var util = require("util");
|
||||
|
||||
var nodePage = require("../../node_page");
|
||||
|
||||
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.setUrl = function(value) {
|
||||
browser.setValue('#node-input-url', value);
|
||||
}
|
||||
|
||||
module.exports = httpinNode;
|
59
test/editor/pageobjects/nodes/core/io/21-httprequest_page.js
Normal file
59
test/editor/pageobjects/nodes/core/io/21-httprequest_page.js
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var util = require("util");
|
||||
|
||||
var nodePage = require("../../node_page");
|
||||
|
||||
function httpRequestNode(id) {
|
||||
nodePage.call(this, 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.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.setRet = function(type) {
|
||||
browser.clickWithWait('#node-input-ret');
|
||||
var retTypeXPath = '//*[@id="node-input-ret"]/option[' + retType[type] + ']';
|
||||
browser.clickWithWait(retTypeXPath);
|
||||
}
|
||||
|
||||
module.exports = httpRequestNode;
|
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var util = require("util");
|
||||
|
||||
var nodePage = require("../../node_page");
|
||||
|
||||
function httpResponseNode(id) {
|
||||
nodePage.call(this, id);
|
||||
}
|
||||
|
||||
util.inherits(httpResponseNode, nodePage);
|
||||
|
||||
module.exports = httpResponseNode;
|
@@ -24,14 +24,58 @@ function changeNode(id) {
|
||||
|
||||
util.inherits(changeNode, nodePage);
|
||||
|
||||
var tType = {
|
||||
"set": 1,
|
||||
"change": 2,
|
||||
"delete": 3,
|
||||
"move": 4,
|
||||
};
|
||||
|
||||
var totType = {
|
||||
"msg": 1,
|
||||
"flow": 2,
|
||||
"global": 3,
|
||||
"str": 4,
|
||||
"num": 5,
|
||||
"bool": 6,
|
||||
"json": 7,
|
||||
"bin": 8,
|
||||
"date": 9,
|
||||
"jsonata": 10,
|
||||
};
|
||||
|
||||
var ptType = {
|
||||
"msg": 1,
|
||||
"flow": 2,
|
||||
"global": 3,
|
||||
};
|
||||
|
||||
function setT(rule, index) {
|
||||
browser.selectByValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/select', rule);
|
||||
}
|
||||
|
||||
changeNode.prototype.ruleSet = function(to, index) {
|
||||
// It is better to create a function whose input value is the object type in the future,
|
||||
changeNode.prototype.ruleSet = function(p, pt, to, tot, index) {
|
||||
index = index ? index : 1;
|
||||
setT("set", index);
|
||||
browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[2]/div[2]/div/input', to);
|
||||
if (pt) {
|
||||
browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]');
|
||||
var num = 5 * index + 6;
|
||||
var ptXPath = '/html/body/div[' + num + ']/a[' + ptType[pt] + ']';
|
||||
browser.clickWithWait(ptXPath);
|
||||
}
|
||||
if (p) {
|
||||
browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p);
|
||||
}
|
||||
if (tot) {
|
||||
browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[2]/div[2]/button[1]');
|
||||
var num = 5 * index + 7;
|
||||
var totXPath = '/html/body/div[' + num + ']/a[' + totType[tot] + ']';
|
||||
browser.clickWithWait(totXPath);
|
||||
}
|
||||
if (to) {
|
||||
browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[2]/div[2]/div/input' , to);
|
||||
}
|
||||
}
|
||||
|
||||
changeNode.prototype.ruleDelete = function(index) {
|
||||
|
31
test/editor/pageobjects/nodes/core/parsers/70-HTML_page.js
Normal file
31
test/editor/pageobjects/nodes/core/parsers/70-HTML_page.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var util = require("util");
|
||||
|
||||
var nodePage = require("../../node_page");
|
||||
|
||||
function htmlNode(id) {
|
||||
nodePage.call(this, id);
|
||||
}
|
||||
|
||||
util.inherits(htmlNode, nodePage);
|
||||
|
||||
htmlNode.prototype.setTag = function(value) {
|
||||
browser.setValue('#node-input-tag', value);
|
||||
}
|
||||
|
||||
module.exports = htmlNode;
|
44
test/editor/pageobjects/nodes/core/storage/50-filein_page.js
Normal file
44
test/editor/pageobjects/nodes/core/storage/50-filein_page.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var util = require("util");
|
||||
|
||||
var nodePage = require("../../node_page");
|
||||
|
||||
function fileinNode(id) {
|
||||
nodePage.call(this, id);
|
||||
}
|
||||
|
||||
util.inherits(fileinNode, nodePage);
|
||||
|
||||
var formatType = {
|
||||
"utf8": 1,
|
||||
"lines": 2,
|
||||
"": 3, // a single Buffer object
|
||||
"stream": 4
|
||||
};
|
||||
|
||||
fileinNode.prototype.setFilename = function(value) {
|
||||
browser.setValue('#node-input-filename', value);
|
||||
}
|
||||
|
||||
fileinNode.prototype.setFormat = function(type) {
|
||||
browser.clickWithWait('#node-input-format');
|
||||
var formatTypeXPath = '//*[@id="node-input-format"]/option[' + formatType[type] + ']';
|
||||
browser.clickWithWait(formatTypeXPath);
|
||||
}
|
||||
|
||||
module.exports = fileinNode;
|
@@ -16,17 +16,33 @@
|
||||
|
||||
var injectNode = require('./core/core/20-inject_page');
|
||||
var debugNode = require('./core/core/58-debug_page');
|
||||
var templateNode = require('./core/core/80-template_page');
|
||||
var functionNode = require('./core/core/80-function_page');
|
||||
var httpinNode = require('./core/io/21-httpin_page');
|
||||
var httpResponseNode = require('./core/io/21-httpresponse_page');
|
||||
var changeNode = require('./core/logic/15-change_page');
|
||||
var rangeNode = require('./core/logic/16-range_page');
|
||||
var httpRequestNode = require('./core/io/21-httprequest_page');
|
||||
var htmlNode = require('./core/parsers/70-HTML_page');
|
||||
var fileinNode = require('./core/storage/50-filein_page');
|
||||
|
||||
|
||||
var nodeCatalog = {
|
||||
// input
|
||||
"inject": injectNode,
|
||||
"httpin": httpinNode,
|
||||
// output
|
||||
"debug": debugNode,
|
||||
"httpResponse": httpResponseNode,
|
||||
// function
|
||||
"function": functionNode,
|
||||
"template": templateNode,
|
||||
"change": changeNode,
|
||||
"range": rangeNode,
|
||||
"httpRequest": httpRequestNode,
|
||||
"html": htmlNode,
|
||||
// storage
|
||||
"filein": fileinNode,
|
||||
}
|
||||
|
||||
function create(type, id) {
|
||||
|
23
test/editor/pageobjects/util/spec_util_page.js
Normal file
23
test/editor/pageobjects/util/spec_util_page.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
function pause(msec) {
|
||||
browser.pause(msec);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
pause: pause,
|
||||
};
|
@@ -15,7 +15,7 @@
|
||||
**/
|
||||
|
||||
function open() {
|
||||
browser.clickWithWait('#red-ui-tab-debug');
|
||||
browser.clickWithWait('#red-ui-tab-debug-link-button');
|
||||
}
|
||||
|
||||
function getMessage(index) {
|
||||
|
@@ -17,11 +17,19 @@
|
||||
var idMap = {
|
||||
// input
|
||||
"inject": "#palette_node_inject",
|
||||
"httpin": "#palette_node_http_in",
|
||||
// output
|
||||
"debug": "#palette_node_debug",
|
||||
"httpResponse": "#palette_node_http_response",
|
||||
// function
|
||||
"function": "#palette_node_function",
|
||||
"template": "#palette_node_template",
|
||||
"change": "#palette_node_change",
|
||||
"range": "#palette_node_range",
|
||||
"httpRequest": "#palette_node_http_request",
|
||||
"html": "#palette_node_html",
|
||||
// storage
|
||||
"filein": "#palette_node_file_in",
|
||||
};
|
||||
|
||||
function getId(type) {
|
||||
|
@@ -36,6 +36,7 @@ function addNode(type, x, y) {
|
||||
}
|
||||
|
||||
function deleteAllNodes() {
|
||||
browser.click('.innerCanvas');
|
||||
browser.keys(['Control', 'a', 'a', 'Control']); // call twice to release the keys.
|
||||
browser.keys(['Delete']);
|
||||
}
|
||||
|
584
test/editor/specs/scenario/cookbook_endpoint_uispec.js
Normal file
584
test/editor/specs/scenario/cookbook_endpoint_uispec.js
Normal file
@@ -0,0 +1,584 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var should = require("should");
|
||||
|
||||
var helper = require("../../editor_helper");
|
||||
var debugTab = require('../../pageobjects/workspace/debugTab_page');
|
||||
var workspace = require('../../pageobjects/workspace/workspace_page');
|
||||
|
||||
var nodeWidth = 200;
|
||||
var nodeHeight = 100;
|
||||
var httpNodeRoot = "/api";
|
||||
|
||||
// https://cookbook.nodered.org/
|
||||
describe('cookbook', function() {
|
||||
beforeEach(function() {
|
||||
workspace.deleteAllNodes();
|
||||
});
|
||||
|
||||
before(function() {
|
||||
helper.startServer();
|
||||
});
|
||||
|
||||
after(function() {
|
||||
helper.stopServer();
|
||||
});
|
||||
|
||||
describe('HTTP endpoints', function () {
|
||||
it('create an HTTP endpoint', function () {
|
||||
var httpinNode = workspace.addNode("httpin");
|
||||
var templateNode = workspace.addNode("template", nodeWidth);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 2);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("get");
|
||||
httpinNode.setUrl("/hello");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello World!</h1>\n</body>\n</html>");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNode = workspace.addNode("inject", 0, nodeHeight);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth, nodeHeight);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2, nodeHeight);
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().indexOf('Hello World!').should.not.eql(-1);
|
||||
});
|
||||
|
||||
it('handle query parameters passed to an HTTP endpoint', function () {
|
||||
var httpinNode = workspace.addNode("httpin");
|
||||
var templateNode = workspace.addNode("template", nodeWidth);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 2);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("get");
|
||||
httpinNode.setUrl("/hello-query");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{req.query.name}}!</h1>\n</body>\n</html>");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNode = workspace.addNode("inject", 0, nodeHeight);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth, nodeHeight);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2, nodeHeight);
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-query?name=Nick');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1);
|
||||
});
|
||||
|
||||
it('handle url parameters in an HTTP endpoint', function () {
|
||||
var httpinNode = workspace.addNode("httpin");
|
||||
var templateNode = workspace.addNode("template", nodeWidth * 2);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 3);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("get");
|
||||
httpinNode.setUrl("/hello-param/:name");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{req.params.name}}!</h1>\n</body>\n</html>");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNode = workspace.addNode("inject", 0, nodeHeight);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth, nodeHeight);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2, nodeHeight);
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-param/Dave');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().indexOf('Hello Dave!').should.not.eql(-1);
|
||||
});
|
||||
|
||||
it('access HTTP request headers', function () {
|
||||
var httpinNode = workspace.addNode("httpin");
|
||||
var templateNode = workspace.addNode("template", nodeWidth * 1.5);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 2.5);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("get");
|
||||
httpinNode.setUrl("/hello-headers");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>User agent: {{req.headers.user-agent}}</h1>\n</body>\n</html>");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNode = workspace.addNode("inject", 0, nodeHeight);
|
||||
var changeNode = workspace.addNode("change", nodeWidth, nodeHeight);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth * 2, nodeHeight);
|
||||
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.clickOk();
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-headers');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
changeNode.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().indexOf('Mozilla').should.not.eql(-1);
|
||||
});
|
||||
|
||||
it('include data captured in another flow', function () {
|
||||
var injectNodeTimestamp = workspace.addNode("inject");
|
||||
var changeNodeStore = workspace.addNode("change", nodeWidth);
|
||||
|
||||
var httpinNode = workspace.addNode("httpin", 0, nodeHeight);
|
||||
var changeNodeCopy = workspace.addNode("change", nodeWidth * 2, nodeHeight);
|
||||
var templateNode = workspace.addNode("template", nodeWidth * 3, nodeHeight);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 4, nodeHeight);
|
||||
|
||||
injectNodeTimestamp.edit();
|
||||
injectNodeTimestamp.setPayload("date");
|
||||
injectNodeTimestamp.clickOk();
|
||||
|
||||
changeNodeStore.edit();
|
||||
changeNodeStore.ruleSet("timestamp", "flow", "payload", "msg");
|
||||
changeNodeStore.clickOk();
|
||||
|
||||
injectNodeTimestamp.connect(changeNodeStore);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("get");
|
||||
httpinNode.setUrl("/hello-data");
|
||||
httpinNode.clickOk();
|
||||
|
||||
changeNodeCopy.edit();
|
||||
changeNodeCopy.ruleSet("timestamp", "msg", "timestamp", "flow");
|
||||
changeNodeCopy.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Time: {{ timestamp }}</h1>\n</body>\n</html>");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(changeNodeCopy);
|
||||
changeNodeCopy.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNodeCheck = workspace.addNode("inject", 0, nodeHeight * 2);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth, nodeHeight * 2);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2, nodeHeight * 2);
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-data');
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNodeCheck.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNodeTimestamp.clickLeftButton();
|
||||
injectNodeCheck.clickLeftButton();
|
||||
var index = debugTab.getMessage().indexOf('Time: ') + 6;
|
||||
debugTab.getMessage().substring(index, index + 13).should.within(1500000000000, 3000000000000);
|
||||
});
|
||||
|
||||
it('serve JSON content', function () {
|
||||
var httpinNode = workspace.addNode("httpin");
|
||||
var templateNode = workspace.addNode("template", nodeWidth);
|
||||
var changeNode = workspace.addNode("change", nodeWidth * 2);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 3);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("get");
|
||||
httpinNode.setUrl("/hello-json");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("{ \"Hello\": \"World\" }");
|
||||
templateNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("headers", "msg", "{}", "json", "1");
|
||||
changeNode.addRule();
|
||||
changeNode.ruleSet("headers.content-type", "msg", "application/json", "str", "2");
|
||||
changeNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(changeNode);
|
||||
changeNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNode = workspace.addNode("inject", 0, nodeHeight);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth, nodeHeight);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2, nodeHeight);
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-json');
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
debugNode.edit();
|
||||
debugNode.setTarget("msg", "headers");
|
||||
debugNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
var message = debugTab.getMessage();
|
||||
message[1].indexOf('application/json').should.not.eql(-1);
|
||||
});
|
||||
|
||||
it('serve a local file', function () {
|
||||
var httpinNode = workspace.addNode("httpin");
|
||||
var fileinNode = workspace.addNode("filein", nodeWidth);
|
||||
var changeNode = workspace.addNode("change", nodeWidth * 2, nodeHeight);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 3.5, nodeHeight);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("get");
|
||||
httpinNode.setUrl("/hello-file");
|
||||
httpinNode.clickOk();
|
||||
|
||||
fileinNode.edit();
|
||||
fileinNode.setFilename("test/resources/file-in-node/test.txt");
|
||||
fileinNode.setFormat("");
|
||||
fileinNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("headers", "msg", "{}", "json");
|
||||
changeNode.addRule();
|
||||
changeNode.ruleSet("headers.content-type", "msg", "text/plain", "str", "2");
|
||||
changeNode.clickOk();
|
||||
|
||||
httpinNode.connect(fileinNode);
|
||||
fileinNode.connect(changeNode);
|
||||
changeNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNode = workspace.addNode("inject", 0, nodeHeight * 2);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth, nodeHeight * 2);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2, nodeHeight * 2);
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-file');
|
||||
httpRequestNode.setMethod("get");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().indexOf('Text file').should.not.eql(-1);
|
||||
});
|
||||
|
||||
it('post raw data to a flow', function() {
|
||||
var httpinNode = workspace.addNode("httpin");
|
||||
var templateNode = workspace.addNode("template", nodeWidth * 2);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 3);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("post");
|
||||
httpinNode.setUrl("/hello-raw");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{ payload }}!</h1>\n</body>\n</html>");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNode = workspace.addNode("inject", 0, nodeHeight);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth, nodeHeight);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2, nodeHeight);
|
||||
|
||||
injectNode.edit()
|
||||
injectNode.setPayload("str", "Nick");
|
||||
injectNode.clickOk();
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-raw');
|
||||
httpRequestNode.setMethod("post");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1);
|
||||
});
|
||||
|
||||
it('post form data to a flow', function () {
|
||||
var httpinNode = workspace.addNode("httpin");
|
||||
var templateNode = workspace.addNode("template", nodeWidth * 1.5);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 2.5);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("post");
|
||||
httpinNode.setUrl("/hello-form");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{ payload.name }}!</h1>\n</body>\n</html>");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNode = workspace.addNode("inject", 0, nodeHeight);
|
||||
var changeNode = workspace.addNode("change", nodeWidth, nodeHeight);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth * 2, nodeHeight);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3, nodeHeight);
|
||||
|
||||
injectNode.edit()
|
||||
injectNode.setPayload("str", "name=Nick");
|
||||
injectNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
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.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
changeNode.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1);
|
||||
});
|
||||
|
||||
it('post JSON data to a flow', function() {
|
||||
var httpinNode = workspace.addNode("httpin");
|
||||
var templateNode = workspace.addNode("template", nodeWidth * 2);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 3);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("post");
|
||||
httpinNode.setUrl("/hello-json");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("<html>\n<head></head>\n<body>\n<h1>Hello {{ payload.name }}!</h1>\n</body>\n</html>");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var injectNode = workspace.addNode("inject", 0, nodeHeight);
|
||||
var changeNode = workspace.addNode("change", nodeWidth, nodeHeight);
|
||||
var httpRequestNode = workspace.addNode("httpRequest", nodeWidth * 2, nodeHeight);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3, nodeHeight);
|
||||
|
||||
injectNode.edit()
|
||||
injectNode.setPayload("json", "{\"name\":\"Nick\"}");
|
||||
injectNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("headers", "msg", "{\"content-type\":\"application/json\"}", "json");
|
||||
changeNode.clickOk();
|
||||
|
||||
httpRequestNode.edit();
|
||||
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/hello-json');
|
||||
httpRequestNode.setMethod("post");
|
||||
httpRequestNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
changeNode.connect(httpRequestNode);
|
||||
httpRequestNode.connect(debugNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1);
|
||||
});
|
||||
|
||||
it('work with cookies', function () {
|
||||
this.timeout(60000);
|
||||
|
||||
var httpinNodeFormat = workspace.addNode("httpin");
|
||||
var functionNodeFormat = workspace.addNode("function", nodeWidth * 1.5);
|
||||
var templateNode = workspace.addNode("template", nodeWidth * 2.5);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 3.5);
|
||||
|
||||
var httpinNodeAdd = workspace.addNode("httpin", 0, nodeHeight);
|
||||
var functionNodeAdd = workspace.addNode("function", nodeWidth * 1.5, nodeHeight);
|
||||
var changeNode = workspace.addNode("change", nodeWidth * 2.5, nodeHeight * 1.5);
|
||||
|
||||
var httpinNodeClear = workspace.addNode("httpin", 0, nodeHeight * 2);
|
||||
var functionNodeClear = workspace.addNode("function", nodeWidth * 1.5, nodeHeight * 2);
|
||||
|
||||
httpinNodeFormat.edit();
|
||||
httpinNodeFormat.setMethod("get");
|
||||
httpinNodeFormat.setUrl("/hello-cookie");
|
||||
httpinNodeFormat.clickOk();
|
||||
|
||||
functionNodeFormat.edit();
|
||||
functionNodeFormat.setCode("msg.payload = JSON.stringify(msg.req.cookies,null,4);");
|
||||
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.clickOk();
|
||||
|
||||
httpinNodeFormat.connect(functionNodeFormat);
|
||||
functionNodeFormat.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
|
||||
httpinNodeAdd.edit();
|
||||
httpinNodeAdd.setMethod("get");
|
||||
httpinNodeAdd.setUrl("/hello-cookie/add");
|
||||
httpinNodeAdd.clickOk();
|
||||
|
||||
functionNodeAdd.edit();
|
||||
functionNodeAdd.setCode("msg.cookies = { };\n msg.cookies[\"demo-\"+(Math.floor(Math.random()*1000))] = Date.now();");
|
||||
functionNodeAdd.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("statusCode", "msg", "302", "num");
|
||||
changeNode.addRule();
|
||||
changeNode.ruleSet("headers", "msg", "{}", "json", "2");
|
||||
changeNode.addRule();
|
||||
changeNode.ruleSet("headers.location", "msg", httpNodeRoot + "/hello-cookie", "str", "3");
|
||||
changeNode.clickOk();
|
||||
|
||||
httpinNodeAdd.connect(functionNodeAdd);
|
||||
functionNodeAdd.connect(changeNode);
|
||||
changeNode.connect(httpResponseNode);
|
||||
|
||||
httpinNodeClear.edit();
|
||||
httpinNodeClear.setMethod("get");
|
||||
httpinNodeClear.setUrl("/hello-cookie/clear");
|
||||
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.clickOk();
|
||||
|
||||
httpinNodeClear.connect(functionNodeClear);
|
||||
functionNodeClear.connect(changeNode);
|
||||
|
||||
workspace.deploy();
|
||||
// This case cannot be checked since http request node does not transfer cookies when redirected.
|
||||
});
|
||||
});
|
||||
});
|
@@ -21,8 +21,11 @@ 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 specUtil = require('../../pageobjects/util/spec_util_page');
|
||||
|
||||
var nodeWidth = 200;
|
||||
var nodeHeight = 100;
|
||||
var httpNodeRoot = "/api";
|
||||
|
||||
// https://cookbook.nodered.org/
|
||||
describe('cookbook', function() {
|
||||
@@ -45,7 +48,7 @@ describe('cookbook', function() {
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2);
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("Hello World!");
|
||||
changeNode.ruleSet("payload", "msg", "Hello World!");
|
||||
changeNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
@@ -56,7 +59,7 @@ describe('cookbook', function() {
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().should.be.equal('"Hello World!"');
|
||||
debugTab.getMessage().should.eql('"Hello World!"');
|
||||
});
|
||||
|
||||
it('delete a message property', function() {
|
||||
@@ -76,7 +79,7 @@ describe('cookbook', function() {
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().should.be.equal("undefined");
|
||||
debugTab.getMessage().should.eql("undefined");
|
||||
});
|
||||
|
||||
it('move a message property', function() {
|
||||
@@ -100,7 +103,7 @@ describe('cookbook', function() {
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().should.be.equal('"Hello"');
|
||||
debugTab.getMessage().should.eql('"Hello"');
|
||||
});
|
||||
|
||||
it('map a property between different numeric ranges', function() {
|
||||
@@ -135,11 +138,319 @@ describe('cookbook', function() {
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode1.clickLeftButton();
|
||||
debugTab.getMessage(1).should.be.equal('0');
|
||||
debugTab.getMessage(1).should.eql('0');
|
||||
injectNode2.clickLeftButton();
|
||||
debugTab.getMessage(2).should.be.equal('2.5024437927663734');
|
||||
debugTab.getMessage(2).should.eql('2.5024437927663734');
|
||||
injectNode3.clickLeftButton();
|
||||
debugTab.getMessage(3).should.be.equal('5');
|
||||
debugTab.getMessage(3).should.eql('5');
|
||||
});
|
||||
});
|
||||
|
||||
describe('flow control', function() {
|
||||
it('trigger a flow whenever Node-RED starts', function() {
|
||||
var injectNode = workspace.addNode("inject");
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2);
|
||||
|
||||
injectNode.edit();
|
||||
injectNode.setPayload("str", "Started!")
|
||||
injectNode.setOnce(true);
|
||||
injectNode.clickOk();
|
||||
injectNode.connect(debugNode);
|
||||
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
workspace.deploy();
|
||||
debugTab.getMessage().should.eql('"Started!"');
|
||||
});
|
||||
|
||||
it('trigger a flow at regular intervals', function() {
|
||||
var injectNode = workspace.addNode("inject");
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2);
|
||||
|
||||
injectNode.edit();
|
||||
injectNode.setTimeType("interval");
|
||||
injectNode.setRepeat(1);
|
||||
injectNode.clickOk();
|
||||
injectNode.connect(debugNode);
|
||||
|
||||
workspace.deploy();
|
||||
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
specUtil.pause(1000);
|
||||
var t1 = Number(debugTab.getMessage(1));
|
||||
t1.should.within(1500000000000, 3000000000000);
|
||||
specUtil.pause(1000);
|
||||
debugTab.getMessage(2).should.within(t1 + 1000, 3000000000000);
|
||||
});
|
||||
|
||||
// skip this case since it needs up to one minite.
|
||||
it.skip('trigger a flow at a specific time');
|
||||
});
|
||||
|
||||
describe('HTTP requests', function() {
|
||||
it('simple get request', function() {
|
||||
var injectNode = workspace.addNode("inject");
|
||||
var httpRequetNode = workspace.addNode("httpRequest", nodeWidth);
|
||||
var htmlNode = workspace.addNode("html", nodeWidth * 2);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3);
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setMethod("get");
|
||||
httpRequetNode.setUrl(helper.url());
|
||||
httpRequetNode.clickOk();
|
||||
|
||||
htmlNode.edit();
|
||||
htmlNode.setTag("title");
|
||||
htmlNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequetNode);
|
||||
httpRequetNode.connect(htmlNode);
|
||||
htmlNode.connect(debugNode);
|
||||
|
||||
workspace.deploy();
|
||||
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().should.eql('"Node-RED"');
|
||||
});
|
||||
|
||||
it('set the URL of a request', function() {
|
||||
var injectNode = workspace.addNode("inject");
|
||||
var changeNode = workspace.addNode("change", nodeWidth * 1.5);
|
||||
var httpRequetNode = workspace.addNode("httpRequest", nodeWidth * 2.5);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3.5);
|
||||
|
||||
injectNode.edit();
|
||||
injectNode.setPayload("str", helper.url());
|
||||
injectNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("url", "msg", "payload", "msg");
|
||||
changeNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
changeNode.connect(httpRequetNode);
|
||||
httpRequetNode.connect(debugNode);
|
||||
|
||||
workspace.deploy();
|
||||
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().should.containEql('<title>Node-RED</title>');
|
||||
});
|
||||
|
||||
it('set the URL of a request using a template', function() {
|
||||
var injectNode = workspace.addNode("inject");
|
||||
var changeNode = workspace.addNode("change", nodeWidth * 1.5);
|
||||
var httpRequetNode = workspace.addNode("httpRequest", nodeWidth * 2.5);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3.5);
|
||||
|
||||
injectNode.edit();
|
||||
injectNode.setPayload("str", 'settings');
|
||||
injectNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("query", "msg", "payload", "msg");
|
||||
changeNode.clickOk();
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setUrl(helper.url() + "/{{{query}}}");
|
||||
httpRequetNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
changeNode.connect(httpRequetNode);
|
||||
httpRequetNode.connect(debugNode);
|
||||
|
||||
workspace.deploy();
|
||||
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().should.containEql('httpNodeRoot');
|
||||
});
|
||||
|
||||
it('set the query string parameters', function() {
|
||||
var injectNode = workspace.addNode("inject");
|
||||
var changeNode = workspace.addNode("change", nodeWidth);
|
||||
var httpRequetNode = workspace.addNode("httpRequest", nodeWidth * 2);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3);
|
||||
|
||||
injectNode.edit();
|
||||
injectNode.setPayload("str", 'Nick');
|
||||
injectNode.clickOk();
|
||||
|
||||
changeNode.edit();
|
||||
changeNode.ruleSet("query", "msg", "payload", "msg");
|
||||
changeNode.clickOk();
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setUrl(helper.url() + httpNodeRoot + '/set-query?q={{{query}}}');
|
||||
httpRequetNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNode);
|
||||
changeNode.connect(httpRequetNode);
|
||||
httpRequetNode.connect(debugNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var httpinNode = workspace.addNode("httpin", 0, nodeHeight);
|
||||
var templateNode = workspace.addNode("template", nodeWidth, nodeHeight);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 2, nodeHeight);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("get");
|
||||
httpinNode.setUrl("/set-query");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("Hello {{req.query.q}}");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().should.eql('"Hello Nick"');
|
||||
});
|
||||
|
||||
it('get a parsed JSON response', function() {
|
||||
var injectNode = workspace.addNode("inject");
|
||||
var changeNodeSetPost = workspace.addNode("change", nodeWidth);
|
||||
var httpRequetNode = workspace.addNode("httpRequest", nodeWidth * 2);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3);
|
||||
|
||||
injectNode.edit();
|
||||
injectNode.setPayload("str", "json-response");
|
||||
injectNode.clickOk();
|
||||
|
||||
changeNodeSetPost.edit();
|
||||
changeNodeSetPost.ruleSet("post", "msg", "payload", "msg");
|
||||
changeNodeSetPost.clickOk();
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setMethod("get");
|
||||
var url = helper.url() + httpNodeRoot + "/{{post}}";
|
||||
httpRequetNode.setUrl(url);
|
||||
httpRequetNode.setRet("obj");
|
||||
httpRequetNode.clickOk();
|
||||
|
||||
debugNode.edit();
|
||||
debugNode.setTarget("msg", "payload.title");
|
||||
debugNode.clickOk();
|
||||
|
||||
injectNode.connect(changeNodeSetPost);
|
||||
changeNodeSetPost.connect(httpRequetNode);
|
||||
httpRequetNode.connect(debugNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var httpinNode = workspace.addNode("httpin", 0, nodeHeight);
|
||||
var templateNode = workspace.addNode("template", nodeWidth * 1.5, nodeHeight);
|
||||
var changeNodeSetHeader = workspace.addNode("change", nodeWidth * 2.5, nodeHeight);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 3.5, nodeHeight);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("get");
|
||||
httpinNode.setUrl("/json-response");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("{\"title\": \"Hello\"}");
|
||||
templateNode.clickOk();
|
||||
|
||||
changeNodeSetHeader.edit();
|
||||
changeNodeSetHeader.ruleSet("headers", "msg", "{\"content-type\":\"application/json\"}", "json");
|
||||
changeNodeSetHeader.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(changeNodeSetHeader);
|
||||
changeNodeSetHeader.connect(httpResponseNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().should.eql('"Hello"');
|
||||
});
|
||||
|
||||
it('get a binary response', function() {
|
||||
var injectNode = workspace.addNode("inject");
|
||||
var httpRequetNode = workspace.addNode("httpRequest", nodeWidth);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 2);
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setMethod("get");
|
||||
httpRequetNode.setUrl(helper.url() + "/settings");
|
||||
httpRequetNode.setRet("bin");
|
||||
httpRequetNode.clickOk();
|
||||
|
||||
injectNode.connect(httpRequetNode);
|
||||
httpRequetNode.connect(debugNode);
|
||||
|
||||
workspace.deploy();
|
||||
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
|
||||
debugTab.getMessage().should.eql(['123', '34', '104', '116', '116', '112', '78', '111', '100', '101']);
|
||||
});
|
||||
|
||||
it('set a request header', function() {
|
||||
var injectNode = workspace.addNode("inject");
|
||||
var functionNode = workspace.addNode("function", nodeWidth);
|
||||
var httpRequetNode = workspace.addNode("httpRequest", nodeWidth * 2);
|
||||
var debugNode = workspace.addNode("debug", nodeWidth * 3);
|
||||
|
||||
functionNode.edit();
|
||||
functionNode.setCode("msg.payload = \"data to post\";");
|
||||
functionNode.clickOk();
|
||||
|
||||
httpRequetNode.edit();
|
||||
httpRequetNode.setMethod("post");
|
||||
var url = helper.url() + httpNodeRoot + "/set-header";
|
||||
httpRequetNode.setUrl(url);
|
||||
httpRequetNode.clickOk();
|
||||
|
||||
injectNode.connect(functionNode);
|
||||
functionNode.connect(httpRequetNode);
|
||||
httpRequetNode.connect(debugNode);
|
||||
|
||||
// The code for confirmation starts from here.
|
||||
var httpinNode = workspace.addNode("httpin", 0, nodeHeight);
|
||||
var templateNode = workspace.addNode("template", nodeWidth * 1.5, nodeHeight);
|
||||
var httpResponseNode = workspace.addNode("httpResponse", nodeWidth * 2.5, nodeHeight);
|
||||
|
||||
httpinNode.edit();
|
||||
httpinNode.setMethod("post");
|
||||
httpinNode.setUrl("/set-header");
|
||||
httpinNode.clickOk();
|
||||
|
||||
templateNode.edit();
|
||||
templateNode.setSyntax("mustache");
|
||||
templateNode.setFormat("handlebars");
|
||||
templateNode.setTemplate("{{ payload }}");
|
||||
templateNode.clickOk();
|
||||
|
||||
httpinNode.connect(templateNode);
|
||||
templateNode.connect(httpResponseNode);
|
||||
// The code for confirmation ends here.
|
||||
|
||||
workspace.deploy();
|
||||
debugTab.open();
|
||||
debugTab.clearMessage();
|
||||
injectNode.clickLeftButton();
|
||||
debugTab.getMessage().should.eql('"data to post"');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -62,10 +62,11 @@ exports.config = {
|
||||
//
|
||||
browserName: 'chrome',
|
||||
chromeOptions: {
|
||||
// Runs tests without opening a broser.
|
||||
args: ['--headless', '--disable-gpu', 'window-size=1920,1080'],
|
||||
// Runs tests with opening a broser.
|
||||
// args: ['--disable-gpu'],
|
||||
args: process.env.NODE_RED_NON_HEADLESS
|
||||
// Runs tests with opening a browser.
|
||||
? ['--disable-gpu']
|
||||
// Runs tests without opening a browser.
|
||||
: ['--headless', '--disable-gpu', 'window-size=1920,1080']
|
||||
},
|
||||
}],
|
||||
//
|
||||
@@ -154,7 +155,7 @@ exports.config = {
|
||||
// Options to be passed to Mocha.
|
||||
// See the full list at http://mochajs.org/
|
||||
mochaOpts: {
|
||||
timeout: 20000,
|
||||
timeout: 60000,
|
||||
ui: 'bdd'
|
||||
},
|
||||
//
|
||||
|
@@ -16,22 +16,348 @@
|
||||
|
||||
var should = require("should");
|
||||
var injectNode = require("../../../../nodes/core/core/20-inject.js");
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
|
||||
describe('inject node', function() {
|
||||
|
||||
before(function(done) {
|
||||
beforeEach(function(done) {
|
||||
helper.startServer(done);
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
helper.stopServer(done);
|
||||
function initContext(done) {
|
||||
Context.init({
|
||||
contextStorage: {
|
||||
memory0: {
|
||||
module: "memory"
|
||||
},
|
||||
memory1: {
|
||||
module: "memory"
|
||||
}
|
||||
}
|
||||
});
|
||||
Context.load().then(function () {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function(done) {
|
||||
helper.unload().then(function () {
|
||||
return Context.clean({allNodes: {}});
|
||||
}).then(function () {
|
||||
return Context.close();
|
||||
}).then(function () {
|
||||
helper.stopServer(done);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
helper.unload();
|
||||
function basicTest(type, val, rval) {
|
||||
it('inject value ('+type+')', function (done) {
|
||||
var flow = [{id: "n1", type: "inject", topic: "t1", payload: val, payloadType: type, wires: [["n2"]], z: "flow"},
|
||||
{id: "n2", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic", "t1");
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
basicTest("num", 10);
|
||||
basicTest("str", "10");
|
||||
basicTest("bool", true);
|
||||
var val_json = '{ "x":"vx", "y":"vy", "z":"vz" }';
|
||||
basicTest("json", val_json, JSON.parse(val_json));
|
||||
var val_buf = "[1,2,3,4,5]";
|
||||
basicTest("bin", val_buf, Buffer.from(JSON.parse(val_buf)));
|
||||
|
||||
it('inject value of environment variable ', function (done) {
|
||||
var flow = [{id: "n1", type: "inject", topic: "t1", payload: "NR_TEST", payloadType: "env", wires: [["n2"]], z: "flow"},
|
||||
{id: "n2", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic", "t1");
|
||||
msg.should.have.property("payload", "foo");
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
process.env.NR_TEST = 'foo';
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value of flow context property', function (done) {
|
||||
var flow = [{id: "n1", type: "inject", topic: "t1", payload: "flowValue", payloadType: "flow", wires: [["n2"]], z: "flow"},
|
||||
{id: "n2", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic", "t1");
|
||||
msg.should.have.property("payload", "changeMe");
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.context().flow.set("flowValue", "changeMe");
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value of persistable flow context property', function (done) {
|
||||
var flow = [{id: "n1", type: "inject", topic: "t1", payload: "#:(memory0)::flowValue", payloadType: "flow", wires: [["n2"]], z: "flow"},
|
||||
{id: "n2", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic", "t1");
|
||||
msg.should.have.property("payload", "changeMe");
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.context().flow.set("flowValue", "changeMe", "memory0", function (err) {
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value of two persistable flow context property', function (done) {
|
||||
var flow = [{id: "n0", z: "flow", type: "inject", topic: "t0", payload: "#:(memory0)::val", payloadType: "flow", wires: [["n2"]]},
|
||||
{id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "flow", wires: [["n2"]]},
|
||||
{id: "n2", z: "flow", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n0 = helper.getNode("n0");
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic");
|
||||
if (msg.topic === "t0") {
|
||||
msg.should.have.property("payload", "foo");
|
||||
}
|
||||
else if (msg.topic === "t1") {
|
||||
msg.should.have.property("payload", "bar");
|
||||
}
|
||||
else {
|
||||
done(new Error("unexpected message"));
|
||||
}
|
||||
count++;
|
||||
if (count === 2) {
|
||||
done();
|
||||
}
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var global = n0.context().flow;
|
||||
global.set("val", "foo", "memory0", function (err) {
|
||||
global.set("val", "bar", "memory1", function (err) {
|
||||
n0.receive({});
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value of global context property', function (done) {
|
||||
var flow = [{id: "n1", type: "inject", topic: "t1", payload: "globalValue", payloadType: "global", wires: [["n2"]]},
|
||||
{id: "n2", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic", "t1");
|
||||
msg.should.have.property("payload", "changeMe");
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.context().global.set("globalValue", "changeMe");
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value of persistable global context property', function (done) {
|
||||
var flow = [{id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "global", wires: [["n2"]]},
|
||||
{id: "n2", z: "flow", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic", "t1");
|
||||
msg.should.have.property("payload", "foo");
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var global = n1.context().global;
|
||||
global.set("val", "foo", "memory1", function (err) {
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value of two persistable global context property', function (done) {
|
||||
var flow = [{id: "n0", z: "flow", type: "inject", topic: "t0", payload: "#:(memory0)::val", payloadType: "global", wires: [["n2"]]},
|
||||
{id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "global", wires: [["n2"]]},
|
||||
{id: "n2", z: "flow", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n0 = helper.getNode("n0");
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic");
|
||||
if (msg.topic === "t0") {
|
||||
msg.should.have.property("payload", "foo");
|
||||
}
|
||||
else if (msg.topic === "t1") {
|
||||
msg.should.have.property("payload", "bar");
|
||||
}
|
||||
else {
|
||||
done(new Error("unexpected message"));
|
||||
}
|
||||
count++;
|
||||
if (count === 2) {
|
||||
done();
|
||||
}
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var global = n0.context().global;
|
||||
global.set("val", "foo", "memory0", function (err) {
|
||||
global.set("val", "bar", "memory1", function (err) {
|
||||
n0.receive({});
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value of persistable flow & global context property', function (done) {
|
||||
var flow = [{id: "n0", z: "flow", type: "inject", topic: "t0", payload: "#:(memory0)::val", payloadType: "flow", wires: [["n2"]]},
|
||||
{id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "global", wires: [["n2"]]},
|
||||
{id: "n2", z: "flow", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n0 = helper.getNode("n0");
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic");
|
||||
if (msg.topic === "t0") {
|
||||
msg.should.have.property("payload", "foo");
|
||||
}
|
||||
else if (msg.topic === "t1") {
|
||||
msg.should.have.property("payload", "bar");
|
||||
}
|
||||
else {
|
||||
done(new Error("unexpected message"));
|
||||
}
|
||||
count++;
|
||||
if (count === 2) {
|
||||
done();
|
||||
}
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var context = n0.context();
|
||||
var flow = context.flow;
|
||||
var global = context.global;
|
||||
flow.set("val", "foo", "memory0", function (err) {
|
||||
global.set("val", "bar", "memory1", function (err) {
|
||||
n0.receive({});
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value of two persistable global context property', function (done) {
|
||||
var flow = [{id: "n0", z: "flow", type: "inject", topic: "t0", payload: "#:(memory0)::val", payloadType: "global", wires: [["n2"]]},
|
||||
{id: "n1", z: "flow", type: "inject", topic: "t1", payload: "#:(memory1)::val", payloadType: "global", wires: [["n2"]]},
|
||||
{id: "n2", z: "flow", type: "helper"}];
|
||||
helper.load(injectNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n0 = helper.getNode("n0");
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("topic");
|
||||
if (msg.topic === "t0") {
|
||||
msg.should.have.property("payload", "foo");
|
||||
}
|
||||
else if (msg.topic === "t1") {
|
||||
msg.should.have.property("payload", "bar");
|
||||
}
|
||||
else {
|
||||
done(new Error("unexpected message"));
|
||||
}
|
||||
count++;
|
||||
if (count === 2) {
|
||||
done();
|
||||
}
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var global = n0.context().global;
|
||||
global.set("val", "foo", "memory0", function (err) {
|
||||
global.set("val", "bar", "memory1", function (err) {
|
||||
n0.receive({});
|
||||
n1.receive({});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should inject once with default delay property', function(done) {
|
||||
helper.load(injectNode, [{id:"n1", type:"inject", topic: "t1",
|
||||
payload:"",payloadType:"date",
|
||||
|
@@ -411,7 +411,7 @@ describe('debug node', function() {
|
||||
data:{
|
||||
id:"n1",
|
||||
msg:JSON.stringify({
|
||||
__encoded__: true,
|
||||
__enc__: true,
|
||||
type: "array",
|
||||
data: Array(1000).fill("X"),
|
||||
length: 1001
|
||||
@@ -438,7 +438,7 @@ describe('debug node', function() {
|
||||
id:"n1",
|
||||
msg:JSON.stringify({
|
||||
foo:{
|
||||
__encoded__: true,
|
||||
__enc__: true,
|
||||
type: "array",
|
||||
data: Array(1000).fill("X"),
|
||||
length: 1001
|
||||
@@ -489,7 +489,7 @@ describe('debug node', function() {
|
||||
foo:{
|
||||
type: "Buffer",
|
||||
data: Array(1000).fill(88),
|
||||
__encoded__: true,
|
||||
__enc__: true,
|
||||
length: 1001
|
||||
}
|
||||
},null," "),
|
||||
|
@@ -1,21 +1,22 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var should = require("should");
|
||||
var functionNode = require("../../../../nodes/core/core/80-function.js");
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
|
||||
describe('function node', function() {
|
||||
@@ -28,10 +29,31 @@ describe('function node', function() {
|
||||
helper.stopServer(done);
|
||||
});
|
||||
|
||||
function initContext(done) {
|
||||
Context.init({
|
||||
contextStorage: {
|
||||
memory1: {
|
||||
module: "memory"
|
||||
},
|
||||
memory2: {
|
||||
module: "memory"
|
||||
}
|
||||
}
|
||||
});
|
||||
Context.load().then(function () {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
helper.unload();
|
||||
helper.unload().then(function () {
|
||||
return Context.clean({allNodes:{}});
|
||||
}).then(function () {
|
||||
return Context.close();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should be loaded', function(done) {
|
||||
var flow = [{id:"n1", type:"function", name: "function" }];
|
||||
helper.load(functionNode, flow, function() {
|
||||
@@ -43,7 +65,7 @@ describe('function node', function() {
|
||||
|
||||
it('should send returned message', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -58,7 +80,7 @@ describe('function node', function() {
|
||||
|
||||
it('should send returned message using send()', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.send(msg);"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -73,7 +95,7 @@ describe('function node', function() {
|
||||
|
||||
it('should pass through _topic', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -89,8 +111,8 @@ describe('function node', function() {
|
||||
|
||||
it('should send to multiple outputs', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"],["n3"]],
|
||||
func:"return [{payload: '1'},{payload: '2'}];"},
|
||||
{id:"n2", type:"helper"}, {id:"n3", type:"helper"} ];
|
||||
func:"return [{payload: '1'},{payload: '2'}];"},
|
||||
{id:"n2", type:"helper"}, {id:"n3", type:"helper"} ];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -116,8 +138,8 @@ describe('function node', function() {
|
||||
|
||||
it('should send to multiple messages', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],
|
||||
func:"return [[{payload: 1},{payload: 2}]];"},
|
||||
{id:"n2", type:"helper"} ];
|
||||
func:"return [[{payload: 1},{payload: 2}]];"},
|
||||
{id:"n2", type:"helper"} ];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -140,7 +162,7 @@ describe('function node', function() {
|
||||
|
||||
it('should allow input to be discarded by returning null', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return null"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -156,8 +178,8 @@ describe('function node', function() {
|
||||
|
||||
it('should handle null amongst valid messages', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return [[msg,null,msg],null]"},
|
||||
{id:"n2", type:"helper"},
|
||||
{id:"n3", type:"helper"}];
|
||||
{id:"n2", type:"helper"},
|
||||
{id:"n3", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -181,7 +203,7 @@ describe('function node', function() {
|
||||
|
||||
it('should get keys in global context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.keys();return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -197,7 +219,7 @@ describe('function node', function() {
|
||||
|
||||
function testNonObjectMessage(functionText,done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:functionText},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -290,7 +312,7 @@ describe('function node', function() {
|
||||
|
||||
it('should set node context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -304,9 +326,198 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should set persistable node context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0','memory1');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n1.context().get("count", "memory1", function (err, val) {
|
||||
val.should.equal("0");
|
||||
done();
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set two persistable node context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0','memory1');context.set('count','1','memory2');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n1.context().get("count", "memory1", function (err, val1) {
|
||||
val1.should.equal("0");
|
||||
n1.context().get("count", "memory2", function (err, val2) {
|
||||
val2.should.equal("1");
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set two persistable node context (single call, w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set(['count1','count2'],['0','1'],'memory1');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n1.context().get("count1", "memory1", function (err, val1) {
|
||||
val1.should.equal("0");
|
||||
n1.context().get("count2", "memory1", function (err, val2) {
|
||||
val2.should.equal("1");
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should set persistable node context (w callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0','memory1', function (err) { node.send(msg); });"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n1.context().get("count", "memory1", function (err, val) {
|
||||
val.should.equal("0");
|
||||
done();
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set two persistable node context (w callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0','memory1', function (err) { context.set('count', '1', 'memory2', function (err) { node.send(msg); }); });"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n1.context().get("count", "memory1", function (err, val1) {
|
||||
val1.should.equal("0");
|
||||
n1.context().get("count", "memory1", function (err, val2) {
|
||||
val2.should.equal("0");
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set two persistable node context (single call, w callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set(['count1','count2'],['0','1'],'memory1', function(err) { node.send(msg); });"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n1.context().get("count1", "memory1", function (err, val1) {
|
||||
val1.should.equal("0");
|
||||
n1.context().get("count2", "memory1", function (err, val2) {
|
||||
val2.should.equal("1");
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should set default persistable node context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n1.context().get("count", "memory1", function (err, val) {
|
||||
val.should.equal("0");
|
||||
done();
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get node context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.get('count');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -320,9 +531,64 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
function checkCallbackError(name, done) {
|
||||
try {
|
||||
helper.log().called.should.be.true();
|
||||
var logEvents = helper.log().args.filter(function (evt) {
|
||||
return evt[0].type == "function";
|
||||
});
|
||||
logEvents.should.have.length(1);
|
||||
var msg = logEvents[0][0];
|
||||
msg.should.have.property('level', helper.log().ERROR);
|
||||
msg.should.have.property('id', name);
|
||||
msg.should.have.property('type', 'function');
|
||||
msg.should.have.property('msg', 'Error: Callback must be a function');
|
||||
done();
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
}
|
||||
|
||||
it('should get persistable node context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.get('count','memory1');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().set("count","0","memory1");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', '0');
|
||||
done();
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get persistable node context (w/ callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.get('count','memory1',function (err, val) { msg.payload=val; node.send(msg); });"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().set("count","0","memory1");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', '0');
|
||||
done();
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get keys in node context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.keys();return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -336,9 +602,79 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should get keys in persistable node context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.keys('memory1');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().set("count","0","memory1");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', ['count']);
|
||||
done();
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get keys in persistable node context (w/ callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.keys('memory1', function(err, keys) { msg.payload=keys; node.send(msg); });"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().set("count","0","memory1");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', ['count']);
|
||||
done();
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get keys in default persistable node context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.keys();return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().set("count","0","memory1");
|
||||
n1.context().set("number","1","memory2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', ['count']);
|
||||
done();
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set flow context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -352,9 +688,115 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should set persistable flow context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0','memory1');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n2.context().flow.get("count", "memory1", function (err, val) {
|
||||
val.should.equal("0");
|
||||
done();
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set two persistable flow context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0','memory1');flow.set('count','1','memory2');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n2.context().flow.get("count", "memory1", function (err, val1) {
|
||||
val1.should.equal("0");
|
||||
n2.context().flow.get("count", "memory2", function (err, val2) {
|
||||
val2.should.equal("1");
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set persistable flow context (w/ callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0','memory1', function (err) { node.send(msg); });"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n2.context().flow.get("count", "memory1", function (err, val) {
|
||||
val.should.equal("0");
|
||||
done();
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set two persistable flow context (w/ callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0','memory1', function (err) { flow.set('count','1','memory2', function (err) { node.send(msg); }); });"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n2.context().flow.get("count", "memory1", function (err, val1) {
|
||||
val1.should.equal("0");
|
||||
n2.context().flow.get("count", "memory2", function (err, val2) {
|
||||
val2.should.equal("1");
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get flow context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.get('count');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -368,9 +810,45 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should get persistable flow context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.get('count','memory1');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().flow.set("count","0","memory1");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', '0');
|
||||
done();
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get persistable flow context (w/ callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.get('count','memory1', function(err, val) { msg.payload=val; node.send(msg); });"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().flow.set("count","0","memory1");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', '0');
|
||||
done();
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get flow context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.flow.get('count');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -386,7 +864,7 @@ describe('function node', function() {
|
||||
|
||||
it('should get keys in flow context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.keys();return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -400,9 +878,55 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should get keys in persistable flow context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.keys('memory1');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().flow.set("count","0","memory1");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', ['count']);
|
||||
done();
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get keys in persistable flow context (w/ callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.keys('memory1', function (err, val) { msg.payload=val; node.send(msg); });"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().flow.set("count","0","memory1");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', ['count']);
|
||||
done();
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set global context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.set('count','0');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -416,9 +940,59 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should set persistable global context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.set('count','0','memory1');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n2.context().global.get("count", "memory1", function(err, val) {
|
||||
val.should.equal("0");
|
||||
done();
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set persistable global context (w/ callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.set('count','0','memory1', function (err) { node.send(msg); });"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
n2.context().global.get("count", "memory1", function(err, val) {
|
||||
val.should.equal("0");
|
||||
done();
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get global context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('count');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -432,9 +1006,45 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should get persistable global context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('count', 'memory1');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
initContext(function () {
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().global.set("count","0", 'memory1');
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', '0');
|
||||
done();
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get persistable global context (w/ callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.get('count', 'memory1', function (err, val) { msg.payload=val; node.send(msg); });"},
|
||||
{id:"n2", type:"helper"}];
|
||||
initContext(function () {
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().global.set("count","0", 'memory1');
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', '0');
|
||||
done();
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get global context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.global.get('count');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -448,9 +1058,97 @@ describe('function node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should get persistable global context (w/o callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.global.get('count','memory1');return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().global.set("count","0", "memory1");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', '0');
|
||||
done();
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get persistable global context (w/ callback)', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.global.get('count','memory1', function (err, val) { msg.payload = val; node.send(msg); });"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().global.set("count","0", "memory1");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', '0');
|
||||
done();
|
||||
}
|
||||
catch(e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle error on get persistable context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.get('count','memory1','callback');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().flow.set("count","0","memory1");
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
checkCallbackError('n1', done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle error on set persistable context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.set('count','0','memory1','callback');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
checkCallbackError('n1', done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle error on get keys in persistable context', function(done) {
|
||||
var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.keys('memory1','callback');return msg;"},
|
||||
{id:"n2", type:"helper",z:"flowA"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context().flow.set("count","0","memory1");
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
checkCallbackError('n1', done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should handle setTimeout()', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"setTimeout(function(){node.send(msg);},1000);"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -476,7 +1174,7 @@ describe('function node', function() {
|
||||
|
||||
it('should handle setInterval()', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"setInterval(function(){node.send(msg);},100);"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -495,7 +1193,7 @@ describe('function node', function() {
|
||||
|
||||
it('should handle clearInterval()', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"var id=setInterval(null,100);setTimeout(function(){clearInterval(id);node.send(msg);},1000);"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -510,7 +1208,7 @@ describe('function node', function() {
|
||||
|
||||
it('should allow accessing node.id', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload = node.id; return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -524,7 +1222,7 @@ describe('function node', function() {
|
||||
|
||||
it('should allow accessing node.name', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload = node.name; return msg;", "name":"name of node"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -538,7 +1236,7 @@ describe('function node', function() {
|
||||
|
||||
it('should use the same Date object from outside the sandbox', function(done) {
|
||||
var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('typeTest')(new Date());return msg;"},
|
||||
{id:"n2", type:"helper"}];
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(functionNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
var should = require("should");
|
||||
var templateNode = require("../../../../nodes/core/core/80-template.js");
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
|
||||
describe('template node', function() {
|
||||
@@ -28,8 +29,35 @@ describe('template node', function() {
|
||||
helper.stopServer(done);
|
||||
});
|
||||
|
||||
beforeEach(function(done) {
|
||||
done();
|
||||
});
|
||||
|
||||
function initContext(done) {
|
||||
Context.init({
|
||||
contextStorage: {
|
||||
memory0: { // do not use (for excluding effect fallback)
|
||||
module: "memory"
|
||||
},
|
||||
memory1: {
|
||||
module: "memory"
|
||||
},
|
||||
memory2: {
|
||||
module: "memory"
|
||||
}
|
||||
}
|
||||
});
|
||||
Context.load().then(function () {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
helper.unload();
|
||||
helper.unload().then(function () {
|
||||
return Context.clean({allNodes:{}});
|
||||
}).then(function () {
|
||||
return Context.close();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -116,7 +144,6 @@ describe('template node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should modify payload from flow context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow.value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
@@ -132,6 +159,44 @@ describe('template node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify payload from persistable flow context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow[memory1].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'payload=foo');
|
||||
done();
|
||||
});
|
||||
n1.context().flow.set("value","foo","memory1",function (err) {
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify payload from two persistable flow context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow[memory1].value}}/{{flow[memory2].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
initContext(function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'payload=foo/bar');
|
||||
done();
|
||||
});
|
||||
n1.context().flow.set("value","foo","memory1",function (err) {
|
||||
n1.context().flow.set("value","bar","memory2",function (err) {
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify payload from global context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{global.value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
@@ -147,6 +212,64 @@ describe('template node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify payload from persistable global context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{global[memory1].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'payload=foo');
|
||||
done();
|
||||
});
|
||||
n1.context().global.set("value","foo","memory1", function (err) {
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify payload from two persistable global context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{global[memory1].value}}/{{global[memory2].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'payload=foo/bar');
|
||||
done();
|
||||
});
|
||||
n1.context().global.set("value","foo","memory1", function (err) {
|
||||
n1.context().global.set("value","bar","memory2", function (err) {
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify payload from persistable flow & global context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow[memory1].value}}/{{global[memory1].value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'payload=foo/bar');
|
||||
done();
|
||||
});
|
||||
n1.context().flow.set("value","foo","memory1", function (err) {
|
||||
n1.context().global.set("value","bar","memory1", function (err) {
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle missing node context', function(done) {
|
||||
// this is artificial test because in flow there is missing z property (probably never happen in real usage)
|
||||
var flow = [{id:"n1",type:"template", field:"payload", template:"payload={{flow.value}},{{global.value}}",wires:[["n2"]]},{id:"n2",type:"helper"}];
|
||||
@@ -206,6 +329,27 @@ describe('template node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify persistable flow context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"#:(memory1)::payload", fieldType:"flow", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
// mesage is intact
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
// result is in flow context
|
||||
n2.context().flow.get("payload", "memory1", function (err, val) {
|
||||
val.should.equal("payload=foo");
|
||||
done();
|
||||
});
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify global context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", fieldType:"global", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
@@ -223,6 +367,27 @@ describe('template node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should modify persistable global context', function(done) {
|
||||
var flow = [{id:"n1",z:"t1", type:"template", field:"#:(memory1)::payload", fieldType:"global", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
// mesage is intact
|
||||
msg.should.have.property('topic', 'bar');
|
||||
msg.should.have.property('payload', 'foo');
|
||||
// result is in global context
|
||||
n2.context().global.get("payload", "memory1", function (err, val) {
|
||||
val.should.equal("payload=foo");
|
||||
done();
|
||||
});
|
||||
});
|
||||
n1.receive({payload:"foo",topic: "bar"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle if the field isn\'t set', function(done) {
|
||||
var flow = [{id:"n1", type:"template", template: "payload={{payload}}",wires:[["n2"]]},{id:"n2",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
@@ -264,6 +429,7 @@ describe('template node', function() {
|
||||
n1.receive({payload:{A:"abc"}});
|
||||
});
|
||||
});
|
||||
|
||||
it('should raise error if passed bad template', function(done) {
|
||||
var flow = [{id:"n1", type:"template", field: "payload", template: "payload={{payload",wires:[["n2"]]},{id:"n2",type:"helper"}];
|
||||
helper.load(templateNode, flow, function() {
|
||||
|
@@ -18,6 +18,7 @@ var should = require("should");
|
||||
var sinon = require("sinon");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
var triggerNode = require("../../../../nodes/core/core/89-trigger.js");
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
var RED = require("../../../../red/red.js");
|
||||
|
||||
describe('trigger node', function() {
|
||||
@@ -26,8 +27,31 @@ describe('trigger node', function() {
|
||||
helper.startServer(done);
|
||||
});
|
||||
|
||||
function initContext(done) {
|
||||
Context.init({
|
||||
contextStorage: {
|
||||
memory0: {
|
||||
module: "memory"
|
||||
},
|
||||
memory1: {
|
||||
module: "memory"
|
||||
},
|
||||
memory2: {
|
||||
module: "memory"
|
||||
}
|
||||
}
|
||||
});
|
||||
Context.load().then(function () {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function(done) {
|
||||
helper.unload().then(function() {
|
||||
helper.unload().then(function () {
|
||||
return Context.clean({allNodes: {}});
|
||||
}).then(function () {
|
||||
return Context.close();
|
||||
}).then(function () {
|
||||
helper.stopServer(done);
|
||||
});
|
||||
});
|
||||
@@ -75,6 +99,74 @@ describe('trigger node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
function basicTest(type, val, rval) {
|
||||
it('should output 1st value when triggered ('+type+')', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:val, op1type:type, op2:"", op2type:"null", duration:"20", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
process.env[val] = rval;
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
delete process.env[val];
|
||||
done();
|
||||
}
|
||||
catch(err) { done(err); }
|
||||
});
|
||||
n1.emit("input", {payload:null});
|
||||
});
|
||||
});
|
||||
|
||||
it('should output 2st value when triggered ('+type+')', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"foo", op1type:"str", op2:val, op2type:type, duration:"20", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
process.env[val] = rval;
|
||||
helper.load(triggerNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var c = 0;
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
if (c === 0) {
|
||||
msg.should.have.property("payload", "foo");
|
||||
c++;
|
||||
}
|
||||
else {
|
||||
if (rval) {
|
||||
msg.should.have.property("payload");
|
||||
should.deepEqual(msg.payload, rval);
|
||||
}
|
||||
else {
|
||||
msg.should.have.property("payload", val);
|
||||
}
|
||||
delete process.env[val];
|
||||
done();
|
||||
}
|
||||
}
|
||||
catch(err) { done(err); }
|
||||
});
|
||||
n1.emit("input", {payload:null});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
basicTest("num", 10);
|
||||
basicTest("str", "10");
|
||||
basicTest("bool", true);
|
||||
var val_json = '{ "x":"vx", "y":"vy", "z":"vz" }';
|
||||
basicTest("json", val_json, JSON.parse(val_json));
|
||||
var val_buf = "[1,2,3,4,5]";
|
||||
basicTest("bin", val_buf, Buffer.from(JSON.parse(val_buf)));
|
||||
basicTest("env", "NR-TEST", "env-val");
|
||||
|
||||
it('should output 1 then 0 when triggered (default)', function(done) {
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", duration:"20", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
@@ -288,7 +380,7 @@ describe('trigger node', function() {
|
||||
|
||||
it('should be able to return things from flow and global context variables', function(done) {
|
||||
var spy = sinon.stub(RED.util, 'evaluateNodeProperty',
|
||||
function(arg1, arg2, arg3, arg4) { return arg1; }
|
||||
function(arg1, arg2, arg3, arg4, arg5) { if (arg5) { arg5(null, arg1) } else { return arg1; } }
|
||||
);
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"foo", op1type:"flow", op2:"bar", op2type:"global", duration:"20", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
@@ -312,7 +404,159 @@ describe('trigger node', function() {
|
||||
});
|
||||
n1.emit("input", {payload:null});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to return things from persistable flow and global context variables', function (done) {
|
||||
var flow = [{"id": "n1", "type": "trigger", "name": "triggerNode", "op1": "#:(memory1)::foo", "op1type": "flow",
|
||||
"op2": "#:(memory1)::bar", "op2type": "global", "duration": "20", "wires": [["n2"]], "z": "flow" },
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var c = 0;
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
if (c === 0) {
|
||||
msg.should.have.a.property("payload", "foo");
|
||||
c += 1;
|
||||
} else {
|
||||
msg.should.have.a.property("payload", "bar");
|
||||
done();
|
||||
}
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var context = n1.context();
|
||||
var flow = context.flow;
|
||||
var global = context.global;
|
||||
flow.set("foo", "foo", "memory1", function (err) {
|
||||
global.set("bar", "bar", "memory1", function (err) {
|
||||
n1.emit("input", { payload: null });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to return things from multiple persistable global context variables', function (done) {
|
||||
var flow = [{"id": "n1", "z": "flow", "type": "trigger",
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "global",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
if (count === 0) {
|
||||
msg.should.have.a.property("payload", "foo");
|
||||
}
|
||||
else {
|
||||
msg.should.have.a.property("payload", "bar");
|
||||
}
|
||||
count++;
|
||||
if (count === 1) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var global = n1.context().global;
|
||||
global.set("val", "foo", "memory1", function (err) {
|
||||
global.set("val", "bar", "memory2", function (err) {
|
||||
n1.emit("input", { payload: null });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to return things from multiple persistable flow context variables', function (done) {
|
||||
var flow = [{"id": "n1", "z": "flow", "type": "trigger",
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "flow"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
if (count === 0) {
|
||||
msg.should.have.a.property("payload", "foo");
|
||||
}
|
||||
else {
|
||||
msg.should.have.a.property("payload", "bar");
|
||||
}
|
||||
count++;
|
||||
if (count === 1) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var flow = n1.context().flow;
|
||||
flow.set("val", "foo", "memory1", function (err) {
|
||||
flow.set("val", "bar", "memory2", function (err) {
|
||||
n1.emit("input", { payload: null });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to return things from multiple persistable flow & global context variables', function (done) {
|
||||
var flow = [{"id": "n1", "z": "flow", "type": "trigger",
|
||||
"duration": "20", "wires": [["n2"]],
|
||||
"op1": "#:(memory1)::val", "op1type": "flow",
|
||||
"op2": "#:(memory2)::val", "op2type": "global"
|
||||
},
|
||||
{"id": "n2", "type": "helper"}];
|
||||
helper.load(triggerNode, flow, function () {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
if (count === 0) {
|
||||
msg.should.have.a.property("payload", "foo");
|
||||
}
|
||||
else {
|
||||
msg.should.have.a.property("payload", "bar");
|
||||
}
|
||||
count++;
|
||||
if (count === 1) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var context = n1.context();
|
||||
var flow = context.flow;
|
||||
var global = context.flow;
|
||||
flow.set("val", "foo", "memory1", function (err) {
|
||||
global.set("val", "bar", "memory2", function (err) {
|
||||
n1.emit("input", { payload: null });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to not output anything on first trigger', function(done) {
|
||||
@@ -386,7 +630,7 @@ describe('trigger node', function() {
|
||||
it('should be able to extend the delay', function(done) {
|
||||
this.timeout(5000); // add extra time for flake
|
||||
var spy = sinon.stub(RED.util, 'evaluateNodeProperty',
|
||||
function(arg1, arg2, arg3, arg4) { return arg1; }
|
||||
function(arg1, arg2, arg3, arg4, arg5) { if (arg5) { arg5(null, arg1) } else { return arg1; } }
|
||||
);
|
||||
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", extend:"true", op1type:"flow", op1:"foo", op2:"bar", op2type:"global", duration:"100", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"} ];
|
||||
@@ -428,14 +672,12 @@ describe('trigger node', function() {
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
if (c === 0) {
|
||||
console.log(c,Date.now() - ss,msg);
|
||||
msg.should.have.a.property("payload", "Hello");
|
||||
c += 1;
|
||||
}
|
||||
else {
|
||||
console.log(c,Date.now() - ss,msg);
|
||||
msg.should.have.a.property("payload", "World");
|
||||
(Date.now() - ss).should.be.greaterThan(150);
|
||||
(Date.now() - ss).should.be.greaterThan(149);
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
89
test/nodes/core/hardware/36-rpi-gpio_spec.js
Normal file
89
test/nodes/core/hardware/36-rpi-gpio_spec.js
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var should = require("should");
|
||||
var rpi = require("../../../../nodes/core/hardware/36-rpi-gpio.js");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
var fs = require("fs");
|
||||
|
||||
describe('RPI GPIO Node', function() {
|
||||
|
||||
before(function(done) {
|
||||
helper.startServer(done);
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
helper.stopServer(done);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
helper.unload();
|
||||
});
|
||||
|
||||
var checkIgnore = function(done) {
|
||||
setTimeout(function() {
|
||||
try {
|
||||
var logEvents = helper.log().args.filter(function(evt) {
|
||||
return ((evt[0].level == 30) && (evt[0].msg.indexOf("rpi-gpio")===0));
|
||||
});
|
||||
logEvents[0][0].should.have.a.property('msg');
|
||||
logEvents[0][0].msg.toString().should.startWith("rpi-gpio : rpi-gpio.errors.ignorenode");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
},25);
|
||||
}
|
||||
|
||||
it('should load Input node', function(done) {
|
||||
var flow = [{id:"n1", type:"rpi-gpio in", name:"rpi-gpio in" }];
|
||||
helper.load(rpi, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
n1.should.have.property('name', 'rpi-gpio in');
|
||||
try {
|
||||
var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString();
|
||||
if (cpuinfo.indexOf(": BCM") === 1) {
|
||||
done(); // It's ON a PI ... should really do more tests !
|
||||
} else {
|
||||
checkIgnore(done);
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
checkIgnore(done);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should load Output node', function(done) {
|
||||
var flow = [{id:"n1", type:"rpi-gpio out", name:"rpi-gpio out" }];
|
||||
helper.load(rpi, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
n1.should.have.property('name', 'rpi-gpio out');
|
||||
try {
|
||||
var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString();
|
||||
if (cpuinfo.indexOf(": BCM") === 1) {
|
||||
done(); // It's ON a PI ... should really do more tests !
|
||||
} else {
|
||||
checkIgnore(done);
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
checkIgnore(done);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@@ -102,38 +102,13 @@ describe('HTTP Request Node', function() {
|
||||
return "localhost:"+testSslPort+url;
|
||||
}
|
||||
|
||||
function saveProxySetting() {
|
||||
preEnvHttpProxyLowerCase = process.env.http_proxy;
|
||||
preEnvHttpProxyUpperCase = process.env.HTTP_PROXY;
|
||||
preEnvNoProxyLowerCase = process.env.no_proxy;
|
||||
preEnvNoProxyUpperCase = process.env.NO_PROXY;
|
||||
function deleteProxySetting() {
|
||||
delete process.env.http_proxy;
|
||||
delete process.env.HTTP_PROXY;
|
||||
delete process.env.no_proxy;
|
||||
delete process.env.NO_PROXY;
|
||||
}
|
||||
|
||||
function restoreProxySetting() {
|
||||
process.env.http_proxy = preEnvHttpProxyLowerCase;
|
||||
process.env.HTTP_PROXY = preEnvHttpProxyUpperCase;
|
||||
// On Windows, if environment variable of NO_PROXY that includes lower cases
|
||||
// such as No_Proxy is replaced with NO_PROXY.
|
||||
process.env.no_proxy = preEnvNoProxyLowerCase;
|
||||
process.env.NO_PROXY = preEnvNoProxyUpperCase;
|
||||
if (preEnvHttpProxyLowerCase == undefined){
|
||||
delete process.env.http_proxy;
|
||||
}
|
||||
if (preEnvHttpProxyUpperCase == undefined){
|
||||
delete process.env.HTTP_PROXY;
|
||||
}
|
||||
if (preEnvNoProxyLowerCase == undefined){
|
||||
delete process.env.no_proxy;
|
||||
}
|
||||
if (preEnvNoProxyUpperCase == undefined){
|
||||
delete process.env.NO_PROXY;
|
||||
}
|
||||
}
|
||||
|
||||
before(function(done) {
|
||||
testApp = express();
|
||||
testApp.use(bodyParser.raw({type:"*/*"}));
|
||||
@@ -225,7 +200,35 @@ describe('HTTP Request Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
beforeEach(function() {
|
||||
preEnvHttpProxyLowerCase = process.env.http_proxy;
|
||||
preEnvHttpProxyUpperCase = process.env.HTTP_PROXY;
|
||||
preEnvNoProxyLowerCase = process.env.no_proxy;
|
||||
preEnvNoProxyUpperCase = process.env.NO_PROXY;
|
||||
process.env.no_proxy = 'localhost';
|
||||
process.env.NO_PROXY = 'localhost';
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
process.env.http_proxy = preEnvHttpProxyLowerCase;
|
||||
process.env.HTTP_PROXY = preEnvHttpProxyUpperCase;
|
||||
// On Windows, if environment variable of NO_PROXY that includes lower cases
|
||||
// such as No_Proxy is replaced with NO_PROXY.
|
||||
process.env.no_proxy = preEnvNoProxyLowerCase;
|
||||
process.env.NO_PROXY = preEnvNoProxyUpperCase;
|
||||
if (preEnvHttpProxyLowerCase == undefined) {
|
||||
delete process.env.http_proxy;
|
||||
}
|
||||
if (preEnvHttpProxyUpperCase == undefined) {
|
||||
delete process.env.HTTP_PROXY;
|
||||
}
|
||||
if (preEnvNoProxyLowerCase == undefined) {
|
||||
delete process.env.no_proxy;
|
||||
}
|
||||
if (preEnvNoProxyUpperCase == undefined) {
|
||||
delete process.env.NO_PROXY;
|
||||
}
|
||||
helper.unload();
|
||||
});
|
||||
|
||||
@@ -1060,13 +1063,12 @@ describe('HTTP Request Node', function() {
|
||||
it('should use http_proxy', function(done) {
|
||||
var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')},
|
||||
{id:"n2", type:"helper"}];
|
||||
saveProxySetting();
|
||||
deleteProxySetting();
|
||||
process.env.http_proxy = "http://localhost:" + testProxyPort;
|
||||
helper.load(httpRequestNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
restoreProxySetting();
|
||||
try {
|
||||
msg.should.have.property('statusCode',200);
|
||||
msg.payload.should.have.property('headers');
|
||||
@@ -1083,13 +1085,12 @@ describe('HTTP Request Node', function() {
|
||||
it('should use http_proxy when environment variable is invalid', function(done) {
|
||||
var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')},
|
||||
{id:"n2", type:"helper"}];
|
||||
saveProxySetting();
|
||||
deleteProxySetting();
|
||||
process.env.http_proxy = "invalidvalue";
|
||||
helper.load(httpRequestNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
restoreProxySetting();
|
||||
try {
|
||||
msg.should.have.property('statusCode',200);
|
||||
msg.payload.should.have.property('headers');
|
||||
@@ -1106,13 +1107,12 @@ describe('HTTP Request Node', function() {
|
||||
it('should use HTTP_PROXY', function(done) {
|
||||
var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')},
|
||||
{id:"n2", type:"helper"}];
|
||||
saveProxySetting();
|
||||
deleteProxySetting();
|
||||
process.env.HTTP_PROXY = "http://localhost:" + testProxyPort;
|
||||
helper.load(httpRequestNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
restoreProxySetting();
|
||||
try {
|
||||
msg.should.have.property('statusCode',200);
|
||||
msg.payload.should.have.property('headers');
|
||||
@@ -1129,14 +1129,13 @@ describe('HTTP Request Node', function() {
|
||||
it('should use no_proxy', function(done) {
|
||||
var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')},
|
||||
{id:"n2", type:"helper"}];
|
||||
saveProxySetting();
|
||||
deleteProxySetting();
|
||||
process.env.http_proxy = "http://localhost:" + testProxyPort;
|
||||
process.env.no_proxy = "foo,localhost";
|
||||
helper.load(httpRequestNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
restoreProxySetting();
|
||||
try {
|
||||
msg.should.have.property('statusCode',200);
|
||||
msg.payload.headers.should.not.have.property('x-testproxy-header','foobar');
|
||||
@@ -1152,14 +1151,13 @@ describe('HTTP Request Node', function() {
|
||||
it('should use NO_PROXY', function(done) {
|
||||
var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')},
|
||||
{id:"n2", type:"helper"}];
|
||||
saveProxySetting();
|
||||
deleteProxySetting();
|
||||
process.env.HTTP_PROXY = "http://localhost:" + testProxyPort;
|
||||
process.env.NO_PROXY = "foo,localhost";
|
||||
helper.load(httpRequestNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
restoreProxySetting();
|
||||
try {
|
||||
msg.should.have.property('statusCode',200);
|
||||
msg.payload.headers.should.not.have.property('x-testproxy-header','foobar');
|
||||
@@ -1198,13 +1196,12 @@ describe('HTTP Request Node', function() {
|
||||
it('should authenticate on proxy server', function(done) {
|
||||
var flow = [{id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate')},
|
||||
{id:"n2", type:"helper"}];
|
||||
saveProxySetting();
|
||||
deleteProxySetting();
|
||||
process.env.http_proxy = "http://foouser:barpassword@localhost:" + testProxyPort;
|
||||
helper.load(httpRequestNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
restoreProxySetting();
|
||||
try {
|
||||
msg.should.have.property('statusCode',200);
|
||||
msg.payload.should.have.property('user', 'foouser');
|
||||
@@ -1223,13 +1220,12 @@ describe('HTTP Request Node', function() {
|
||||
it('should output an error when proxy authentication was failed', function(done) {
|
||||
var flow = [{id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate')},
|
||||
{id:"n2", type:"helper"}];
|
||||
saveProxySetting();
|
||||
deleteProxySetting();
|
||||
process.env.http_proxy = "http://xxxuser:barpassword@localhost:" + testProxyPort;
|
||||
helper.load(httpRequestNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
restoreProxySetting();
|
||||
try {
|
||||
msg.should.have.property('statusCode',407);
|
||||
msg.headers.should.have.property('proxy-authenticate', 'BASIC realm="test"');
|
||||
|
@@ -19,6 +19,7 @@ var should = require("should");
|
||||
var stoppable = require('stoppable');
|
||||
var helper = require("node-red-node-test-helper");
|
||||
var tcpinNode = require("../../../../nodes/core/io/31-tcpin.js");
|
||||
const RED = require("../../../../red/red.js");
|
||||
|
||||
|
||||
describe('TCP Request Node', function() {
|
||||
@@ -28,12 +29,12 @@ describe('TCP Request Node', function() {
|
||||
function startServer(done) {
|
||||
port += 1;
|
||||
server = stoppable(net.createServer(function(c) {
|
||||
c.on('data', function(data) {
|
||||
var rdata = "ACK:"+data.toString();
|
||||
c.write(rdata);
|
||||
});
|
||||
c.on('data', function(data) {
|
||||
var rdata = "ACK:"+data.toString();
|
||||
c.write(rdata);
|
||||
});
|
||||
c.on('error', function(err) {
|
||||
startServer(done);
|
||||
startServer(done);
|
||||
});
|
||||
})).listen(port, "127.0.0.1", function(err) {
|
||||
done();
|
||||
@@ -64,48 +65,108 @@ describe('TCP Request Node', function() {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
if((typeof val0) === 'object') {
|
||||
n1.receive(val0);
|
||||
} else {
|
||||
n1.receive({payload:val0});
|
||||
}
|
||||
if((typeof val0) === 'object') {
|
||||
n1.receive(val0);
|
||||
} else {
|
||||
n1.receive({payload:val0});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
it('should send & recv data', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"time", splitc: "0", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, "foo", "ACK:foo", done)
|
||||
function testTCPMany(flow, values, result, done) {
|
||||
helper.load(tcpinNode, flow, () => {
|
||||
const n1 = helper.getNode("n1");
|
||||
const n2 = helper.getNode("n2");
|
||||
n2.on("input", msg => {
|
||||
try {
|
||||
msg.should.have.property('payload', Buffer(result));
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
values.forEach(value => {
|
||||
n1.receive(typeof value === 'object' ? value : {payload: value});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('single message', function () {
|
||||
it('should send & recv data', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"time", splitc: "0", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, "foo", "ACK:foo", done)
|
||||
});
|
||||
|
||||
it('should send & recv data when specified character received', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"char", splitc: "0", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, "foo0bar0", "ACK:foo0", done);
|
||||
});
|
||||
|
||||
it('should send & recv data after fixed number of chars received', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"count", splitc: "7", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, "foo bar", "ACK:foo", done);
|
||||
});
|
||||
|
||||
it('should send & receive, then keep connection', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", splitc: "5", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, "foo", "ACK:foo", done);
|
||||
});
|
||||
|
||||
it('should send & recv data to/from server:port from msg', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"", port:"", out:"time", splitc: "0", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, {payload:"foo", host:"localhost", port:port}, "ACK:foo", done)
|
||||
});
|
||||
});
|
||||
|
||||
it('should send & recv data when specified character received', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"char", splitc: "0", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, "foo0bar0", "ACK:foo0", done);
|
||||
});
|
||||
describe('many messages', function () {
|
||||
it('should send & recv data', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"time", splitc: "0", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
|
||||
it('should send & recv data after fixed number of chars received', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"count", splitc: "7", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, "foo bar", "ACK:foo", done);
|
||||
});
|
||||
testTCPMany(flow, ['f', 'o', 'o'], 'ACK:foo', done);
|
||||
});
|
||||
|
||||
it('should send & receive, then keep connection', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", splitc: "5", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, "foo", "ACK:foo", done);
|
||||
});
|
||||
it('should send & recv data when specified character received', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"char", splitc: "0", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCPMany(flow, ["foo0","bar0"], "ACK:foo0", done);
|
||||
});
|
||||
|
||||
it('should send & close', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", splitc: "5", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, "foo", "ACK:foo", done);
|
||||
});
|
||||
it('should send & recv data after fixed number of chars received', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"count", splitc: "7", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCPMany(flow, ["fo", "ob", "ar"], "ACK:foo", done);
|
||||
});
|
||||
|
||||
it('should send & recv data to/from server:port from msg', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"", port:"", out:"time", splitc: "0", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCP(flow, {payload:"foo", host:"localhost", port:port}, "ACK:foo", done)
|
||||
});
|
||||
|
||||
it('should send & receive, then keep connection', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", splitc: "5", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCPMany(flow, ["foo", "bar", "baz"], "ACK:foobarbaz", done);
|
||||
});
|
||||
|
||||
it('should send & recv data to/from server:port from msg', function(done) {
|
||||
var flow = [{id:"n1", type:"tcp request", server:"", port:"", out:"time", splitc: "0", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
testTCPMany(flow, [
|
||||
{payload:"f", host:"localhost", port:port},
|
||||
{payload:"o", host:"localhost", port:port},
|
||||
{payload:"o", host:"localhost", port:port}], "ACK:foo", done);
|
||||
});
|
||||
|
||||
it('should limit the queue size', function (done) {
|
||||
RED.settings.tcpMsgQueueSize = 10;
|
||||
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", splitc: "5", wires:[["n2"]] },
|
||||
{id:"n2", type:"helper"}];
|
||||
// create one more msg than is allowed
|
||||
const msgs = new Array(RED.settings.tcpMsgQueueSize + 1).fill('x');
|
||||
const expected = msgs.slice(0, -1);
|
||||
testTCPMany(flow, msgs, "ACK:" + expected.join(''), done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -19,6 +19,7 @@ var should = require("should");
|
||||
var switchNode = require("../../../../nodes/core/logic/10-switch.js");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
var RED = require("../../../../red/red.js");
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
|
||||
describe('switch Node', function() {
|
||||
|
||||
@@ -26,10 +27,31 @@ describe('switch Node', function() {
|
||||
helper.startServer(done);
|
||||
});
|
||||
|
||||
function initContext(done) {
|
||||
Context.init({
|
||||
contextStorage: {
|
||||
memory0: {
|
||||
module: "memory"
|
||||
},
|
||||
memory1: {
|
||||
module: "memory"
|
||||
}
|
||||
}
|
||||
});
|
||||
Context.load().then(function () {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function(done) {
|
||||
helper.unload();
|
||||
RED.settings.nodeMessageBufferMaxLength = 0;
|
||||
helper.stopServer(done);
|
||||
helper.unload().then(function () {
|
||||
return Context.clean({allNodes: {}});
|
||||
}).then(function () {
|
||||
return Context.close();
|
||||
}).then(function () {
|
||||
RED.settings.nodeMessageBufferMaxLength = 0;
|
||||
helper.stopServer(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should be loaded with some defaults', function(done) {
|
||||
@@ -125,7 +147,7 @@ describe('switch Node', function() {
|
||||
helper.load(switchNode, flow, function() {
|
||||
var switchNode1 = helper.getNode("switchNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
var sid = undefined;
|
||||
var sid;
|
||||
var count = 0;
|
||||
if (modifier !== undefined) {
|
||||
modifier(switchNode1);
|
||||
@@ -293,6 +315,102 @@ describe('switch Node', function() {
|
||||
genericSwitchTest("istype", "undefined", true, true, undefined, done);
|
||||
});
|
||||
|
||||
it('should handle flow context', function (done) {
|
||||
var flow = [{"id": "switchNode1", "type": "switch", "property": "foo", "propertyType": "flow",
|
||||
"rules": [{"t": "eq", "v": "bar", "vt": "flow"}],
|
||||
"checkall": "true", "outputs": "1", "wires": [["helperNode1"]], "z": "flow"},
|
||||
{"id": "helperNode1", "type": "helper", "wires": []}];
|
||||
helper.load(switchNode, flow, function () {
|
||||
var switchNode1 = helper.getNode("switchNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function (msg) {
|
||||
try {
|
||||
msg.payload.should.equal("value");
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
switchNode1.context().flow.set("foo", "flowValue");
|
||||
switchNode1.context().flow.set("bar", "flowValue");
|
||||
switchNode1.receive({payload: "value"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle persistable flow context', function (done) {
|
||||
var flow = [{"id": "switchNode1", "type": "switch", "property": "#:(memory1)::foo", "propertyType": "flow",
|
||||
"rules": [{"t": "eq", "v": "#:(memory1)::bar", "vt": "flow"}],
|
||||
"checkall": "true", "outputs": "1", "wires": [["helperNode1"]], "z": "flow"},
|
||||
{"id": "helperNode1", "type": "helper", "wires": []}];
|
||||
helper.load(switchNode, flow, function () {
|
||||
initContext(function () {
|
||||
var switchNode1 = helper.getNode("switchNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function (msg) {
|
||||
try {
|
||||
msg.payload.should.equal("value");
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
switchNode1.context().flow.set("foo", "flowValue", "memory1", function (err) {
|
||||
switchNode1.context().flow.set("bar", "flowValue", "memory1", function (err) {
|
||||
switchNode1.receive({payload: "value"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle global context', function (done) {
|
||||
var flow = [{"id": "switchNode1", "type": "switch", "property": "foo", "propertyType": "global",
|
||||
"rules": [{"t": "eq", "v": "bar", "vt": "global"}],
|
||||
"checkall": "true", "outputs": "1", "wires": [["helperNode1"]]},
|
||||
{"id": "helperNode1", "type": "helper", "wires": []}];
|
||||
helper.load(switchNode, flow, function () {
|
||||
var switchNode1 = helper.getNode("switchNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function (msg) {
|
||||
try {
|
||||
msg.payload.should.equal("value");
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
switchNode1.context().global.set("foo", "globalValue");
|
||||
switchNode1.context().global.set("bar", "globalValue");
|
||||
switchNode1.receive({payload: "value"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle persistable global context', function (done) {
|
||||
var flow = [{"id": "switchNode1", "type": "switch", "property": "#:(memory1)::foo", "propertyType": "global",
|
||||
"rules": [{"t": "eq", "v": "#:(memory1)::bar", "vt": "global"}],
|
||||
"checkall": "true", "outputs": "1", "wires": [["helperNode1"]]},
|
||||
{"id": "helperNode1", "type": "helper", "wires": []}];
|
||||
helper.load(switchNode, flow, function () {
|
||||
initContext(function () {
|
||||
var switchNode1 = helper.getNode("switchNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function (msg) {
|
||||
try {
|
||||
msg.payload.should.equal("foo");
|
||||
done();
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
switchNode1.context().global.set("foo", "globalValue", "memory1", function (err) {
|
||||
switchNode1.context().global.set("bar", "globalValue", "memory1", function (err) {
|
||||
switchNode1.receive({payload: "foo"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should match regex with ignore-case flag set true', function(done) {
|
||||
var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"regex","v":"onetwothree","case":true}],checkall:true,outputs:1,wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -333,6 +451,75 @@ describe('switch Node', function() {
|
||||
singularSwitchTest(false, true, false, true, done);
|
||||
});
|
||||
|
||||
it('should check if payload is empty (string)', function(done) {
|
||||
singularSwitchTest("empty", true, true, "", done);
|
||||
});
|
||||
it('should check if payload is empty (array)', function(done) {
|
||||
singularSwitchTest("empty", true, true, [], done);
|
||||
});
|
||||
it('should check if payload is empty (buffer)', function(done) {
|
||||
singularSwitchTest("empty", true, true, Buffer.alloc(0), done);
|
||||
});
|
||||
it('should check if payload is empty (object)', function(done) {
|
||||
singularSwitchTest("empty", true, true, {}, done);
|
||||
});
|
||||
it('should check if payload is empty (non-empty string)', function(done) {
|
||||
singularSwitchTest("empty", true, false, "1", done);
|
||||
});
|
||||
it('should check if payload is empty (non-empty array)', function(done) {
|
||||
singularSwitchTest("empty", true, false, [1], done);
|
||||
});
|
||||
it('should check if payload is empty (non-empty buffer)', function(done) {
|
||||
singularSwitchTest("empty", true, false, Buffer.alloc(1), done);
|
||||
});
|
||||
it('should check if payload is empty (non-empty object)', function(done) {
|
||||
singularSwitchTest("empty", true, false, {a:1}, done);
|
||||
});
|
||||
it('should check if payload is empty (null)', function(done) {
|
||||
singularSwitchTest("empty", true, false, null, done);
|
||||
});
|
||||
it('should check if payload is empty (undefined)', function(done) {
|
||||
singularSwitchTest("empty", true, false, undefined, done);
|
||||
});
|
||||
it('should check if payload is empty (0)', function(done) {
|
||||
singularSwitchTest("empty", true, false, 0, done);
|
||||
});
|
||||
|
||||
it('should check if payload is not empty (string)', function(done) {
|
||||
singularSwitchTest("nempty", true, !true, "", done);
|
||||
});
|
||||
it('should check if payload is not empty (array)', function(done) {
|
||||
singularSwitchTest("nempty", true, !true, [], done);
|
||||
});
|
||||
it('should check if payload is not empty (buffer)', function(done) {
|
||||
singularSwitchTest("nempty", true, !true, Buffer.alloc(0), done);
|
||||
});
|
||||
it('should check if payload is not empty (object)', function(done) {
|
||||
singularSwitchTest("nempty", true, !true, {}, done);
|
||||
});
|
||||
it('should check if payload is not empty (non-empty string)', function(done) {
|
||||
singularSwitchTest("nempty", true, !false, "1", done);
|
||||
});
|
||||
it('should check if payload is not empty (non-empty array)', function(done) {
|
||||
singularSwitchTest("nempty", true, !false, [1], done);
|
||||
});
|
||||
it('should check if payload is not empty (non-empty buffer)', function(done) {
|
||||
singularSwitchTest("nempty", true, !false, Buffer.alloc(1), done);
|
||||
});
|
||||
it('should check if payload is not empty (non-empty object)', function(done) {
|
||||
singularSwitchTest("nempty", true, !false, {a:1}, done);
|
||||
});
|
||||
it('should check if payload is not empty (null)', function(done) {
|
||||
singularSwitchTest("nempty", true, false, null, done);
|
||||
});
|
||||
it('should check if payload is not empty (undefined)', function(done) {
|
||||
singularSwitchTest("nempty", true, false, undefined, done);
|
||||
});
|
||||
it('should check if payload is not empty (0)', function(done) {
|
||||
singularSwitchTest("nempty", true, false, 0, done);
|
||||
});
|
||||
|
||||
|
||||
it('should check input against a previous value', function(done) {
|
||||
var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{ "t": "gt", "v": "", "vt": "prev" }],checkall:true,outputs:1,wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -460,7 +647,7 @@ describe('switch Node', function() {
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
},100)
|
||||
},500)
|
||||
});
|
||||
});
|
||||
|
||||
@@ -584,6 +771,53 @@ describe('switch Node', function() {
|
||||
customFlowSwitchTest(flow, true, -5, done);
|
||||
});
|
||||
|
||||
it('should handle flow and global contexts with JSONata expression', function(done) {
|
||||
var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"$abs($flowContext(\"payload\"))",propertyType:"jsonata",rules:[{"t":"btwn","v":"$flowContext(\"vt\")","vt":"jsonata","v2":"$globalContext(\"v2t\")","v2t":"jsonata"}],checkall:true,outputs:1,wires:[["helperNode1"]],z:"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],z:"flow"},
|
||||
{id:"flow",type:"tab"}];
|
||||
helper.load(switchNode, flow, function() {
|
||||
var switchNode1 = helper.getNode("switchNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
switchNode1.context().flow.set("payload",-5);
|
||||
switchNode1.context().flow.set("vt",4);
|
||||
switchNode1.context().global.set("v2t",6);
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
should.equal(msg.payload,"pass");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
switchNode1.receive({payload:"pass"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle persistable flow and global contexts with JSONata expression', function(done) {
|
||||
var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"$abs($flowContext(\"payload\",\"memory1\"))",propertyType:"jsonata",rules:[{"t":"btwn","v":"$flowContext(\"vt\",\"memory1\")","vt":"jsonata","v2":"$globalContext(\"v2t\",\"memory1\")","v2t":"jsonata"}],checkall:true,outputs:1,wires:[["helperNode1"]],z:"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],z:"flow"},
|
||||
{id:"flow",type:"tab"}];
|
||||
helper.load(switchNode, flow, function() {
|
||||
initContext(function () {
|
||||
var switchNode1 = helper.getNode("switchNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
switchNode1.context().flow.set(["payload","vt"],[-7,6],"memory1",function(){
|
||||
switchNode1.context().global.set("v2t",8,"memory1",function(){
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
should.equal(msg.payload,"pass");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
switchNode1.receive({payload:"pass"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should take head of message sequence (no repair)', function(done) {
|
||||
var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"head","v":3}],checkall:false,repair:false,outputs:1,wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -599,7 +833,7 @@ describe('switch Node', function() {
|
||||
it('should take head of message sequence (w. context)', function(done) {
|
||||
var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"head","v":"count",vt:"global"}],checkall:false,repair:true,outputs:1,wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [0, 1, 2], true,
|
||||
customFlowSequenceSwitchTest(flow, [0, 1, 2, 3, 4], [0, 1, 2], true,
|
||||
function(node) {
|
||||
node.context().global.set("count", 3);
|
||||
}, done);
|
||||
@@ -642,7 +876,7 @@ describe('switch Node', function() {
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
customFlowSwitchTest(flow, true, 9, done);
|
||||
});
|
||||
|
||||
|
||||
it('should be able to use $I in JSONata expression', function(done) {
|
||||
var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"payload",rules:[{"t":"jsonata_exp","v":"$I % 2 = 1",vt:"jsonata"}],checkall:true,repair:true,outputs:1,wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -666,9 +900,11 @@ describe('switch Node', function() {
|
||||
var vals = new Array(port_count);
|
||||
var recv_count = 0;
|
||||
for (var id in outs) {
|
||||
var out = outs[id];
|
||||
vals[out.port] = out.vals;
|
||||
recv_count += out.vals.length;
|
||||
if (outs.hasOwnProperty(id)) {
|
||||
var out = outs[id];
|
||||
vals[out.port] = out.vals;
|
||||
recv_count += out.vals.length;
|
||||
}
|
||||
}
|
||||
var count = 0;
|
||||
function check_msg(msg, ix, vf) {
|
||||
@@ -676,7 +912,7 @@ describe('switch Node', function() {
|
||||
msg.should.have.property("payload");
|
||||
var payload = msg.payload;
|
||||
msg.should.have.property("parts");
|
||||
vf(payload).should.be.ok;
|
||||
vf(payload).should.be.ok();
|
||||
var parts = msg.parts;
|
||||
var evals = vals[ix];
|
||||
parts.should.have.property("id");
|
||||
@@ -703,8 +939,8 @@ describe('switch Node', function() {
|
||||
}
|
||||
var index = parts.index;
|
||||
var eindex = counts[ix];
|
||||
var eval = evals[eindex];
|
||||
payload.should.equal(eval);
|
||||
var value = evals[eindex];
|
||||
payload.should.equal(value);
|
||||
counts[ix]++;
|
||||
count++;
|
||||
if (count === recv_count) {
|
||||
@@ -716,18 +952,22 @@ describe('switch Node', function() {
|
||||
}
|
||||
}
|
||||
for (var id in outs) {
|
||||
(function() {
|
||||
var node = helper.getNode(id);
|
||||
var port = outs[id].port;
|
||||
var vf = outs[id].vf;
|
||||
node.on("input", function(msg) {
|
||||
check_msg(msg, port, vf);
|
||||
});
|
||||
})();
|
||||
if (outs.hasOwnProperty(id)) {
|
||||
(function() {
|
||||
var node = helper.getNode(id);
|
||||
var port = outs[id].port;
|
||||
var vf = outs[id].vf;
|
||||
node.on("input", function(msg) {
|
||||
check_msg(msg, port, vf);
|
||||
});
|
||||
})();
|
||||
}
|
||||
}
|
||||
for(var i in seq_in) {
|
||||
n1.receive({payload:seq_in[i], xindex:i,
|
||||
parts:{index:i, count:seq_in.length, id:222}});
|
||||
if (seq_in.hasOwnProperty(i)) {
|
||||
n1.receive({payload:seq_in[i], xindex:i,
|
||||
parts:{index:i, count:seq_in.length, id:222}});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -786,9 +1026,9 @@ describe('switch Node', function() {
|
||||
var data = [ 1, -2, 2, 0, -1 ];
|
||||
var outs = {
|
||||
"n2" : { port:0, vals:[1, 2, 0],
|
||||
vf:function(x) { return(x > 0); } },
|
||||
vf:function(x) { return(x >= 0); } },
|
||||
"n3" : { port:1, vals:[-2, 0, -1],
|
||||
vf:function(x) { return(x < 0); } },
|
||||
vf:function(x) { return(x <= 0); } },
|
||||
"n4" : { port:2, vals:[],
|
||||
vf:function(x) { return(false); } },
|
||||
};
|
||||
@@ -821,4 +1061,24 @@ describe('switch Node', function() {
|
||||
n1.receive({payload:1, parts:{index:0, count:4, id:222}});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle invalid jsonata expression', function(done) {
|
||||
|
||||
var flow = [{id:"switchNode1",type:"switch",name:"switchNode",property:"$invalidExpression(payload)",propertyType:"jsonata",rules:[{"t":"btwn","v":"$sqrt(16)","vt":"jsonata","v2":"$sqrt(36)","v2t":"jsonata"}],checkall:true,outputs:1,wires:[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(switchNode, flow, function() {
|
||||
var n1 = helper.getNode("switchNode1");
|
||||
setTimeout(function() {
|
||||
var logEvents = helper.log().args.filter(function (evt) {
|
||||
return evt[0].type == "switch";
|
||||
});
|
||||
var evt = logEvents[0][0];
|
||||
evt.should.have.property('id', "switchNode1");
|
||||
evt.should.have.property('type', "switch");
|
||||
done();
|
||||
}, 150);
|
||||
n1.receive({payload:1});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -15,8 +15,10 @@
|
||||
**/
|
||||
|
||||
var should = require("should");
|
||||
var sinon = require("sinon");
|
||||
|
||||
var changeNode = require("../../../../nodes/core/logic/15-change.js");
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
|
||||
describe('change Node', function() {
|
||||
@@ -25,9 +27,30 @@ describe('change Node', function() {
|
||||
helper.startServer(done);
|
||||
});
|
||||
|
||||
function initContext(done) {
|
||||
Context.init({
|
||||
contextStorage: {
|
||||
memory0: {
|
||||
module: "memory"
|
||||
},
|
||||
memory1: {
|
||||
module: "memory"
|
||||
}
|
||||
}
|
||||
});
|
||||
Context.load().then(function () {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function(done) {
|
||||
helper.unload();
|
||||
helper.stopServer(done);
|
||||
helper.unload().then(function () {
|
||||
return Context.clean({allNodes: {}});
|
||||
}).then(function () {
|
||||
return Context.close();
|
||||
}).then(function () {
|
||||
helper.stopServer(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should load node with defaults', function(done) {
|
||||
@@ -95,6 +118,30 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value of persistable global context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t":"set","p":"#:(memory1)::globalValue","pt":"global","to":"changed","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
changeNode1.context().global.get("globalValue", "memory1", function (err, val) {
|
||||
val.should.equal("changed");
|
||||
done();
|
||||
});
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().global.set("globalValue","changeMe","memory1", function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets the value and type of the message property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "set", "p": "payload", "pt": "msg", "to": "12345", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -299,6 +346,28 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value to persistable flow context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"#:(memory1)::flowValue","tot":"flow"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.payload.should.eql("Hello World!");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().flow.set("flowValue","Hello World!","memory1",function(err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value to global context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"globalValue","tot":"global"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -318,6 +387,28 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value to persistable global context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"#:(memory1)::globalValue","tot":"global"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.payload.should.eql("Hello World!");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().global.set("globalValue","Hello World!","memory1", function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value to a number', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"123","tot":"num"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -454,6 +545,120 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('reports invalid jsonata expression', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$invalid(payload)","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
sinon.spy(changeNode1,"error");
|
||||
helperNode1.on("input", function(msg) {
|
||||
done("Invalid jsonata expression passed message through");
|
||||
});
|
||||
changeNode1.receive({payload:"Hello World!"});
|
||||
setTimeout(function() {
|
||||
try {
|
||||
changeNode1.error.called.should.be.true();
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
},50);
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using flow context with jsonata', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$flowContext(\"foo\")","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"},{"id":"flow","type":"tab"}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
changeNode1.context().flow.set("foo","bar");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.payload.should.eql("bar");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.receive({payload:"Hello World!"});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using global context with jsonata', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$globalContext(\"foo\")","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"},{"id":"flow","type":"tab"}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
changeNode1.context().global.set("foo","bar");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.payload.should.eql("bar");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.receive({payload:"Hello World!"});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using persistable flow context with jsonata', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$flowContext(\"foo\",\"memory1\")","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"},{"id":"flow","type":"tab"}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.payload.should.eql("bar");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().flow.set("foo","bar","memory1",function(err){
|
||||
if(err){
|
||||
done(err);
|
||||
}else{
|
||||
changeNode1.context().flow.set("foo","error!");
|
||||
changeNode1.receive({payload:"Hello World!"});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using persistable global context with jsonata', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$globalContext(\"foo\",\"memory1\")","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"},{"id":"flow","type":"tab"}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.payload.should.eql("bar");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().global.set("foo","bar","memory1",function(err){
|
||||
if(err){
|
||||
done(err);
|
||||
}else{
|
||||
changeNode1.context().global.set("foo","error!");
|
||||
changeNode1.receive({payload:"Hello World!"});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
describe('#change', function() {
|
||||
it('changes the value of the message property', function(done) {
|
||||
@@ -693,6 +898,28 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using persistable flow context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"#:(memory1)::topic","to":"123","fromt":"flow","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.payload.should.equal("abc123abc");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().flow.set("topic","ABC","memory1", function (err) {
|
||||
changeNode1.receive({payload:"abcABCabc"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using global context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"topic","to":"123","fromt":"global","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -712,6 +939,28 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using persistable global context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"#:(memory1)::topic","to":"123","fromt":"global","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.payload.should.equal("abc123abc");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().global.set("topic","ABC","memory1",function (err) {
|
||||
changeNode1.receive({payload:"abcABCabc"});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the number using global context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"topic","to":"ABC","fromt":"global","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -731,6 +980,28 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the number using persistable global context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"#:(memory1)::topic","to":"ABC","fromt":"global","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.payload.should.equal("ABC");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().global.set("topic",123,"memory1",function (err) {
|
||||
changeNode1.receive({payload:123});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using number - string payload', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"123","to":"456","fromt":"num","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -822,6 +1093,30 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value of the persistable global context', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "global", "from": "Hello", "fromt": "str", "to": "Goodbye", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
helperNode1.context().global.get("payload","memory1", function (err, val) {
|
||||
val.should.equal("Goodbye World!");
|
||||
done();
|
||||
});
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().global.set("payload","Hello World!","memory1",function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value and doesnt change type of the flow context for partial match', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "flow", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"}];
|
||||
@@ -842,6 +1137,31 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value and doesnt change type of the persistable flow context for partial match', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "flow", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
helperNode1.context().flow.get("payload","memory1",function (err, val) {
|
||||
val.should.equal("Change456Me");
|
||||
val.should.be.a.String();
|
||||
done();
|
||||
});
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().flow.set("payload","Change123Me","memory1",function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value and type of the flow context if a complete match', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "flow", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"}];
|
||||
@@ -862,6 +1182,31 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value and type of the persistable flow context if a complete match', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "flow", "from": "123", "fromt": "str", "to": "456", "tot": "num" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
helperNode1.context().flow.get("payload","memory1",function (err, val) {
|
||||
val.should.be.a.Number();
|
||||
val.should.equal(456);
|
||||
done();
|
||||
});
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().flow.set("payload","123","memory1",function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using number - number flow context', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "flow", "from": "123", "fromt": "num", "to": "abc", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"}];
|
||||
@@ -881,6 +1226,30 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using number - number persistable flow context', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "flow", "from": "123", "fromt": "num", "to": "abc", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
helperNode1.context().flow.get("payload","memory1",function (err, val) {
|
||||
val.should.equal("abc");
|
||||
done();
|
||||
});
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().flow.set("payload",123,"memory1",function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using boolean - boolean flow context', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "payload", "pt": "flow", "from": "true", "fromt": "bool", "to": "abc", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"}];
|
||||
@@ -900,6 +1269,49 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('changes the value using boolean - boolean persistable flow context', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "change", "p": "#:(memory1)::payload", "pt": "flow", "from": "true", "fromt": "bool", "to": "abc", "tot": "str" }],"reg":false,"name":"changeNode","wires":[["helperNode1"]],"z":"flow"},
|
||||
{id:"helperNode1", type:"helper", wires:[],"z":"flow"}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
helperNode1.context().flow.get("payload","memory1",function (err, val) {
|
||||
val.should.equal("abc");
|
||||
done();
|
||||
});
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().flow.set("payload",true,"memory1",function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('reports invalid fromValue', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"null","fromt":"msg","to":"abc","tot":"str"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
setTimeout(function() {
|
||||
var logEvents = helper.log().args.filter(function (evt) {
|
||||
return evt[0].type == "change";
|
||||
});
|
||||
logEvents.should.have.length(1);
|
||||
var msg = logEvents[0][0];
|
||||
msg.should.have.property('level', helper.log().ERROR);
|
||||
msg.should.have.property('id', 'changeNode1');
|
||||
done();
|
||||
},25);
|
||||
changeNode1.receive({payload:"",null:null});
|
||||
});
|
||||
});
|
||||
|
||||
describe('env var', function() {
|
||||
before(function() {
|
||||
process.env.NR_TEST_A = 'foo';
|
||||
@@ -966,6 +1378,30 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('deletes the value of persistable global context property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change",rules:[{ "t": "delete", "p": "#:(memory1)::globalValue", "pt": "global"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
changeNode1.context().global.get("globalValue","memory1",function(err,val) {
|
||||
should.equal(undefined);
|
||||
done();
|
||||
});
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
changeNode1.context().global.set("globalValue","Hello World!","memory1",function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('deletes the value of a multi-level message property', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change","action":"delete","property":"foo.bar","from":"","to":"","reg":false,"name":"changeNode","wires":[["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper", wires:[]}];
|
||||
@@ -1133,6 +1569,7 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('applies multiple rules in order', function(done) {
|
||||
var flow = [{"id":"changeNode1","type":"change","wires":[["helperNode1"]],
|
||||
rules:[
|
||||
@@ -1157,5 +1594,101 @@ describe('change Node', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can access two persistable flow context property', function(done) {
|
||||
var flow = [{"id":"changeNode1", "z":"t1", "type":"change",
|
||||
"wires":[["helperNode1"]],
|
||||
rules:[
|
||||
{"t":"set", "p":"val0", "to":"#:(memory0)::val", "tot":"flow"},
|
||||
{"t":"set", "p":"val1", "to":"#:(memory1)::val", "tot":"flow"}
|
||||
]},
|
||||
{id:"helperNode1", "z":"t1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("val0", "foo");
|
||||
msg.should.have.property("val1", "bar");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var flow = changeNode1.context().flow;
|
||||
flow.set("val", "foo", "memory0", function (err) {
|
||||
flow.set("val", "bar", "memory1", function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can access two persistable global context property', function(done) {
|
||||
var flow = [{"id":"changeNode1", "z":"t1", "type":"change",
|
||||
"wires":[["helperNode1"]],
|
||||
rules:[
|
||||
{"t":"set", "p":"val0", "to":"#:(memory0)::val", "tot":"global"},
|
||||
{"t":"set", "p":"val1", "to":"#:(memory1)::val", "tot":"global"}
|
||||
]},
|
||||
{id:"helperNode1", "z":"t1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("val0", "foo");
|
||||
msg.should.have.property("val1", "bar");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var global = changeNode1.context().global;
|
||||
global.set("val", "foo", "memory0", function (err) {
|
||||
global.set("val", "bar", "memory1", function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can access persistable global & flow context property', function(done) {
|
||||
var flow = [{"id":"changeNode1", "z":"t1", "type":"change",
|
||||
"wires":[["helperNode1"]],
|
||||
rules:[
|
||||
{"t":"set", "p":"val0", "to":"#:(memory0)::val", "tot":"flow"},
|
||||
{"t":"set", "p":"val1", "to":"#:(memory1)::val", "tot":"global"}
|
||||
]},
|
||||
{id:"helperNode1", "z":"t1", type:"helper", wires:[]}];
|
||||
helper.load(changeNode, flow, function() {
|
||||
initContext(function () {
|
||||
var changeNode1 = helper.getNode("changeNode1");
|
||||
var helperNode1 = helper.getNode("helperNode1");
|
||||
helperNode1.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("val0", "foo");
|
||||
msg.should.have.property("val1", "bar");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var context = changeNode1.context();
|
||||
var flow = context.flow;
|
||||
var global = context.global;
|
||||
flow.set("val", "foo", "memory0", function (err) {
|
||||
global.set("val", "bar", "memory1", function (err) {
|
||||
changeNode1.receive({payload:""});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@@ -19,6 +19,9 @@ var splitNode = require("../../../../nodes/core/logic/17-split.js");
|
||||
var joinNode = require("../../../../nodes/core/logic/17-split.js");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
var RED = require("../../../../red/red.js");
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
|
||||
var TimeoutForErrorCase = 20;
|
||||
|
||||
describe('SPLIT node', function() {
|
||||
|
||||
@@ -264,21 +267,156 @@ describe('SPLIT node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle invalid spltType (not an array)', function (done) {
|
||||
var flow = [{ id: "sn1", type: "split", splt: "1", spltType: "bin", wires: [["sn2"]] },
|
||||
{ id: "sn2", type: "helper" }];
|
||||
helper.load(splitNode, flow, function () {
|
||||
var sn1 = helper.getNode("sn1");
|
||||
var sn2 = helper.getNode("sn2");
|
||||
setTimeout(function () {
|
||||
done();
|
||||
}, TimeoutForErrorCase);
|
||||
sn2.on("input", function (msg) {
|
||||
done(new Error("This path does not go through."));
|
||||
});
|
||||
sn1.receive({ payload: "123" });
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle invalid splt length', function (done) {
|
||||
var flow = [{ id: "sn1", type: "split", splt: 0, spltType: "len", wires: [["sn2"]] },
|
||||
{ id: "sn2", type: "helper" }];
|
||||
helper.load(splitNode, flow, function () {
|
||||
var sn1 = helper.getNode("sn1");
|
||||
var sn2 = helper.getNode("sn2");
|
||||
setTimeout(function () {
|
||||
done();
|
||||
}, TimeoutForErrorCase);
|
||||
sn2.on("input", function (msg) {
|
||||
done(new Error("This path does not go through."));
|
||||
});
|
||||
sn1.receive({ payload: "123" });
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle invalid array splt length', function (done) {
|
||||
var flow = [{ id: "sn1", type: "split", arraySplt: 0, arraySpltType: "len", wires: [["sn2"]] },
|
||||
{ id: "sn2", type: "helper" }];
|
||||
helper.load(splitNode, flow, function () {
|
||||
var sn1 = helper.getNode("sn1");
|
||||
var sn2 = helper.getNode("sn2");
|
||||
setTimeout(function () {
|
||||
done();
|
||||
}, TimeoutForErrorCase);
|
||||
sn2.on("input", function (msg) {
|
||||
done(new Error("This path does not go through."));
|
||||
});
|
||||
sn1.receive({ payload: "123" });
|
||||
});
|
||||
});
|
||||
|
||||
it('should ceil count value when msg.payload type is string', function (done) {
|
||||
var flow = [{ id: "sn1", type: "split", splt: "2", spltType: "len", wires: [["sn2"]] },
|
||||
{ id: "sn2", type: "helper" }];
|
||||
helper.load(splitNode, flow, function () {
|
||||
var sn1 = helper.getNode("sn1");
|
||||
var sn2 = helper.getNode("sn2");
|
||||
sn2.on("input", function (msg) {
|
||||
msg.should.have.property("parts");
|
||||
msg.parts.should.have.property("count", 2);
|
||||
msg.parts.should.have.property("index");
|
||||
if (msg.parts.index === 0) { msg.payload.length.should.equal(2); }
|
||||
if (msg.parts.index === 1) { msg.payload.length.should.equal(1); done(); }
|
||||
});
|
||||
sn1.receive({ payload: "123" });
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle spltBufferString value of undefined', function (done) {
|
||||
var flow = [{ id: "sn1", type: "split", wires: [["sn2"]], splt: "[52]", spltType: "bin" },
|
||||
{ id: "sn2", type: "helper" }];
|
||||
helper.load(splitNode, flow, function () {
|
||||
var sn1 = helper.getNode("sn1");
|
||||
var sn2 = helper.getNode("sn2");
|
||||
sn2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("parts");
|
||||
msg.parts.should.have.property("index");
|
||||
if (msg.parts.index === 0) { msg.payload.toString().should.equal("123"); done(); }
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
sn1.receive({ payload: "123" });
|
||||
});
|
||||
});
|
||||
|
||||
it('should ceil count value when msg.payload type is Buffer', function (done) {
|
||||
var flow = [{ id: "sn1", type: "split", splt: "2", spltType: "len", wires: [["sn2"]] },
|
||||
{ id: "sn2", type: "helper" }];
|
||||
helper.load(splitNode, flow, function () {
|
||||
var sn1 = helper.getNode("sn1");
|
||||
var sn2 = helper.getNode("sn2");
|
||||
sn2.on("input", function (msg) {
|
||||
msg.should.have.property("parts");
|
||||
msg.parts.should.have.property("count", 2);
|
||||
msg.parts.should.have.property("index");
|
||||
if (msg.parts.index === 0) { msg.payload.length.should.equal(2); }
|
||||
if (msg.parts.index === 1) { msg.payload.length.should.equal(1); done(); }
|
||||
});
|
||||
var b = new Buffer.from("123");
|
||||
sn1.receive({ payload: b });
|
||||
});
|
||||
});
|
||||
|
||||
it('should set msg.parts.ch when node.spltType is str', function (done) {
|
||||
var flow = [{ id: "sn1", type: "split", splt: "2", spltType: "str", stream: false, wires: [["sn2"]] },
|
||||
{ id: "sn2", type: "helper" }];
|
||||
helper.load(splitNode, flow, function () {
|
||||
var sn1 = helper.getNode("sn1");
|
||||
var sn2 = helper.getNode("sn2");
|
||||
sn2.on("input", function (msg) {
|
||||
msg.should.have.property("parts");
|
||||
msg.parts.should.have.property("count", 2);
|
||||
msg.parts.should.have.property("index");
|
||||
if (msg.parts.index === 0) { msg.payload.length.should.equal(2); }
|
||||
if (msg.parts.index === 1) { msg.payload.length.should.equal(1); done(); }
|
||||
});
|
||||
var b = new Buffer.from("123");
|
||||
sn1.receive({ payload: b });
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('JOIN node', function() {
|
||||
|
||||
before(function(done) {
|
||||
beforeEach(function(done) {
|
||||
helper.startServer(done);
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
helper.stopServer(done);
|
||||
});
|
||||
function initContext(done) {
|
||||
Context.init({
|
||||
contextStorage: {
|
||||
memory: {
|
||||
module: "memory"
|
||||
}
|
||||
}
|
||||
});
|
||||
Context.load().then(function () {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
helper.unload();
|
||||
RED.settings.nodeMessageBufferMaxLength = 0;
|
||||
afterEach(function(done) {
|
||||
helper.unload().then(function(){
|
||||
return Context.clean({allNodes:{}});
|
||||
}).then(function(){
|
||||
return Context.close();
|
||||
}).then(function(){
|
||||
RED.settings.nodeMessageBufferMaxLength = 0;
|
||||
helper.stopServer(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should be loaded', function(done) {
|
||||
@@ -696,6 +834,57 @@ describe('JOIN node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should manually join things into an array, send when told complete', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:1, mode:"custom", build:"array"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.be.an.Array();
|
||||
msg.payload.length.should.equal(3);
|
||||
msg.payload[0].should.equal(1);
|
||||
msg.payload[1].should.equal(2);
|
||||
msg.payload[2].should.equal(3);
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.receive({payload:1, topic:"A"});
|
||||
n1.receive({payload:2, topic:"B"});
|
||||
n1.receive({payload:3, topic:"C"});
|
||||
n1.receive({complete:true});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should manually join things into an object, send when told complete', function(done) {
|
||||
var flow = [{id:"n1", type:"join", wires:[["n2"]], timeout:1, mode:"custom", build:"object"},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.be.an.Object();
|
||||
Object.keys(msg.payload).length.should.equal(3);
|
||||
msg.payload.A.should.equal(1);
|
||||
msg.payload.B.should.equal(2);
|
||||
msg.payload.C.should.equal(3);
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.receive({payload:1, topic:"A"});
|
||||
n1.receive({payload:2, topic:"B"});
|
||||
n1.receive({payload:3, topic:"C"});
|
||||
n1.receive({complete:true});
|
||||
});
|
||||
});
|
||||
|
||||
it('should join split strings back into a word', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"auto", wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
@@ -739,7 +928,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should redece messages', function(done) {
|
||||
it('should reduce messages', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$A+payload",
|
||||
@@ -767,7 +956,137 @@ describe('JOIN node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should redece messages using $I', function(done) {
|
||||
it('should reduce messages - count only in last part', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$A+payload",
|
||||
reduceInit:"0",
|
||||
reduceInitType:"num",
|
||||
reduceFixup:undefined,
|
||||
wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.equal(10);
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.receive({payload:3, parts:{index:2, id:222}});
|
||||
n1.receive({payload:2, parts:{index:1, id:222}});
|
||||
n1.receive({payload:4, parts:{index:3, count:4,id:222}});
|
||||
n1.receive({payload:1, parts:{index:0, id:222}});
|
||||
});
|
||||
});
|
||||
|
||||
function checkInitTypes(itype, ival, rval, initializer, checker, done) {
|
||||
var flow = [{id:"n1", z:"f0", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$A",
|
||||
reduceInit:ival,
|
||||
reduceInitType:itype,
|
||||
reduceFixup:undefined,
|
||||
wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
if (!initializer) {
|
||||
initializer = (node, cb) => {
|
||||
cb();
|
||||
};
|
||||
}
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
initializer(n1, function () {
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
checker(msg.payload, rval);
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:222}});
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:222}});
|
||||
n1.receive({payload:4, parts:{index:3, count:4, id:222}});
|
||||
n1.receive({payload:1, parts:{index:0, count:4, id:222}});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function checkInitTypesSimple(itype, val, done) {
|
||||
checkInitTypes(itype, val, val, undefined, should.equal, done);
|
||||
}
|
||||
|
||||
function checkInitTypesComplex(itype, ival, rval, done) {
|
||||
checkInitTypes(itype, ival, rval, undefined, should.deepEqual, done);
|
||||
}
|
||||
|
||||
it('should reduce messages with init types (str)', function(done) {
|
||||
checkInitTypesSimple('str', "xyz", done);
|
||||
});
|
||||
|
||||
it('should reduce messages with init types (num)', function(done) {
|
||||
checkInitTypesSimple('num', 10, done);
|
||||
});
|
||||
|
||||
it('should reduce messages with init types (bool)', function(done) {
|
||||
checkInitTypesSimple('bool', true, done);
|
||||
});
|
||||
|
||||
it('should reduce messages with init types (json)', function(done) {
|
||||
var ival = '{"x":"vx", "y":"vy", "z":"vz"}';
|
||||
var rval = JSON.parse(ival);
|
||||
checkInitTypesComplex('json', ival, rval, done);
|
||||
});
|
||||
|
||||
it('should reduce messages with init types (bin)', function(done) {
|
||||
var ival = "[1,2,3]";
|
||||
var rval = Buffer.from(JSON.parse(ival));
|
||||
checkInitTypesComplex('bin', ival, rval, done);
|
||||
});
|
||||
|
||||
it('should reduce messages with init types (JSONata)', function(done) {
|
||||
var ival = "1+2+3";
|
||||
var rval = 6;
|
||||
checkInitTypesComplex('jsonata', ival, rval, done);
|
||||
});
|
||||
|
||||
it('should reduce messages with init types (env)', function(done) {
|
||||
function init(node, cb) {
|
||||
process.env.NR_XYZ = "nr_xyz";
|
||||
cb();
|
||||
}
|
||||
function fin(err) {
|
||||
delete process.env.NR_XYZ;
|
||||
done(err);
|
||||
}
|
||||
checkInitTypes('env', "NR_XYZ", "nr_xyz", init, should.equal, fin);
|
||||
});
|
||||
|
||||
it('should reduce messages with init types (flow.name)', function(done) {
|
||||
function init(node, cb) {
|
||||
var context = node.context();
|
||||
context.flow.set("foo", "bar");
|
||||
cb();
|
||||
}
|
||||
checkInitTypes('flow', "foo", "bar", init, should.equal, done);
|
||||
});
|
||||
|
||||
it('should reduce messages with init types (global.name)', function(done) {
|
||||
function init(node, cb) {
|
||||
var context = node.context();
|
||||
context.global.set("foo", "bar");
|
||||
cb();
|
||||
}
|
||||
checkInitTypes('global', "foo", "bar", init, should.equal, done);
|
||||
});
|
||||
|
||||
it('should reduce messages using $I', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$A+$I",
|
||||
@@ -795,7 +1114,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should redece messages with fixup', function(done) {
|
||||
it('should reduce messages with fixup', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$A+payload",
|
||||
@@ -824,7 +1143,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should redece messages (left)', function(done) {
|
||||
it('should reduce messages (left)', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"'(' & $A & '+' & payload & ')'",
|
||||
@@ -853,7 +1172,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should redece messages (right)', function(done) {
|
||||
it('should reduce messages (right)', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:true,
|
||||
reduceExp:"'(' & $A & '+' & payload & ')'",
|
||||
@@ -882,7 +1201,7 @@ describe('JOIN node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should redece messages with array result', function(done) {
|
||||
it('should reduce messages with array result', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$append($A,[payload])",
|
||||
@@ -942,7 +1261,7 @@ describe('JOIN node', function() {
|
||||
evt.should.have.property('type', "join");
|
||||
evt.should.have.property('msg', "join.too-many");
|
||||
done();
|
||||
}, 150);
|
||||
}, TimeoutForErrorCase);
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:222}});
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:222}});
|
||||
n1.receive({payload:4, parts:{index:3, count:4, id:222}});
|
||||
@@ -950,4 +1269,320 @@ describe('JOIN node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should reduce messages with flow context', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$A+(payload*$flowContext(\"two\"))",
|
||||
reduceInit:"$flowContext(\"one\")",
|
||||
reduceInitType:"jsonata",
|
||||
reduceFixup:"$A*$flowContext(\"three\")",
|
||||
wires:[["n2"]],z:"flow"},
|
||||
{id:"n2", type:"helper",z:"flow"},
|
||||
{id:"flow", type:"tab"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.equal(((((1+1*2)+2*2)+3*2)+4*2)*3);
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.context().flow.set("one",1);
|
||||
n1.context().flow.set("two",2);
|
||||
n1.context().flow.set("three",3);
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:222}});
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:222}});
|
||||
n1.receive({payload:4, parts:{index:3, count:4, id:222}});
|
||||
n1.receive({payload:1, parts:{index:0, count:4, id:222}});
|
||||
});
|
||||
});
|
||||
|
||||
it('should reduce messages with global context', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$A+(payload/$globalContext(\"two\"))",
|
||||
reduceInit:"$globalContext(\"one\")",
|
||||
reduceInitType:"jsonata",
|
||||
reduceFixup:"$A*$globalContext(\"three\")",
|
||||
wires:[["n2"]],z:"flow"},
|
||||
{id:"n2", type:"helper",z:"flow"},
|
||||
{id:"flow", type:"tab"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.equal(((((1+1/2)+2/2)+3/2)+4/2)*3);
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.context().global.set("one",1);
|
||||
n1.context().global.set("two",2);
|
||||
n1.context().global.set("three",3);
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:222}});
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:222}});
|
||||
n1.receive({payload:4, parts:{index:3, count:4, id:222}});
|
||||
n1.receive({payload:1, parts:{index:0, count:4, id:222}});
|
||||
});
|
||||
});
|
||||
|
||||
it('should reduce messages with persistable flow context', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$A+(payload*$flowContext(\"two\",\"memory\"))",
|
||||
reduceInit:"$flowContext(\"one\",\"memory\")",
|
||||
reduceInitType:"jsonata",
|
||||
reduceFixup:"$A*$flowContext(\"three\",\"memory\")",
|
||||
wires:[["n2"]],z:"flow"},
|
||||
{id:"n2", type:"helper",z:"flow"},
|
||||
{id:"flow", type:"tab"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
try {
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.equal(((((1+1*2)+2*2)+3*2)+4*2)*3);
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.context().flow.set(["one","two","three"],[1,2,3],"memory",function(err){
|
||||
if(err){
|
||||
done(err);
|
||||
} else{
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:222}});
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:222}});
|
||||
n1.receive({payload:4, parts:{index:3, count:4, id:222}});
|
||||
n1.receive({payload:1, parts:{index:0, count:4, id:222}});
|
||||
}
|
||||
});
|
||||
}catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should reduce messages with persistable global context', function(done) {
|
||||
var flow = [{id:"n1", type:"join", mode:"reduce",
|
||||
reduceRight:false,
|
||||
reduceExp:"$A+(payload/$globalContext(\"two\",\"memory\"))",
|
||||
reduceInit:"$globalContext(\"one\",\"memory\")",
|
||||
reduceInitType:"jsonata",
|
||||
reduceFixup:"$A*$globalContext(\"three\",\"memory\")",
|
||||
wires:[["n2"]],z:"flow"},
|
||||
{id:"n2", type:"helper",z:"flow"},
|
||||
{id:"flow", type:"tab"}];
|
||||
helper.load(joinNode, flow, function() {
|
||||
initContext(function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.equal(((((1+1/2)+2/2)+3/2)+4/2)*3);
|
||||
done();
|
||||
}
|
||||
catch(e) { done(e); }
|
||||
});
|
||||
n1.context().global.set(["one","two","three"],[1,2,3],"memory",function(err){
|
||||
if(err){
|
||||
done(err);
|
||||
} else{
|
||||
n1.receive({payload:3, parts:{index:2, count:4, id:222}});
|
||||
n1.receive({payload:2, parts:{index:1, count:4, id:222}});
|
||||
n1.receive({payload:4, parts:{index:3, count:4, id:222}});
|
||||
n1.receive({payload:1, parts:{index:0, count:4, id:222}});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle invalid JSONata reduce expression - syntax error"', function (done) {
|
||||
var flow = [{
|
||||
id: "n1", type: "join", mode: "reduce",
|
||||
reduceRight: false,
|
||||
reduceExp: "invalid expr",
|
||||
reduceInit: "0",
|
||||
reduceInitType: "num",
|
||||
reduceFixup: undefined,
|
||||
wires: [["n2"]]
|
||||
},
|
||||
{ id: "n2", type: "helper" }];
|
||||
helper.load(joinNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
setTimeout(function () {
|
||||
done();
|
||||
}, TimeoutForErrorCase);
|
||||
n2.on("input", function (msg) {
|
||||
done(new Error("This path does not go through."));
|
||||
});
|
||||
n1.receive({ payload: "A", parts: { id: 1, type: "string", ch: ",", index: 0, count: 1 } });
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle invalid JSONata reduce expression - runtime error"', function (done) {
|
||||
var flow = [{
|
||||
id: "n1", type: "join", mode: "reduce",
|
||||
reduceRight: false,
|
||||
reduceExp: "$uknown()",
|
||||
reduceInit: "0",
|
||||
reduceInitType: "num",
|
||||
reduceFixup: undefined,
|
||||
wires: [["n2"]]
|
||||
},
|
||||
{ id: "n2", type: "helper" }];
|
||||
helper.load(joinNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
setTimeout(function () {
|
||||
done();
|
||||
}, TimeoutForErrorCase);
|
||||
n2.on("input", function (msg) {
|
||||
done(new Error("This path does not go through."));
|
||||
});
|
||||
n1.receive({ payload: "A", parts: { id: 1, type: "string", ch: ",", index: 0, count: 1 } });
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle invalid JSONata fixup expression - syntax err"', function (done) {
|
||||
var flow = [{
|
||||
id: "n1", type: "join", mode: "reduce",
|
||||
reduceRight: false,
|
||||
reduceExp: "$A",
|
||||
reduceInit: "0",
|
||||
reduceInitType: "num",
|
||||
reduceFixup: "invalid expr",
|
||||
wires: [["n2"]]
|
||||
},
|
||||
{ id: "n2", type: "helper" }];
|
||||
helper.load(joinNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
setTimeout(function () {
|
||||
done();
|
||||
}, TimeoutForErrorCase);
|
||||
n2.on("input", function (msg) {
|
||||
done(new Error("This path does not go through."));
|
||||
});
|
||||
n1.receive({ payload: "A", parts: { id: 1, type: "string", ch: ",", index: 0, count: 1 } });
|
||||
});
|
||||
});
|
||||
it('should handle invalid JSONata fixup expression - runtime err"', function (done) {
|
||||
var flow = [{
|
||||
id: "n1", type: "join", mode: "reduce",
|
||||
reduceRight: false,
|
||||
reduceExp: "$A",
|
||||
reduceInit: "0",
|
||||
reduceInitType: "num",
|
||||
reduceFixup: "$unknown()",
|
||||
wires: [["n2"]]
|
||||
},
|
||||
{ id: "n2", type: "helper" }];
|
||||
helper.load(joinNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
setTimeout(function () {
|
||||
done();
|
||||
}, TimeoutForErrorCase);
|
||||
n2.on("input", function (msg) {
|
||||
done(new Error("This path does not go through."));
|
||||
});
|
||||
n1.receive({ payload: "A", parts: { id: 1, type: "string", ch: ",", index: 0, count: 1 } });
|
||||
});
|
||||
});
|
||||
|
||||
it('should concat payload when group.type is array', function (done) {
|
||||
var flow = [{ id: "n1", type: "join", wires: [["n2"]], build: "array", mode: "auto" },
|
||||
{ id: "n2", type: "helper" }];
|
||||
helper.load(joinNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.should.be.an.Array();
|
||||
msg.payload[0].should.equal("ab");
|
||||
msg.payload[1].should.equal("cd");
|
||||
msg.payload[2].should.equal("ef");
|
||||
done();
|
||||
}
|
||||
catch (e) { done(e); }
|
||||
});
|
||||
n1.receive({ payload: "ab", parts: { id: 1, type: "array", ch: ",", index: 0, count: 3, len:2}});
|
||||
n1.receive({ payload: "cd", parts: { id: 1, type: "array", ch: ",", index: 1, count: 3, len:2}});
|
||||
n1.receive({ payload: "ef", parts: { id: 1, type: "array", ch: ",", index: 2, count: 3, len:2}});
|
||||
});
|
||||
});
|
||||
|
||||
it('should concat payload when group.type is buffer and group.joinChar is undefined', function (done) {
|
||||
var flow = [{ id: "n1", type: "join", wires: [["n2"]], joiner: ",", build: "buffer", mode: "auto" },
|
||||
{ id: "n2", type: "helper" }];
|
||||
helper.load(joinNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
Buffer.isBuffer(msg.payload).should.be.true();
|
||||
msg.payload.toString().should.equal("ABC");
|
||||
done();
|
||||
}
|
||||
catch (e) { done(e); }
|
||||
});
|
||||
n1.receive({ payload: Buffer.from("A"), parts: { id: 1, type: "buffer", index: 0, count: 3 } });
|
||||
n1.receive({ payload: Buffer.from("B"), parts: { id: 1, type: "buffer", index: 1, count: 3 } });
|
||||
n1.receive({ payload: Buffer.from("C"), parts: { id: 1, type: "buffer", index: 2, count: 3 } });
|
||||
});
|
||||
});
|
||||
|
||||
it('should concat payload when group.type is string and group.joinChar is not string', function (done) {
|
||||
var flow = [{ id: "n1", type: "join", wires: [["n2"]], joiner: ",", build: "buffer", mode: "auto" },
|
||||
{ id: "n2", type: "helper" }];
|
||||
helper.load(joinNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
msg.payload.toString().should.equal("A0B0C");
|
||||
done();
|
||||
}
|
||||
catch (e) { done(e); }
|
||||
});
|
||||
n1.receive({ payload: Buffer.from("A"), parts: { id: 1, type: "string", ch: Buffer.from("0"), index: 0, count: 3 } });
|
||||
n1.receive({ payload: Buffer.from("B"), parts: { id: 1, type: "string", ch: Buffer.from("0"), index: 1, count: 3 } });
|
||||
n1.receive({ payload: Buffer.from("C"), parts: { id: 1, type: "string", ch: Buffer.from("0"), index: 2, count: 3 } });
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle msg.parts property when mode is auto and parts or id are missing', function (done) {
|
||||
var flow = [{ id: "n1", type: "join", wires: [["n2"]], joiner: "[44]", joinerType: "bin", build: "string", mode: "auto" },
|
||||
{ id: "n2", type: "helper" }];
|
||||
helper.load(joinNode, flow, function () {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n2.on("input", function (msg) {
|
||||
done(new Error("This path does not go through."));
|
||||
});
|
||||
n1.receive({ payload: "A", parts: { type: "string", ch: ",", index: 0, count: 2 } });
|
||||
n1.receive({ payload: "B", parts: { type: "string", ch: ",", index: 1, count: 2 } });
|
||||
setTimeout(function () {
|
||||
done();
|
||||
}, TimeoutForErrorCase);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -18,20 +18,32 @@ var should = require("should");
|
||||
var sortNode = require("../../../../nodes/core/logic/18-sort.js");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
var RED = require("../../../../red/red.js");
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
|
||||
describe('SORT node', function() {
|
||||
|
||||
before(function(done) {
|
||||
beforeEach(function(done) {
|
||||
helper.startServer(done);
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
helper.stopServer(done);
|
||||
});
|
||||
function initContext(done) {
|
||||
Context.init({
|
||||
contextStorage: {
|
||||
memory: {
|
||||
module: "memory"
|
||||
}
|
||||
}
|
||||
});
|
||||
Context.load().then(function () {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
helper.unload();
|
||||
RED.settings.nodeMessageBufferMaxLength = 0;
|
||||
afterEach(function(done) {
|
||||
helper.unload().then(function(){
|
||||
RED.settings.nodeMessageBufferMaxLength = 0;
|
||||
helper.stopServer(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should be loaded', function(done) {
|
||||
@@ -48,8 +60,8 @@ describe('SORT node', function() {
|
||||
var sort = flow[0];
|
||||
sort.target = target;
|
||||
sort.targetType = "msg";
|
||||
sort.msgKey = key;
|
||||
sort.msgKeyType = key_type;
|
||||
sort.msgKey = key;
|
||||
sort.msgKeyType = key_type;
|
||||
helper.load(sortNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
@@ -214,8 +226,6 @@ describe('SORT node', function() {
|
||||
});
|
||||
})();
|
||||
|
||||
return;
|
||||
|
||||
(function() {
|
||||
var flow = [{id:"n1", type:"sort", order:"descending", as_num:false, wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
@@ -229,6 +239,134 @@ describe('SORT node', function() {
|
||||
});
|
||||
})();
|
||||
|
||||
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"},
|
||||
{id:"flow", type:"tab"}];
|
||||
var data_in = [ "first", "second", "third", "fourth" ];
|
||||
var data_out = [ "second", "third", "first", "fourth" ];
|
||||
helper.load(sortNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context()["flow"].set("first","3");
|
||||
n1.context()["flow"].set("second","1");
|
||||
n1.context()["flow"].set("third","2");
|
||||
n1.context()["flow"].set("fourth","4");
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property("data");
|
||||
var data = msg["data"];
|
||||
data.length.should.equal(data_out.length);
|
||||
for(var i = 0; i < data_out.length; i++) {
|
||||
data[i].should.equal(data_out[i]);
|
||||
}
|
||||
done();
|
||||
});
|
||||
var msg = {};
|
||||
msg["data"] = data_in;
|
||||
n1.receive(msg);
|
||||
});
|
||||
});
|
||||
|
||||
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"},
|
||||
{id:"n2", type:"helper",z:"flow"},
|
||||
{id:"flow", type:"tab"}];
|
||||
var data_in = [ "first", "second", "third", "fourth" ];
|
||||
var data_out = [ "second", "fourth", "third", "first" ];
|
||||
helper.load(sortNode, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n1.context()["global"].set("first","4");
|
||||
n1.context()["global"].set("second","1");
|
||||
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();
|
||||
}
|
||||
});
|
||||
var len = data_in.length;
|
||||
for(var i = 0; i < len; i++) {
|
||||
var parts = { id: "X", index: i, count: len };
|
||||
var msg = {parts: parts};
|
||||
msg["payload"] = data_in[i];
|
||||
n1.receive(msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should sort payload by persistable context (exp, not number, descending)', function(done) {
|
||||
var flow = [{id:"n1", type:"sort", target:"data", targetType:"msg", msgKey:"$globalContext($,\"memory\")", msgKeyType:"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" ];
|
||||
var data_out = [ "fourth", "first", "third", "second" ];
|
||||
helper.load(sortNode, flow, function() {
|
||||
initContext(function(){
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
n1.context()["global"].set(["first","second","third","fourth"],["3","1","2","4"],"memory",function(){
|
||||
n2.on("input", function(msg) {
|
||||
msg.should.have.property("data");
|
||||
var data = msg["data"];
|
||||
data.length.should.equal(data_out.length);
|
||||
for(var i = 0; i < data_out.length; i++) {
|
||||
data[i].should.equal(data_out[i]);
|
||||
}
|
||||
done();
|
||||
});
|
||||
var msg = {};
|
||||
msg["data"] = data_in;
|
||||
n1.receive(msg);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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"},
|
||||
{id:"n2", type:"helper",z:"flow"},
|
||||
{id:"flow", type:"tab"}];
|
||||
var data_in = [ "first", "second", "third", "fourth" ];
|
||||
var data_out = [ "first", "third", "fourth", "second" ];
|
||||
helper.load(sortNode, flow, function() {
|
||||
initContext(function(){
|
||||
var n1 = helper.getNode("n1");
|
||||
var n2 = helper.getNode("n2");
|
||||
var count = 0;
|
||||
n1.context()["flow"].set(["first","second","third","fourth"],["4","1","3","2"],"memory",function(){
|
||||
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();
|
||||
}
|
||||
});
|
||||
var len = data_in.length;
|
||||
for(var i = 0; i < len; i++) {
|
||||
var parts = { id: "X", index: i, count: len };
|
||||
var msg = {parts: parts};
|
||||
msg["payload"] = data_in[i];
|
||||
n1.receive(msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle JSONata script error', function(done) {
|
||||
var flow = [{id:"n1", type:"sort", order:"ascending", as_num:false, target:"payload", targetType:"seq", seqKey:"$unknown()", seqKeyType:"jsonata", wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
@@ -251,8 +389,6 @@ describe('SORT node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
it('should handle too many pending messages', function(done) {
|
||||
var flow = [{id:"n1", type:"sort", order:"ascending", as_num:false, target:"payload", targetType:"seq", seqKey:"payload", seqKeyType:"msg", wires:[["n2"]]},
|
||||
{id:"n2", type:"helper"}];
|
||||
|
@@ -247,4 +247,85 @@ describe('JSON node', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass an object if provided a valid JSON string and schema', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",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 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 pass a string if provided a valid object and schema', function(done) {
|
||||
var flow = [{id:"jn1",type:"json",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 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 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"}];
|
||||
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 a valid object and invalid 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 = "garbage";
|
||||
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-compile");
|
||||
logEvents[0][0].should.have.a.property('level',helper.log().ERROR);
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -46,82 +46,173 @@ describe('file Nodes', function() {
|
||||
it('should be loaded', function(done) {
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":true}];
|
||||
helper.load(fileNode, flow, function() {
|
||||
var fileNode1 = helper.getNode("fileNode1");
|
||||
fileNode1.should.have.property('name', 'fileNode');
|
||||
done();
|
||||
try {
|
||||
var fileNode1 = helper.getNode("fileNode1");
|
||||
fileNode1.should.have.property('name', 'fileNode');
|
||||
done();
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should write to a file', function(done) {
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":true}];
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":true, wires: [["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
helper.load(fileNode, flow, function() {
|
||||
var n1 = helper.getNode("fileNode1");
|
||||
n1.emit("input", {payload:"test"});
|
||||
setTimeout(function() {
|
||||
var f = fs.readFileSync(fileToTest);
|
||||
f.should.have.length(4);
|
||||
fs.unlinkSync(fileToTest);
|
||||
done();
|
||||
},wait);
|
||||
var n2 = helper.getNode("helperNode1");
|
||||
n2.on("input", function(msg) {
|
||||
try {
|
||||
var f = fs.readFileSync(fileToTest);
|
||||
f.should.have.length(4);
|
||||
fs.unlinkSync(fileToTest);
|
||||
msg.should.have.property("payload", "test");
|
||||
done();
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"test"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should append to a file and add newline', function(done) {
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":false}];
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":false, wires: [["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
try {
|
||||
fs.unlinkSync(fileToTest);
|
||||
}catch(err) {}
|
||||
} catch(err) {
|
||||
}
|
||||
helper.load(fileNode, flow, function() {
|
||||
var n1 = helper.getNode("fileNode1");
|
||||
n1.emit("input", {payload:"test2"}); // string
|
||||
var n2 = helper.getNode("helperNode1");
|
||||
var count = 0;
|
||||
var data = ["test2", true, 999, [2]];
|
||||
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
data.should.containDeep([msg.payload]);
|
||||
if (count === 3) {
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
if (os.type() !== "Windows_NT") {
|
||||
f.should.have.length(19);
|
||||
f.should.equal("test2\ntrue\n999\n[2]\n");
|
||||
}
|
||||
else {
|
||||
f.should.have.length(23);
|
||||
f.should.equal("test2\r\ntrue\r\n999\r\n[2]\r\n");
|
||||
}
|
||||
done();
|
||||
}
|
||||
count++;
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
|
||||
n1.receive({payload:"test2"}); // string
|
||||
setTimeout(function() {
|
||||
n1.emit("input", {payload:true}); // boolean
|
||||
n1.receive({payload:true}); // boolean
|
||||
},30);
|
||||
setTimeout(function() {
|
||||
n1.emit("input", {payload:999}); // number
|
||||
n1.receive({payload:999}); // number
|
||||
},60);
|
||||
setTimeout(function() {
|
||||
n1.emit("input", {payload:[2]}); // object (array)
|
||||
n1.receive({payload:[2]}); // object (array)
|
||||
},90);
|
||||
setTimeout(function() {
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
if (os.type() !== "Windows_NT") {
|
||||
f.should.have.length(19);
|
||||
f.should.equal("test2\ntrue\n999\n[2]\n");
|
||||
}
|
||||
else {
|
||||
f.should.have.length(23);
|
||||
f.should.equal("test2\r\ntrue\r\n999\r\n[2]\r\n");
|
||||
}
|
||||
done();
|
||||
},wait);
|
||||
});
|
||||
});
|
||||
|
||||
it('should append to a file after it has been deleted ', function(done) {
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":false}];
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":false, wires: [["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
try {
|
||||
fs.unlinkSync(fileToTest);
|
||||
} catch(err) {}
|
||||
} catch(err) {
|
||||
}
|
||||
helper.load(fileNode, flow, function() {
|
||||
var n1 = helper.getNode("fileNode1");
|
||||
var n2 = helper.getNode("helperNode1");
|
||||
var data = ["one", "two", "three", "four"];
|
||||
var count = 0;
|
||||
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("payload");
|
||||
data.should.containDeep([msg.payload]);
|
||||
try {
|
||||
if (count === 1) {
|
||||
// Check they got appended as expected
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
f.should.equal("onetwo");
|
||||
|
||||
// Delete the file
|
||||
fs.unlinkSync(fileToTest);
|
||||
setTimeout(function() {
|
||||
// Send two more messages to the file
|
||||
n1.receive({payload:"three"});
|
||||
n1.receive({payload:"four"});
|
||||
}, wait);
|
||||
}
|
||||
if (count === 3) {
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
f.should.equal("threefour");
|
||||
fs.unlinkSync(fileToTest);
|
||||
done();
|
||||
}
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
|
||||
// Send two messages to the file
|
||||
n1.emit("input", {payload:"one"});
|
||||
n1.emit("input", {payload:"two"});
|
||||
setTimeout(function() {
|
||||
n1.receive({payload:"one"});
|
||||
n1.receive({payload:"two"});
|
||||
});
|
||||
});
|
||||
|
||||
it('should append to a file after it has been recreated ', function(done) {
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":false, wires: [["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
try {
|
||||
fs.unlinkSync(fileToTest);
|
||||
} catch(err) {
|
||||
}
|
||||
helper.load(fileNode, flow, function() {
|
||||
var n1 = helper.getNode("fileNode1");
|
||||
var n2 = helper.getNode("helperNode1");
|
||||
var data = ["one", "two", "three", "four"];
|
||||
var count = 0;
|
||||
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
// Check they got appended as expected
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
f.should.equal("onetwo");
|
||||
msg.should.have.property("payload");
|
||||
data.should.containDeep([msg.payload]);
|
||||
if (count == 1) {
|
||||
// Check they got appended as expected
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
f.should.equal("onetwo");
|
||||
|
||||
// Delete the file
|
||||
fs.unlinkSync(fileToTest);
|
||||
|
||||
// Send two more messages to the file
|
||||
n1.emit("input", {payload:"three"});
|
||||
n1.emit("input", {payload:"four"});
|
||||
|
||||
setTimeout(function() {
|
||||
if (os.type() === "Windows_NT") {
|
||||
var dummyFile = path.join(resourcesDir,"50-file-test-dummy.txt");
|
||||
fs.rename(fileToTest, dummyFile, function() {
|
||||
recreateTest(n1, dummyFile);
|
||||
});
|
||||
} else {
|
||||
recreateTest(n1, fileToTest);
|
||||
}
|
||||
}
|
||||
if (count == 3) {
|
||||
// Check the file was updated
|
||||
try {
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
@@ -131,42 +222,16 @@ describe('file Nodes', function() {
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
},wait);
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
},wait);
|
||||
});
|
||||
});
|
||||
|
||||
it('should append to a file after it has been recreated ', function(done) {
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":false}];
|
||||
try {
|
||||
fs.unlinkSync(fileToTest);
|
||||
} catch(err) {}
|
||||
helper.load(fileNode, flow, function() {
|
||||
var n1 = helper.getNode("fileNode1");
|
||||
// Send two messages to the file
|
||||
n1.emit("input", {payload:"one"});
|
||||
n1.emit("input", {payload:"two"});
|
||||
setTimeout(function() {
|
||||
try {
|
||||
// Check they got appended as expected
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
f.should.equal("onetwo");
|
||||
|
||||
if (os.type() === "Windows_NT") {
|
||||
var dummyFile = path.join(resourcesDir,"50-file-test-dummy.txt");
|
||||
fs.rename(fileToTest, dummyFile, function() {
|
||||
recreateTest(n1, dummyFile);
|
||||
});
|
||||
} else {
|
||||
recreateTest(n1, fileToTest);
|
||||
}
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
},wait);
|
||||
count++;
|
||||
});
|
||||
|
||||
// Send two messages to the file
|
||||
n1.receive({payload:"one"});
|
||||
n1.receive({payload:"two"});
|
||||
});
|
||||
|
||||
function recreateTest(n1, fileToDelete) {
|
||||
@@ -177,50 +242,52 @@ describe('file Nodes', function() {
|
||||
fs.writeFileSync(fileToTest,"");
|
||||
|
||||
// Send two more messages to the file
|
||||
n1.emit("input", {payload:"three"});
|
||||
n1.emit("input", {payload:"four"});
|
||||
|
||||
setTimeout(function() {
|
||||
// Check the file was updated
|
||||
try {
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
f.should.equal("threefour");
|
||||
fs.unlinkSync(fileToTest);
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
},wait);
|
||||
n1.receive({payload:"three"});
|
||||
n1.receive({payload:"four"});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('should use msg.filename if filename not set in node', function(done) {
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "appendNewline":true, "overwriteFile":true}];
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "appendNewline":true, "overwriteFile":true, wires: [["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
helper.load(fileNode, flow, function() {
|
||||
var n1 = helper.getNode("fileNode1");
|
||||
n1.emit("input", {payload:"fine", filename:fileToTest});
|
||||
setTimeout(function() {
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
if (os.type() !== "Windows_NT") {
|
||||
f.should.have.length(5);
|
||||
f.should.equal("fine\n");
|
||||
}
|
||||
else {
|
||||
f.should.have.length(6);
|
||||
f.should.equal("fine\r\n");
|
||||
}
|
||||
done();
|
||||
},wait);
|
||||
var n2 = helper.getNode("helperNode1");
|
||||
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
msg.should.have.property("payload", "fine");
|
||||
msg.should.have.property("filename", fileToTest);
|
||||
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
if (os.type() !== "Windows_NT") {
|
||||
f.should.have.length(5);
|
||||
f.should.equal("fine\n");
|
||||
}
|
||||
else {
|
||||
f.should.have.length(6);
|
||||
f.should.equal("fine\r\n");
|
||||
}
|
||||
done();
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
});
|
||||
|
||||
n1.receive({payload:"fine", filename:fileToTest});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to delete the file', function(done) {
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":"delete"}];
|
||||
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":"delete", wires: [["helperNode1"]]},
|
||||
{id:"helperNode1", type:"helper"}];
|
||||
helper.load(fileNode, flow, function() {
|
||||
var n1 = helper.getNode("fileNode1");
|
||||
n1.emit("input", {payload:"fine"});
|
||||
setTimeout(function() {
|
||||
var n2 = helper.getNode("helperNode1");
|
||||
|
||||
n2.on("input", function (msg) {
|
||||
try {
|
||||
var f = fs.readFileSync(fileToTest).toString();
|
||||
f.should.not.equal("fine");
|
||||
@@ -230,7 +297,9 @@ describe('file Nodes', function() {
|
||||
e.code.should.equal("ENOENT");
|
||||
done();
|
||||
}
|
||||
},wait);
|
||||
});
|
||||
|
||||
n1.receive({payload:"fine"});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -394,6 +463,11 @@ describe('file Nodes', function() {
|
||||
});
|
||||
|
||||
it('should try to create a new directory if asked to do so (append)', function(done) {
|
||||
// fs.writeFileSync of afterEach failed on Windows.
|
||||
if (os.type() === "Windows_NT") {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
// Stub file write so we can make writes fail
|
||||
var fileToTest2 = path.join(resourcesDir,"file-out-node","50-file-test-file.txt");
|
||||
var spy = sinon.stub(fs, "ensureDir", function(arg1,arg2,arg3,arg4) { arg2(null); });
|
||||
|
231
test/red/api/admin/context_spec.js
Normal file
231
test/red/api/admin/context_spec.js
Normal file
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var should = require("should");
|
||||
var request = require('supertest');
|
||||
var express = require('express');
|
||||
var bodyParser = require('body-parser');
|
||||
var sinon = require('sinon');
|
||||
var when = require('when');
|
||||
|
||||
var context = require("../../../../red/api/admin/context");
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
var Util = require("../../../../red/runtime/util");
|
||||
|
||||
describe("api/admin/context", function() {
|
||||
var app = undefined;
|
||||
|
||||
before(function (done) {
|
||||
var node_context = undefined;
|
||||
app = express();
|
||||
app.use(bodyParser.json());
|
||||
app.get("/context/:scope(global)", context.get);
|
||||
app.get("/context/:scope(global)/*", context.get);
|
||||
app.get("/context/:scope(node|flow)/:id", context.get);
|
||||
app.get("/context/:scope(node|flow)/:id/*", context.get);
|
||||
|
||||
context.init({
|
||||
settings: {
|
||||
},
|
||||
log:{warn:function(){},_:function(){},audit:function(){}},
|
||||
nodes: {
|
||||
listContextStores: Context.listStores,
|
||||
getContext: Context.get,
|
||||
getNode: function(id) {
|
||||
if (id === 'NID') {
|
||||
return {
|
||||
id: 'NID',
|
||||
context: function () {
|
||||
return node_context;
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
util: Util
|
||||
});
|
||||
|
||||
Context.init({
|
||||
contextStorage: {
|
||||
memory0: {
|
||||
module: "memory"
|
||||
},
|
||||
memory1: {
|
||||
module: "memory"
|
||||
}
|
||||
}
|
||||
});
|
||||
Context.load().then(function () {
|
||||
var ctx = Context.get("NID", "FID");
|
||||
node_context = ctx;
|
||||
ctx.set("foo", "n_v00", "memory0");
|
||||
ctx.set("bar", "n_v01", "memory0");
|
||||
ctx.set("baz", "n_v10", "memory1");
|
||||
ctx.set("bar", "n_v11", "memory1");
|
||||
ctx.flow.set("foo", "f_v00", "memory0");
|
||||
ctx.flow.set("bar", "f_v01", "memory0");
|
||||
ctx.flow.set("baz", "f_v10", "memory1");
|
||||
ctx.flow.set("bar", "f_v11", "memory1");
|
||||
ctx.global.set("foo", "g_v00", "memory0");
|
||||
ctx.global.set("bar", "g_v01", "memory0");
|
||||
ctx.global.set("baz", "g_v10", "memory1");
|
||||
ctx.global.set("bar", "g_v11", "memory1");
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
after(function () {
|
||||
Context.clean({allNodes:{}});
|
||||
Context.close();
|
||||
});
|
||||
|
||||
function check_mem(body, mem, name, val) {
|
||||
var mem0 = body[mem];
|
||||
mem0.should.have.property(name);
|
||||
mem0[name].should.deepEqual(val);
|
||||
}
|
||||
|
||||
function check_scope(scope, prefix, id) {
|
||||
describe('# '+scope, function () {
|
||||
var xid = id ? ("/"+id) : "";
|
||||
|
||||
it('should return '+scope+' contexts', function (done) {
|
||||
request(app)
|
||||
.get('/context/'+scope+xid)
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
var body = res.body;
|
||||
body.should.have.key('memory0', 'memory1');
|
||||
check_mem(body, 'memory0',
|
||||
'foo', {msg:prefix+'_v00', format:'string[5]'});
|
||||
check_mem(body, 'memory0',
|
||||
'bar', {msg:prefix+'_v01', format:'string[5]'});
|
||||
check_mem(body, 'memory1',
|
||||
'baz', {msg:prefix+'_v10', format:'string[5]'});
|
||||
check_mem(body, 'memory1',
|
||||
'bar', {msg:prefix+'_v11', format:'string[5]'});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a value from default '+scope+' context', function (done) {
|
||||
request(app)
|
||||
.get('/context/'+scope+xid+'/foo')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
var body = res.body;
|
||||
body.should.deepEqual({msg: prefix+'_v00', format: 'string[5]'});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a value from specified '+scope+' context', function (done) {
|
||||
request(app)
|
||||
.get('/context/'+scope+xid+'/bar?store=memory1')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
var body = res.body;
|
||||
body.should.deepEqual({msg: prefix+'_v11', format: 'string[5]', store: 'memory1'});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return specified '+scope+' store', function (done) {
|
||||
request(app)
|
||||
.get('/context/'+scope+xid+'?store=memory1')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
var body = res.body;
|
||||
body.should.deepEqual({
|
||||
memory1: {
|
||||
baz: { msg: prefix+'_v10', format: 'string[5]' },
|
||||
bar: { msg: prefix+'_v11', format: 'string[5]' }
|
||||
}
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return undefined for unknown key of default '+scope+' store', function (done) {
|
||||
request(app)
|
||||
.get('/context/'+scope+xid+'/unknown')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
var body = res.body;
|
||||
body.should.deepEqual({msg:'(undefined)', format:'undefined'});
|
||||
done();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('should cause error for unknown '+scope+' store', function (done) {
|
||||
request(app)
|
||||
.get('/context/'+scope+xid+'?store=unknown')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done();
|
||||
}
|
||||
done("unexpected");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
check_scope("global", "g", undefined);
|
||||
check_scope("node", "n", "NID");
|
||||
check_scope("flow", "f", "FID");
|
||||
|
||||
describe("# errors", function () {
|
||||
it('should cause error for unknown scope', function (done) {
|
||||
request(app)
|
||||
.get('/context/scope')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done();
|
||||
}
|
||||
done("unexpected");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
@@ -20,8 +20,7 @@ var express = require('express');
|
||||
var sinon = require('sinon');
|
||||
|
||||
var locales = require("../../../../red/api/editor/locales");
|
||||
var i18n = require("../../../../red/util/i18n");
|
||||
|
||||
var i18n = require("../../../../red/util").i18n;
|
||||
|
||||
describe("api/editor/locales", function() {
|
||||
beforeEach(function() {
|
||||
@@ -31,18 +30,39 @@ describe("api/editor/locales", function() {
|
||||
describe('get named resource catalog',function() {
|
||||
var app;
|
||||
before(function() {
|
||||
// bit of a mess of internal workings
|
||||
// locales.init({
|
||||
// i18n: {
|
||||
// i: {
|
||||
// language: function() { return 'en-US'},
|
||||
// changeLanguage: function(lang,callback) {
|
||||
// if (callback) {
|
||||
// callback();
|
||||
// }
|
||||
// },
|
||||
// getResourceBundle: function(lang, namespace) {
|
||||
// return {namespace:namespace, lang:lang};
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
// });
|
||||
locales.init({});
|
||||
sinon.stub(i18n.i,'lng',function() { return 'en-US'});
|
||||
sinon.stub(i18n.i,'setLng',function(lang,callback) { if (callback) {callback();}});
|
||||
sinon.stub(i18n,'catalog',function(namespace, lang) {return {namespace:namespace, lang:lang};});
|
||||
|
||||
// bit of a mess of internal workings
|
||||
sinon.stub(i18n.i,'changeLanguage',function(lang,callback) { if (callback) {callback();}});
|
||||
if (i18n.i.getResourceBundle) {
|
||||
sinon.stub(i18n.i,'getResourceBundle',function(lang, namespace) {return {namespace:namespace, lang:lang};});
|
||||
} else {
|
||||
// If i18n.init has not been called, then getResourceBundle isn't
|
||||
// defined - so hardcode a stub
|
||||
i18n.i.getResourceBundle = function(lang, namespace) {return {namespace:namespace, lang:lang};};
|
||||
i18n.i.getResourceBundle.restore = function() { delete i18n.i.getResourceBundle };
|
||||
}
|
||||
app = express();
|
||||
app.get(/locales\/(.+)\/?$/,locales.get);
|
||||
});
|
||||
after(function() {
|
||||
i18n.i.lng.restore();
|
||||
i18n.i.setLng.restore();
|
||||
i18n.catalog.restore();
|
||||
i18n.i.changeLanguage.restore();
|
||||
i18n.i.getResourceBundle.restore();
|
||||
})
|
||||
it('returns with default language', function(done) {
|
||||
request(app)
|
||||
|
20
test/red/runtime-api/context_spec.js
Normal file
20
test/red/runtime-api/context_spec.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
describe("runtime-api/context", function() {
|
||||
|
||||
|
||||
});
|
@@ -165,7 +165,7 @@ describe('nodes/registry/installer', function() {
|
||||
});
|
||||
});
|
||||
it("rejects when non-existant path is provided", function(done) {
|
||||
this.timeout(10000);
|
||||
this.timeout(20000);
|
||||
var resourcesDir = path.resolve(path.join(__dirname,"resources","local","TestNodeModule","node_modules","NonExistant"));
|
||||
installer.installModule(resourcesDir).then(function() {
|
||||
done(new Error("Unexpected success"));
|
||||
|
@@ -89,6 +89,8 @@ describe("runtime", function() {
|
||||
var redNodesGetNodeList;
|
||||
var redNodesLoadFlows;
|
||||
var redNodesStartFlows;
|
||||
var redNodesLoadContextsPlugin;
|
||||
|
||||
beforeEach(function() {
|
||||
storageInit = sinon.stub(storage,"init",function(settings) {return Promise.resolve();});
|
||||
redNodesInit = sinon.stub(redNodes,"init", function() {});
|
||||
@@ -96,6 +98,7 @@ describe("runtime", function() {
|
||||
redNodesCleanModuleList = sinon.stub(redNodes,"cleanModuleList",function(){});
|
||||
redNodesLoadFlows = sinon.stub(redNodes,"loadFlows",function() {return Promise.resolve()});
|
||||
redNodesStartFlows = sinon.stub(redNodes,"startFlows",function() {});
|
||||
redNodesLoadContextsPlugin = sinon.stub(redNodes,"loadContextsPlugin",function() {return Promise.resolve()});
|
||||
});
|
||||
afterEach(function() {
|
||||
storageInit.restore();
|
||||
@@ -105,6 +108,7 @@ describe("runtime", function() {
|
||||
redNodesCleanModuleList.restore();
|
||||
redNodesLoadFlows.restore();
|
||||
redNodesStartFlows.restore();
|
||||
redNodesLoadContextsPlugin.restore();
|
||||
});
|
||||
it("reports errored/missing modules",function(done) {
|
||||
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) {
|
||||
@@ -187,7 +191,7 @@ describe("runtime", function() {
|
||||
});
|
||||
|
||||
it("reports runtime metrics",function(done) {
|
||||
var stopFlows = sinon.stub(redNodes,"stopFlows",function() {} );
|
||||
var stopFlows = sinon.stub(redNodes,"stopFlows",function() { return Promise.resolve();} );
|
||||
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
|
||||
var util = mockUtil(true);
|
||||
runtime.init({testSettings: true, runtimeMetricInterval:200, httpAdminRoot:"/", load:function() { return Promise.resolve();}},util);
|
||||
@@ -214,10 +218,19 @@ describe("runtime", function() {
|
||||
|
||||
});
|
||||
|
||||
it("stops components", function() {
|
||||
var stopFlows = sinon.stub(redNodes,"stopFlows",function() {} );
|
||||
runtime.stop();
|
||||
stopFlows.called.should.be.true();
|
||||
stopFlows.restore();
|
||||
it("stops components", function(done) {
|
||||
var stopFlows = sinon.stub(redNodes,"stopFlows",function() { return Promise.resolve();} );
|
||||
var closeContextsPlugin = sinon.stub(redNodes,"closeContextsPlugin",function() { return Promise.resolve();} );
|
||||
runtime.stop().then(function(){
|
||||
stopFlows.called.should.be.true();
|
||||
closeContextsPlugin.called.should.be.true();
|
||||
stopFlows.restore();
|
||||
closeContextsPlugin.restore();
|
||||
done();
|
||||
}).catch(function(err){
|
||||
stopFlows.restore();
|
||||
closeContextsPlugin.restore();
|
||||
return done(err)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
897
test/red/runtime/nodes/context/index_spec.js
Normal file
897
test/red/runtime/nodes/context/index_spec.js
Normal file
@@ -0,0 +1,897 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var should = require("should");
|
||||
var sinon = require('sinon');
|
||||
var path = require("path");
|
||||
var Context = require("../../../../../red/runtime/nodes/context/index");
|
||||
|
||||
describe('context', function() {
|
||||
describe('local memory',function() {
|
||||
beforeEach(function() {
|
||||
Context.init({});
|
||||
Context.load();
|
||||
});
|
||||
afterEach(function() {
|
||||
Context.clean({allNodes:{}});
|
||||
return Context.close();
|
||||
});
|
||||
it('stores local property',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
should.not.exist(context1.get("foo"));
|
||||
context1.set("foo","test");
|
||||
context1.get("foo").should.equal("test");
|
||||
});
|
||||
it('stores local property - creates parent properties',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
context1.set("foo.bar","test");
|
||||
context1.get("foo").should.eql({bar:"test"});
|
||||
});
|
||||
it('deletes local property',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
context1.set("foo.abc.bar1","test1");
|
||||
context1.set("foo.abc.bar2","test2");
|
||||
context1.get("foo.abc").should.eql({bar1:"test1",bar2:"test2"});
|
||||
context1.set("foo.abc.bar1",undefined);
|
||||
context1.get("foo.abc").should.eql({bar2:"test2"});
|
||||
context1.set("foo.abc",undefined);
|
||||
should.not.exist(context1.get("foo.abc"));
|
||||
context1.set("foo",undefined);
|
||||
should.not.exist(context1.get("foo"));
|
||||
});
|
||||
it('stores flow property',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
should.not.exist(context1.flow.get("foo"));
|
||||
context1.flow.set("foo","test");
|
||||
context1.flow.get("foo").should.equal("test");
|
||||
});
|
||||
it('stores global property',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
should.not.exist(context1.global.get("foo"));
|
||||
context1.global.set("foo","test");
|
||||
context1.global.get("foo").should.equal("test");
|
||||
});
|
||||
|
||||
it('keeps local context local', function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
var context2 = Context.get("2","flowA");
|
||||
|
||||
should.not.exist(context1.get("foo"));
|
||||
should.not.exist(context2.get("foo"));
|
||||
context1.set("foo","test");
|
||||
|
||||
context1.get("foo").should.equal("test");
|
||||
should.not.exist(context2.get("foo"));
|
||||
});
|
||||
it('flow context accessible to all flow nodes', function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
var context2 = Context.get("2","flowA");
|
||||
|
||||
should.not.exist(context1.flow.get("foo"));
|
||||
should.not.exist(context2.flow.get("foo"));
|
||||
|
||||
context1.flow.set("foo","test");
|
||||
context1.flow.get("foo").should.equal("test");
|
||||
context2.flow.get("foo").should.equal("test");
|
||||
});
|
||||
|
||||
it('flow context not shared to nodes on other flows', function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
var context2 = Context.get("2","flowB");
|
||||
|
||||
should.not.exist(context1.flow.get("foo"));
|
||||
should.not.exist(context2.flow.get("foo"));
|
||||
|
||||
context1.flow.set("foo","test");
|
||||
context1.flow.get("foo").should.equal("test");
|
||||
should.not.exist(context2.flow.get("foo"));
|
||||
});
|
||||
|
||||
it('global context shared to all nodes', function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
var context2 = Context.get("2","flowB");
|
||||
|
||||
should.not.exist(context1.global.get("foo"));
|
||||
should.not.exist(context2.global.get("foo"));
|
||||
|
||||
context1.global.set("foo","test");
|
||||
context1.global.get("foo").should.equal("test");
|
||||
context2.global.get("foo").should.equal("test");
|
||||
});
|
||||
|
||||
it('deletes context',function() {
|
||||
var context = Context.get("1","flowA");
|
||||
should.not.exist(context.get("foo"));
|
||||
context.set("foo","abc");
|
||||
context.get("foo").should.equal("abc");
|
||||
|
||||
return Context.delete("1","flowA").then(function(){
|
||||
context = Context.get("1","flowA");
|
||||
should.not.exist(context.get("foo"));
|
||||
});
|
||||
});
|
||||
|
||||
it('enumerates context keys - sync', function() {
|
||||
var context = Context.get("1","flowA");
|
||||
|
||||
var keys = context.keys();
|
||||
keys.should.be.an.Array();
|
||||
keys.should.be.empty();
|
||||
|
||||
context.set("foo","bar");
|
||||
keys = context.keys();
|
||||
keys.should.have.length(1);
|
||||
keys[0].should.equal("foo");
|
||||
|
||||
context.set("abc.def","bar");
|
||||
keys = context.keys();
|
||||
keys.should.have.length(2);
|
||||
keys[1].should.equal("abc");
|
||||
});
|
||||
|
||||
it('enumerates context keys - async', function(done) {
|
||||
var context = Context.get("1","flowA");
|
||||
|
||||
var keys = context.keys(function(err,keys) {
|
||||
keys.should.be.an.Array();
|
||||
keys.should.be.empty();
|
||||
context.set("foo","bar");
|
||||
keys = context.keys(function(err,keys) {
|
||||
keys.should.have.length(1);
|
||||
keys[0].should.equal("foo");
|
||||
|
||||
context.set("abc.def","bar");
|
||||
keys = context.keys(function(err,keys) {
|
||||
keys.should.have.length(2);
|
||||
keys[1].should.equal("abc");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should enumerate only context keys when GlobalContext was given - sync', function() {
|
||||
Context.init({functionGlobalContext: {foo:"bar"}});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flowA");
|
||||
context.global.set("foo2","bar2");
|
||||
var keys = context.global.keys();
|
||||
keys.should.have.length(2);
|
||||
keys[0].should.equal("foo");
|
||||
keys[1].should.equal("foo2");
|
||||
});
|
||||
});
|
||||
|
||||
it('should enumerate only context keys when GlobalContext was given - async', function(done) {
|
||||
Context.init({functionGlobalContext: {foo:"bar"}});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flowA");
|
||||
context.global.set("foo2","bar2");
|
||||
context.global.keys(function(err,keys) {
|
||||
keys.should.have.length(2);
|
||||
keys[0].should.equal("foo");
|
||||
keys[1].should.equal("foo2");
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
|
||||
|
||||
it('returns functionGlobalContext value if store value undefined', function() {
|
||||
Context.init({functionGlobalContext: {foo:"bar"}});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flowA");
|
||||
var v = context.global.get('foo');
|
||||
v.should.equal('bar');
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
describe('external context storage',function() {
|
||||
var resourcesDir = path.resolve(path.join(__dirname,"..","resources","context"));
|
||||
var sandbox = sinon.sandbox.create();
|
||||
var stubGet = sandbox.stub();
|
||||
var stubSet = sandbox.stub();
|
||||
var stubKeys = sandbox.stub();
|
||||
var stubDelete = sandbox.stub().returns(Promise.resolve());
|
||||
var stubClean = sandbox.stub().returns(Promise.resolve());
|
||||
var stubOpen = sandbox.stub().returns(Promise.resolve());
|
||||
var stubClose = sandbox.stub().returns(Promise.resolve());
|
||||
var stubGet2 = sandbox.stub();
|
||||
var stubSet2 = sandbox.stub();
|
||||
var stubKeys2 = sandbox.stub();
|
||||
var stubDelete2 = sandbox.stub().returns(Promise.resolve());
|
||||
var stubClean2 = sandbox.stub().returns(Promise.resolve());
|
||||
var stubOpen2 = sandbox.stub().returns(Promise.resolve());
|
||||
var stubClose2 = sandbox.stub().returns(Promise.resolve());
|
||||
var testPlugin = function(config){
|
||||
function Test(){}
|
||||
Test.prototype.get = stubGet;
|
||||
Test.prototype.set = stubSet;
|
||||
Test.prototype.keys = stubKeys;
|
||||
Test.prototype.delete = stubDelete;
|
||||
Test.prototype.clean = stubClean;
|
||||
Test.prototype.open = stubOpen;
|
||||
Test.prototype.close = stubClose;
|
||||
return new Test(config);
|
||||
};
|
||||
var testPlugin2 = function(config){
|
||||
function Test2(){}
|
||||
Test2.prototype.get = stubGet2;
|
||||
Test2.prototype.set = stubSet2;
|
||||
Test2.prototype.keys = stubKeys2;
|
||||
Test2.prototype.delete = stubDelete2;
|
||||
Test2.prototype.clean = stubClean2;
|
||||
Test2.prototype.open = stubOpen2;
|
||||
Test2.prototype.close = stubClose2;
|
||||
return new Test2(config);
|
||||
};
|
||||
var contextStorage={
|
||||
test:{
|
||||
module: testPlugin,
|
||||
config:{}
|
||||
}
|
||||
};
|
||||
var contextDefaultStorage={
|
||||
default: {
|
||||
module: testPlugin2,
|
||||
config:{}
|
||||
},
|
||||
test:{
|
||||
module: testPlugin,
|
||||
config:{}
|
||||
}
|
||||
};
|
||||
var contextAlias={
|
||||
default: "test",
|
||||
test:{
|
||||
module: testPlugin,
|
||||
config:{}
|
||||
}
|
||||
};
|
||||
var memoryStorage ={
|
||||
memory:{
|
||||
module: "memory"
|
||||
}
|
||||
};
|
||||
|
||||
afterEach(function() {
|
||||
sandbox.reset();
|
||||
return Context.clean({allNodes:{}}).then(function(){
|
||||
return Context.close();
|
||||
});
|
||||
});
|
||||
|
||||
describe('load modules',function(){
|
||||
it('should call open()', function() {
|
||||
Context.init({contextStorage:contextDefaultStorage});
|
||||
Context.load().then(function(){
|
||||
stubOpen.called.should.be.true();
|
||||
stubOpen2.called.should.be.true();
|
||||
});
|
||||
});
|
||||
it('should load memory module', function() {
|
||||
Context.init({contextStorage:{memory:{module:"memory"}}});
|
||||
Context.load();
|
||||
});
|
||||
it('should load localfilesystem module', function() {
|
||||
Context.init({contextStorage:{file:{module:"localfilesystem",config:{dir:resourcesDir}}}});
|
||||
Context.load();
|
||||
});
|
||||
it('should ignore reserved storage name `_`', function(done) {
|
||||
Context.init({contextStorage:{_:{module:testPlugin}}});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
var cb = function(){}
|
||||
context.set("foo","bar","_",cb);
|
||||
context.get("foo","_",cb);
|
||||
context.keys("_",cb);
|
||||
stubSet.called.should.be.false();
|
||||
stubGet.called.should.be.false();
|
||||
stubKeys.called.should.be.false();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should fail when using invalid store name', function(done) {
|
||||
Context.init({contextStorage:{'Invalid name':{module:testPlugin}}});
|
||||
Context.load().then(function(){
|
||||
done("An error was not thrown");
|
||||
}).catch(function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should fail when using invalid sign character', function (done) {
|
||||
Context.init({ contextStorage:{'abc-123':{module:testPlugin}}});
|
||||
Context.load().then(function () {
|
||||
done("An error was not thrown");
|
||||
}).catch(function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should fail when using invalid default context', function(done) {
|
||||
Context.init({contextStorage:{default:"noexist"}});
|
||||
Context.load().then(function(){
|
||||
done("An error was not thrown");
|
||||
}).catch(function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should fail for the storage with no module', function(done) {
|
||||
Context.init({ contextStorage: { test: {}}});
|
||||
Context.load().then(function(){
|
||||
done("An error was not thrown");
|
||||
}).catch(function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should fail to load non-existent module', function(done) {
|
||||
Context.init({contextStorage:{ file:{module:"nonexistent"} }});
|
||||
Context.load().then(function(){
|
||||
done("An error was not thrown");
|
||||
}).catch(function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should fail to load invalid module', function (done) {
|
||||
Context.init({contextStorage: {
|
||||
test: {
|
||||
module: function (config) {
|
||||
throw new Error("invalid plugin was loaded.");
|
||||
}
|
||||
}
|
||||
}});
|
||||
Context.load().then(function () {
|
||||
done("An error was not thrown");
|
||||
}).catch(function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('close modules',function(){
|
||||
it('should call close()', function(done) {
|
||||
Context.init({contextStorage:contextDefaultStorage});
|
||||
Context.load().then(function(){
|
||||
return Context.close().then(function(){
|
||||
stubClose.called.should.be.true();
|
||||
stubClose2.called.should.be.true();
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('store context',function() {
|
||||
it('should store local property to external context storage',function(done) {
|
||||
Context.init({contextStorage:contextStorage});
|
||||
var cb = function(){done("An error occurred")}
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.set("foo","bar","test",cb);
|
||||
context.get("foo","test",cb);
|
||||
context.keys("test",cb);
|
||||
stubSet.calledWithExactly("1:flow","foo","bar",cb).should.be.true();
|
||||
stubGet.calledWith("1:flow","foo").should.be.true();
|
||||
stubKeys.calledWithExactly("1:flow",cb).should.be.true();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
it('should store flow property to external context storage',function(done) {
|
||||
Context.init({contextStorage:contextStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
var cb = function(){done("An error occurred")}
|
||||
context.flow.set("foo","bar","test",cb);
|
||||
context.flow.get("foo","test",cb);
|
||||
context.flow.keys("test",cb);
|
||||
stubSet.calledWithExactly("flow","foo","bar",cb).should.be.true();
|
||||
stubGet.calledWith("flow","foo").should.be.true();
|
||||
stubKeys.calledWithExactly("flow",cb).should.be.true();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
it('should store global property to external context storage',function(done) {
|
||||
Context.init({contextStorage:contextStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
var cb = function(){done("An error occurred")}
|
||||
context.global.set("foo","bar","test",cb);
|
||||
context.global.get("foo","test",cb);
|
||||
context.global.keys("test",cb);
|
||||
stubSet.calledWithExactly("global","foo","bar",cb).should.be.true();
|
||||
stubGet.calledWith("global","foo").should.be.true();
|
||||
stubKeys.calledWith("global").should.be.true();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
it('should store data to the default context when non-existent context storage was specified', function(done) {
|
||||
Context.init({contextStorage:contextDefaultStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
var cb = function(){done("An error occurred")}
|
||||
context.set("foo","bar","nonexist",cb);
|
||||
context.get("foo","nonexist",cb);
|
||||
context.keys("nonexist",cb);
|
||||
stubGet.called.should.be.false();
|
||||
stubSet.called.should.be.false();
|
||||
stubKeys.called.should.be.false();
|
||||
stubSet2.calledWithExactly("1:flow","foo","bar",cb).should.be.true();
|
||||
stubGet2.calledWith("1:flow","foo").should.be.true();
|
||||
stubKeys2.calledWithExactly("1:flow",cb).should.be.true();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
it('should use the default context', function(done) {
|
||||
Context.init({contextStorage:contextDefaultStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
var cb = function(){done("An error occurred")}
|
||||
context.set("foo","bar","default",cb);
|
||||
context.get("foo","default",cb);
|
||||
context.keys("default",cb);
|
||||
stubGet.called.should.be.false();
|
||||
stubSet.called.should.be.false();
|
||||
stubKeys.called.should.be.false();
|
||||
stubSet2.calledWithExactly("1:flow","foo","bar",cb).should.be.true();
|
||||
stubGet2.calledWith("1:flow","foo").should.be.true();
|
||||
stubKeys2.calledWithExactly("1:flow",cb).should.be.true();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
it('should use the alias of default context', function(done) {
|
||||
Context.init({contextStorage:contextDefaultStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
var cb = function(){done("An error occurred")}
|
||||
context.set("foo","alias",cb);
|
||||
context.get("foo",cb);
|
||||
context.keys(cb);
|
||||
stubGet.called.should.be.false();
|
||||
stubSet.called.should.be.false();
|
||||
stubKeys.called.should.be.false();
|
||||
stubSet2.calledWithExactly("1:flow","foo","alias",cb).should.be.true();
|
||||
stubGet2.calledWith("1:flow","foo").should.be.true();
|
||||
stubKeys2.calledWithExactly("1:flow",cb).should.be.true();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
it('should use default as the alias of other context', function(done) {
|
||||
Context.init({contextStorage:contextAlias});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
var cb = function(){done("An error occurred")}
|
||||
context.set("foo","alias",cb);
|
||||
context.get("foo",cb);
|
||||
context.keys(cb);
|
||||
stubSet.calledWithExactly("1:flow","foo","alias",cb).should.be.true();
|
||||
stubGet.calledWith("1:flow","foo").should.be.true();
|
||||
stubKeys.calledWithExactly("1:flow",cb).should.be.true();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
it('should not throw an error using undefined storage for local context', function(done) {
|
||||
Context.init({contextStorage:contextStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
var cb = function(){done("An error occurred")}
|
||||
context.get("local","nonexist",cb);
|
||||
done()
|
||||
}).catch(done);
|
||||
});
|
||||
it('should throw an error using undefined storage for flow context', function(done) {
|
||||
Context.init({contextStorage:contextStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
var cb = function(){done("An error occurred")}
|
||||
context.flow.get("flow","nonexist",cb);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should return functionGlobalContext value as a default - synchronous', function(done) {
|
||||
var fGC = { "foo": 456 };
|
||||
Context.init({contextStorage:memoryStorage, functionGlobalContext:fGC });
|
||||
Context.load().then(function() {
|
||||
var context = Context.get("1","flow");
|
||||
// Get foo - should be value from fGC
|
||||
var v = context.global.get("foo");
|
||||
v.should.equal(456);
|
||||
|
||||
// Update foo - should not touch fGC object
|
||||
context.global.set("foo","new value");
|
||||
fGC.foo.should.equal(456);
|
||||
|
||||
// Get foo - should be the updated value
|
||||
v = context.global.get("foo");
|
||||
v.should.equal("new value");
|
||||
done();
|
||||
}).catch(done);
|
||||
})
|
||||
|
||||
it('should return functionGlobalContext value as a default - async', function(done) {
|
||||
var fGC = { "foo": 456 };
|
||||
Context.init({contextStorage:memoryStorage, functionGlobalContext:fGC });
|
||||
Context.load().then(function() {
|
||||
var context = Context.get("1","flow");
|
||||
// Get foo - should be value from fGC
|
||||
context.global.get("foo", function(err, v) {
|
||||
if (err) {
|
||||
done(err)
|
||||
} else {
|
||||
v.should.equal(456);
|
||||
// Update foo - should not touch fGC object
|
||||
context.global.set("foo","new value", function(err) {
|
||||
if (err) {
|
||||
done(err)
|
||||
} else {
|
||||
fGC.foo.should.equal(456);
|
||||
// Get foo - should be the updated value
|
||||
context.global.get("foo", function(err, v) {
|
||||
if (err) {
|
||||
done(err)
|
||||
} else {
|
||||
v.should.equal("new value");
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}).catch(done);
|
||||
})
|
||||
|
||||
it('should return multiple values if key is an array', function(done) {
|
||||
Context.init({contextStorage:memoryStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.set("foo1","bar1","memory");
|
||||
context.set("foo2","bar2","memory");
|
||||
context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
foo1.should.be.equal("bar1");
|
||||
foo2.should.be.equal("bar2");
|
||||
should.not.exist(foo3);
|
||||
done();
|
||||
}
|
||||
});
|
||||
}).catch(function(err){ done(err); });
|
||||
});
|
||||
|
||||
it('should return multiple functionGlobalContext values if key is an array', function(done) {
|
||||
var fGC = { "foo1": 456, "foo2": 789 };
|
||||
Context.init({contextStorage:memoryStorage, functionGlobalContext:fGC });
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.global.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
foo1.should.be.equal(456);
|
||||
foo2.should.be.equal(789);
|
||||
should.not.exist(foo3);
|
||||
done();
|
||||
}
|
||||
});
|
||||
}).catch(function(err){ done(err); });
|
||||
});
|
||||
|
||||
it('should return an error if an error occurs in getting multiple store values', function(done) {
|
||||
Context.init({contextStorage:contextStorage});
|
||||
stubGet.onFirstCall().callsArgWith(2, "error2", "bar1");
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.global.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err === "error2") {
|
||||
done();
|
||||
} else {
|
||||
done("An error occurred");
|
||||
}
|
||||
});
|
||||
}).catch(function(err){ done(err); });
|
||||
});
|
||||
|
||||
it('should return a first error if some errors occur in getting multiple store values', function(done) {
|
||||
Context.init({contextStorage:contextStorage});
|
||||
stubGet.onFirstCall().callsArgWith(2, "error1");
|
||||
stubGet.onSecondCall().callsArgWith(2, null, "bar2");
|
||||
stubGet.onThirdCall().callsArgWith(2, "error3");
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err === "error1") {
|
||||
done();
|
||||
} else {
|
||||
done("An error occurred");
|
||||
}
|
||||
});
|
||||
}).catch(function(err){ done(err); });
|
||||
});
|
||||
|
||||
it('should store multiple properties if key and value are arrays', function(done) {
|
||||
Context.init({contextStorage:memoryStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3"], "memory", function(err){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
foo1.should.be.equal("bar1");
|
||||
foo2.should.be.equal("bar2");
|
||||
foo3.should.be.equal("bar3");
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should deletes multiple properties', function(done) {
|
||||
Context.init({contextStorage:memoryStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3"], "memory", function(err){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
foo1.should.be.equal("bar1");
|
||||
foo2.should.be.equal("bar2");
|
||||
foo3.should.be.equal("bar3");
|
||||
context.set(["foo1","foo2","foo3"], new Array(3), "memory", function(err){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
should.not.exist(foo1);
|
||||
should.not.exist(foo2);
|
||||
should.not.exist(foo3);
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should use null for missing values if the value array is shorter than the key array', function(done) {
|
||||
Context.init({contextStorage:memoryStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.set(["foo1","foo2","foo3"], ["bar1","bar2"], "memory", function(err){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
context.keys(function(err, keys){
|
||||
keys.should.have.length(3);
|
||||
keys.should.eql(["foo1","foo2","foo3"]);
|
||||
context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
foo1.should.be.equal("bar1");
|
||||
foo2.should.be.equal("bar2");
|
||||
should(foo3).be.null();
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should use null for missing values if the value is not array', function(done) {
|
||||
Context.init({contextStorage:memoryStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.set(["foo1","foo2","foo3"], "bar1", "memory", function(err){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
context.keys(function(err, keys){
|
||||
keys.should.have.length(3);
|
||||
keys.should.eql(["foo1","foo2","foo3"]);
|
||||
context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
foo1.should.be.equal("bar1");
|
||||
should(foo2).be.null();
|
||||
should(foo3).be.null();
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should ignore the extra values if the value array is longer than the key array', function(done) {
|
||||
Context.init({contextStorage:memoryStorage});
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3","ignored"], "memory", function(err){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
context.keys(function(err, keys){
|
||||
keys.should.have.length(3);
|
||||
keys.should.eql(["foo1","foo2","foo3"]);
|
||||
context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
foo1.should.be.equal("bar1");
|
||||
foo2.should.be.equal("bar2");
|
||||
foo3.should.be.equal("bar3");
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an error if an error occurs in storing multiple values', function(done) {
|
||||
Context.init({contextStorage:contextStorage});
|
||||
stubSet.onFirstCall().callsArgWith(3, "error2");
|
||||
Context.load().then(function(){
|
||||
var context = Context.get("1","flow");
|
||||
context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3"], "memory", function(err){
|
||||
if (err === "error2") {
|
||||
done();
|
||||
} else {
|
||||
done("An error occurred");
|
||||
}
|
||||
});
|
||||
}).catch(function(err){ done(err); });
|
||||
});
|
||||
|
||||
it('should throw an error if callback of context.get is not a function', function (done) {
|
||||
Context.init({ contextStorage: memoryStorage });
|
||||
Context.load().then(function () {
|
||||
var context = Context.get("1", "flow");
|
||||
context.get("foo", "memory", "callback");
|
||||
done("should throw an error.");
|
||||
}).catch(function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not throw an error if callback of context.get is not specified', function (done) {
|
||||
Context.init({ contextStorage: memoryStorage });
|
||||
Context.load().then(function () {
|
||||
var context = Context.get("1", "flow");
|
||||
context.get("foo", "memory");
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should throw an error if callback of context.set is not a function', function (done) {
|
||||
Context.init({ contextStorage: memoryStorage });
|
||||
Context.load().then(function () {
|
||||
var context = Context.get("1", "flow");
|
||||
context.set("foo", "bar", "memory", "callback");
|
||||
done("should throw an error.");
|
||||
}).catch(function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not throw an error if callback of context.set is not specified', function (done) {
|
||||
Context.init({ contextStorage: memoryStorage });
|
||||
Context.load().then(function () {
|
||||
var context = Context.get("1", "flow");
|
||||
context.set("foo", "bar", "memory");
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should throw an error if callback of context.keys is not a function', function (done) {
|
||||
Context.init({ contextStorage: memoryStorage });
|
||||
Context.load().then(function () {
|
||||
var context = Context.get("1", "flow");
|
||||
context.keys("memory", "callback");
|
||||
done("should throw an error.");
|
||||
}).catch(function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not throw an error if callback of context.keys is not specified', function (done) {
|
||||
Context.init({ contextStorage: memoryStorage });
|
||||
Context.load().then(function () {
|
||||
var context = Context.get("1", "flow");
|
||||
context.keys("memory");
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('listStores', function () {
|
||||
it('should list context storages', function (done) {
|
||||
Context.init({ contextStorage: contextDefaultStorage });
|
||||
Context.load().then(function () {
|
||||
var list = Context.listStores();
|
||||
list.default.should.equal("default");
|
||||
list.stores.should.eql(["default", "test"]);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should list context storages without default storage', function (done) {
|
||||
Context.init({ contextStorage: contextStorage });
|
||||
Context.load().then(function () {
|
||||
var list = Context.listStores();
|
||||
list.default.should.equal("test");
|
||||
list.stores.should.eql(["test"]);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('delete context',function(){
|
||||
it('should not call delete() when external context storage is used', function(done) {
|
||||
Context.init({contextStorage:contextDefaultStorage});
|
||||
Context.load().then(function(){
|
||||
Context.get("flowA");
|
||||
return Context.delete("flowA").then(function(){
|
||||
stubDelete.called.should.be.false();
|
||||
stubDelete2.called.should.be.false();
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('clean context',function(){
|
||||
it('should call clean()', function(done) {
|
||||
Context.init({contextStorage:contextDefaultStorage});
|
||||
Context.load().then(function(){
|
||||
return Context.clean({allNodes:{}}).then(function(){
|
||||
stubClean.calledWithExactly([]).should.be.true();
|
||||
stubClean2.calledWithExactly([]).should.be.true();
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
774
test/red/runtime/nodes/context/localfilesystem_spec.js
Normal file
774
test/red/runtime/nodes/context/localfilesystem_spec.js
Normal file
@@ -0,0 +1,774 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var should = require('should');
|
||||
var fs = require('fs-extra');
|
||||
var path = require("path");
|
||||
var LocalFileSystem = require('../../../../../red/runtime/nodes/context/localfilesystem');
|
||||
|
||||
var resourcesDir = path.resolve(path.join(__dirname,"..","resources","context"));
|
||||
|
||||
describe('localfilesystem',function() {
|
||||
var context;
|
||||
|
||||
before(function() {
|
||||
return fs.remove(resourcesDir);
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
context = LocalFileSystem({dir: resourcesDir, cache: false});
|
||||
return context.open();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
return context.clean([]).then(function(){
|
||||
return context.close().then(function(){
|
||||
return fs.remove(resourcesDir);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#get/set',function() {
|
||||
it('should store property',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo","test",function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.equal("test");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store property - creates parent properties',function(done) {
|
||||
context.set("nodeX","foo.bar","test",function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.eql({bar:"test"});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store local scope property', function (done) {
|
||||
context.set("abc:def", "foo.bar", "test", function (err) {
|
||||
context.get("abc:def", "foo", function (err, value) {
|
||||
value.should.be.eql({ bar: "test" });
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should delete property',function(done) {
|
||||
context.set("nodeX","foo.abc.bar1","test1",function(err){
|
||||
context.set("nodeX","foo.abc.bar2","test2",function(err){
|
||||
context.get("nodeX","foo.abc",function(err, value){
|
||||
value.should.be.eql({bar1:"test1",bar2:"test2"});
|
||||
context.set("nodeX","foo.abc.bar1",undefined,function(err){
|
||||
context.get("nodeX","foo.abc",function(err, value){
|
||||
value.should.be.eql({bar2:"test2"});
|
||||
context.set("nodeX","foo.abc",undefined,function(err){
|
||||
context.get("nodeX","foo.abc",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo",undefined,function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not shared context with other scope', function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo","testX",function(err){
|
||||
context.set("nodeY","foo","testY",function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.equal("testX");
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
value.should.be.equal("testY");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store string',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo","bar",function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.String();
|
||||
value.should.be.equal("bar");
|
||||
context.set("nodeX","foo","1",function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.String();
|
||||
value.should.be.equal("1");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store number',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo",1,function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.Number();
|
||||
value.should.be.equal(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store null',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo",null,function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should(value).be.null();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store boolean',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo",true,function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.Boolean().and.true();
|
||||
context.set("nodeX","foo",false,function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.Boolean().and.false();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store object',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo",{obj:"bar"},function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.Object();
|
||||
value.should.eql({obj:"bar"});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store array',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo",["a","b","c"],function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.Array();
|
||||
value.should.eql(["a","b","c"]);
|
||||
context.get("nodeX","foo[1]",function(err, value){
|
||||
value.should.be.String();
|
||||
value.should.equal("b");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store array of arrays',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo",[["a","b","c"],[1,2,3,4],[true,false]],function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.Array();
|
||||
value.should.have.length(3);
|
||||
value[0].should.have.length(3);
|
||||
value[1].should.have.length(4);
|
||||
value[2].should.have.length(2);
|
||||
context.get("nodeX","foo[1]",function(err, value){
|
||||
value.should.be.Array();
|
||||
value.should.have.length(4);
|
||||
value.should.be.eql([1,2,3,4]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should store array of objects',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo",[{obj:"bar1"},{obj:"bar2"},{obj:"bar3"}],function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.Array();
|
||||
value.should.have.length(3);
|
||||
value[0].should.be.Object();
|
||||
value[1].should.be.Object();
|
||||
value[2].should.be.Object();
|
||||
context.get("nodeX","foo[1]",function(err, value){
|
||||
value.should.be.Object();
|
||||
value.should.be.eql({obj:"bar2"});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should set/get multiple values', function(done) {
|
||||
context.set("nodeX",["one","two","three"],["test1","test2","test3"], function(err) {
|
||||
context.get("nodeX",["one","two"], function() {
|
||||
Array.prototype.slice.apply(arguments).should.eql([undefined,"test1","test2"])
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
it('should set/get multiple values - get unknown', function(done) {
|
||||
context.set("nodeX",["one","two","three"],["test1","test2","test3"], function(err) {
|
||||
context.get("nodeX",["one","two","unknown"], function() {
|
||||
Array.prototype.slice.apply(arguments).should.eql([undefined,"test1","test2",undefined])
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
it('should set/get multiple values - single value providd', function(done) {
|
||||
context.set("nodeX",["one","two","three"],"test1", function(err) {
|
||||
context.get("nodeX",["one","two"], function() {
|
||||
Array.prototype.slice.apply(arguments).should.eql([undefined,"test1",null])
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
it('should throw error if bad key included in multiple keys - get', function(done) {
|
||||
context.set("nodeX",["one","two","three"],["test1","test2","test3"], function(err) {
|
||||
context.get("nodeX",["one",".foo","three"], function(err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
it('should throw error if bad key included in multiple keys - set', function(done) {
|
||||
context.set("nodeX",["one",".foo","three"],["test1","test2","test3"], function(err) {
|
||||
should.exist(err);
|
||||
// Check 'one' didn't get set as a result
|
||||
context.get("nodeX","one",function(err,one) {
|
||||
should.not.exist(one);
|
||||
done();
|
||||
})
|
||||
});
|
||||
})
|
||||
|
||||
it('should throw an error when getting a value with invalid key', function (done) {
|
||||
context.set("nodeX","foo","bar",function(err) {
|
||||
context.get("nodeX"," ",function(err,value) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw an error when setting a value with invalid key',function (done) {
|
||||
context.set("nodeX"," ","bar",function (err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw an error when callback of get() is not a function',function (done) {
|
||||
try {
|
||||
context.get("nodeX","foo","callback");
|
||||
done("should throw an error.");
|
||||
} catch (err) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error when callback of get() is not specified',function (done) {
|
||||
try {
|
||||
context.get("nodeX","foo");
|
||||
done("should throw an error.");
|
||||
} catch (err) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error when callback of set() is not a function',function (done) {
|
||||
try {
|
||||
context.set("nodeX","foo","bar","callback");
|
||||
done("should throw an error.");
|
||||
} catch (err) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('should not throw an error when callback of set() is not specified', function (done) {
|
||||
try {
|
||||
context.set("nodeX"," ","bar");
|
||||
done();
|
||||
} catch (err) {
|
||||
done("should not throw an error.");
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle empty context file', function (done) {
|
||||
fs.outputFile(path.join(resourcesDir,"contexts","nodeX","flow.json"),"",function(){
|
||||
context.get("nodeX", "foo", function (err, value) {
|
||||
should.not.exist(value);
|
||||
context.set("nodeX", "foo", "test", function (err) {
|
||||
context.get("nodeX", "foo", function (err, value) {
|
||||
value.should.be.equal("test");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw an error when reading corrupt context file', function (done) {
|
||||
fs.outputFile(path.join(resourcesDir, "contexts", "nodeX", "flow.json"),"{abc",function(){
|
||||
context.get("nodeX", "foo", function (err, value) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#keys',function() {
|
||||
it('should enumerate context keys', function(done) {
|
||||
context.keys("nodeX",function(err, value){
|
||||
value.should.be.an.Array();
|
||||
value.should.be.empty();
|
||||
context.set("nodeX","foo","bar",function(err){
|
||||
context.keys("nodeX",function(err, value){
|
||||
value.should.have.length(1);
|
||||
value[0].should.equal("foo");
|
||||
context.set("nodeX","abc.def","bar",function(err){
|
||||
context.keys("nodeX",function(err, value){
|
||||
value.should.have.length(2);
|
||||
value[1].should.equal("abc");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should enumerate context keys in each scopes', function(done) {
|
||||
context.keys("nodeX",function(err, value){
|
||||
value.should.be.an.Array();
|
||||
value.should.be.empty();
|
||||
context.keys("nodeY",function(err, value){
|
||||
value.should.be.an.Array();
|
||||
value.should.be.empty();
|
||||
context.set("nodeX","foo","bar",function(err){
|
||||
context.set("nodeY","hoge","piyo",function(err){
|
||||
context.keys("nodeX",function(err, value){
|
||||
value.should.have.length(1);
|
||||
value[0].should.equal("foo");
|
||||
context.keys("nodeY",function(err, value){
|
||||
value.should.have.length(1);
|
||||
value[0].should.equal("hoge");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw an error when callback of keys() is not a function', function (done) {
|
||||
try {
|
||||
context.keys("nodeX", "callback");
|
||||
done("should throw an error.");
|
||||
} catch (err) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error when callback of keys() is not specified', function (done) {
|
||||
try {
|
||||
context.keys("nodeX");
|
||||
done("should throw an error.");
|
||||
} catch (err) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('#delete',function() {
|
||||
it('should delete context',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo","testX",function(err){
|
||||
context.set("nodeY","foo","testY",function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.equal("testX");
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
value.should.be.equal("testY");
|
||||
context.delete("nodeX").then(function(){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
value.should.be.equal("testY");
|
||||
done();
|
||||
});
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#clean',function() {
|
||||
it('should clean unnecessary context',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo","testX",function(err){
|
||||
context.set("nodeY","foo","testY",function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.equal("testX");
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
value.should.be.equal("testY");
|
||||
context.clean([]).then(function(){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not clean active context',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo","testX",function(err){
|
||||
context.set("nodeY","foo","testY",function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.equal("testX");
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
value.should.be.equal("testY");
|
||||
context.clean(["nodeX"]).then(function(){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.be.equal("testX");
|
||||
context.get("nodeY","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#if cache is enabled',function() {
|
||||
afterEach(function() {
|
||||
return context.clean([]).then(function(){
|
||||
return context.close().then(function(){
|
||||
return fs.remove(resourcesDir);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should load contexts into the cache',function() {
|
||||
var globalData = {key:"global"};
|
||||
var flowData = {key:"flow"};
|
||||
var nodeData = {key:"node"};
|
||||
return Promise.all([
|
||||
fs.outputFile(path.join(resourcesDir,"contexts","global","global.json"), JSON.stringify(globalData,null,4), "utf8"),
|
||||
fs.outputFile(path.join(resourcesDir,"contexts","flow","flow.json"), JSON.stringify(flowData,null,4), "utf8"),
|
||||
fs.outputFile(path.join(resourcesDir,"contexts","flow","node.json"), JSON.stringify(nodeData,null,4), "utf8")
|
||||
]).then(function(){
|
||||
context = LocalFileSystem({dir: resourcesDir, cache: true});
|
||||
return context.open();
|
||||
}).then(function(){
|
||||
return Promise.all([
|
||||
fs.remove(path.join(resourcesDir,"contexts","global","global.json")),
|
||||
fs.remove(path.join(resourcesDir,"contexts","flow","flow.json")),
|
||||
fs.remove(path.join(resourcesDir,"contexts","flow","node.json"))
|
||||
]);
|
||||
}).then(function(){
|
||||
context.get("global","key").should.be.equal("global");
|
||||
context.get("flow","key").should.be.equal("flow");
|
||||
context.get("node:flow","key").should.be.equal("node");
|
||||
});
|
||||
});
|
||||
|
||||
it('should store property to the cache',function() {
|
||||
context = LocalFileSystem({dir: resourcesDir, cache: true});
|
||||
return context.open().then(function(){
|
||||
return new Promise(function(resolve, reject){
|
||||
context.set("global","foo","bar",function(err){
|
||||
if(err){
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}).then(function(){
|
||||
return fs.remove(path.join(resourcesDir,"contexts","global","global.json"));
|
||||
}).then(function(){
|
||||
context.get("global","foo").should.be.equal("bar");
|
||||
})
|
||||
});
|
||||
|
||||
it('should enumerate context keys in the cache',function() {
|
||||
var globalData = {foo:"bar"};
|
||||
fs.outputFile(path.join(resourcesDir,"contexts","global","global.json"), JSON.stringify(globalData,null,4), "utf8").then(function(){
|
||||
context = LocalFileSystem({dir: resourcesDir, cache: true});
|
||||
return context.open()
|
||||
}).then(function(){
|
||||
return fs.remove(path.join(resourcesDir,"contexts","global","global.json"));
|
||||
}).then(function(){
|
||||
var keys = context.keys("global");
|
||||
keys.should.have.length(1);
|
||||
keys[0].should.equal("foo");
|
||||
return new Promise(function(resolve, reject){
|
||||
context.set("global","foo2","bar2",function(err){
|
||||
if(err){
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}).then(function(){
|
||||
return fs.remove(path.join(resourcesDir,"contexts","global","global.json"));
|
||||
}).then(function(){
|
||||
var keys = context.keys("global");
|
||||
keys.should.have.length(2);
|
||||
keys[1].should.equal("foo2");
|
||||
})
|
||||
});
|
||||
|
||||
it('should delete context in the cache',function() {
|
||||
context = LocalFileSystem({dir: resourcesDir, cache: true});
|
||||
return context.open().then(function(){
|
||||
return new Promise(function(resolve, reject){
|
||||
context.set("global","foo","bar",function(err){
|
||||
if(err){
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}).then(function(){
|
||||
context.get("global","foo").should.be.equal("bar");
|
||||
return context.delete("global");
|
||||
}).then(function(){
|
||||
should.not.exist(context.get("global","foo"))
|
||||
})
|
||||
});
|
||||
|
||||
it('should clean unnecessary context in the cache',function() {
|
||||
var flowAData = {key:"flowA"};
|
||||
var flowBData = {key:"flowB"};
|
||||
return Promise.all([
|
||||
fs.outputFile(path.join(resourcesDir,"contexts","flowA","flow.json"), JSON.stringify(flowAData,null,4), "utf8"),
|
||||
fs.outputFile(path.join(resourcesDir,"contexts","flowB","flow.json"), JSON.stringify(flowBData,null,4), "utf8")
|
||||
]).then(function(){
|
||||
context = LocalFileSystem({dir: resourcesDir, cache: true});
|
||||
return context.open();
|
||||
}).then(function(){
|
||||
context.get("flowA","key").should.be.equal("flowA");
|
||||
context.get("flowB","key").should.be.equal("flowB");
|
||||
return context.clean(["flowA"]);
|
||||
}).then(function(){
|
||||
context.get("flowA","key").should.be.equal("flowA");
|
||||
should.not.exist(context.get("flowB","key"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Configuration', function () {
|
||||
it('should change a base directory', function (done) {
|
||||
var differentBaseContext = LocalFileSystem({
|
||||
base: "contexts2",
|
||||
dir: resourcesDir,
|
||||
cache: false
|
||||
});
|
||||
differentBaseContext.open().then(function () {
|
||||
differentBaseContext.set("node2", "foo2", "bar2", function (err) {
|
||||
differentBaseContext.get("node2", "foo2", function (err, value) {
|
||||
value.should.be.equal("bar2");
|
||||
context.get("node2", "foo2", function(err, value) {
|
||||
should.not.exist(value);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should use userDir', function (done) {
|
||||
var userDirContext = LocalFileSystem({
|
||||
base: "contexts2",
|
||||
cache: false,
|
||||
settings: {
|
||||
userDir: resourcesDir
|
||||
}
|
||||
});
|
||||
userDirContext.open().then(function () {
|
||||
userDirContext.set("node2", "foo2", "bar2", function (err) {
|
||||
userDirContext.get("node2", "foo2", function (err, value) {
|
||||
value.should.be.equal("bar2");
|
||||
context.get("node2", "foo2", function (err, value) {
|
||||
should.not.exist(value);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should use NODE_RED_HOME', function (done) {
|
||||
var oldNRH = process.env.NODE_RED_HOME;
|
||||
process.env.NODE_RED_HOME = resourcesDir;
|
||||
fs.mkdirSync(resourcesDir);
|
||||
fs.writeFileSync(path.join(resourcesDir,".config.json"),"");
|
||||
var nrHomeContext = LocalFileSystem({
|
||||
base: "contexts2",
|
||||
cache: false
|
||||
});
|
||||
try {
|
||||
nrHomeContext.open().then(function () {
|
||||
nrHomeContext.set("node2", "foo2", "bar2", function (err) {
|
||||
nrHomeContext.get("node2", "foo2", function (err, value) {
|
||||
value.should.be.equal("bar2");
|
||||
context.get("node2", "foo2", function (err, value) {
|
||||
should.not.exist(value);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} finally {
|
||||
process.env.NODE_RED_HOME = oldNRH;
|
||||
}
|
||||
});
|
||||
|
||||
it('should use HOME_PATH', function (done) {
|
||||
var oldNRH = process.env.NODE_RED_HOME;
|
||||
var oldHOMEPATH = process.env.HOMEPATH;
|
||||
process.env.NODE_RED_HOME = resourcesDir;
|
||||
process.env.HOMEPATH = resourcesDir;
|
||||
var homePath = path.join(resourcesDir, ".node-red");
|
||||
fs.outputFile(path.join(homePath, ".config.json"),"",function(){
|
||||
var homeContext = LocalFileSystem({
|
||||
base: "contexts2",
|
||||
cache: false
|
||||
});
|
||||
try {
|
||||
homeContext.open().then(function () {
|
||||
homeContext.set("node2", "foo2", "bar2", function (err) {
|
||||
homeContext.get("node2", "foo2", function (err, value) {
|
||||
value.should.be.equal("bar2");
|
||||
context.get("node2", "foo2", function (err, value) {
|
||||
should.not.exist(value);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} finally {
|
||||
process.env.NODE_RED_HOME = oldNRH;
|
||||
process.env.HOMEPATH = oldHOMEPATH;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should use HOME_PATH', function (done) {
|
||||
var oldNRH = process.env.NODE_RED_HOME;
|
||||
var oldHOMEPATH = process.env.HOMEPATH;
|
||||
var oldHOME = process.env.HOME;
|
||||
process.env.NODE_RED_HOME = resourcesDir;
|
||||
process.env.HOMEPATH = resourcesDir;
|
||||
process.env.HOME = resourcesDir;
|
||||
var homeContext = LocalFileSystem({
|
||||
base: "contexts2",
|
||||
cache: false
|
||||
});
|
||||
try {
|
||||
homeContext.open().then(function () {
|
||||
homeContext.set("node2", "foo2", "bar2", function (err) {
|
||||
homeContext.get("node2", "foo2", function (err, value) {
|
||||
value.should.be.equal("bar2");
|
||||
context.get("node2", "foo2", function (err, value) {
|
||||
should.not.exist(value);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} finally {
|
||||
process.env.NODE_RED_HOME = oldNRH;
|
||||
process.env.HOMEPATH = oldHOMEPATH;
|
||||
process.env.HOME = oldHOME;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
319
test/red/runtime/nodes/context/memory_spec.js
Normal file
319
test/red/runtime/nodes/context/memory_spec.js
Normal file
@@ -0,0 +1,319 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var should = require('should');
|
||||
var Memory = require('../../../../../red/runtime/nodes/context/memory');
|
||||
|
||||
describe('memory',function() {
|
||||
var context;
|
||||
|
||||
beforeEach(function() {
|
||||
context = Memory({});
|
||||
return context.open();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
return context.clean([]).then(function(){
|
||||
return context.close();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#get/set',function() {
|
||||
describe('sync',function() {
|
||||
it('should store property',function() {
|
||||
should.not.exist(context.get("nodeX","foo"));
|
||||
context.set("nodeX","foo","test");
|
||||
context.get("nodeX","foo").should.equal("test");
|
||||
});
|
||||
|
||||
it('should store property - creates parent properties',function() {
|
||||
context.set("nodeX","foo.bar","test");
|
||||
context.get("nodeX","foo").should.eql({bar:"test"});
|
||||
});
|
||||
|
||||
it('should delete property',function() {
|
||||
context.set("nodeX","foo.abc.bar1","test1");
|
||||
context.set("nodeX","foo.abc.bar2","test2");
|
||||
context.get("nodeX","foo.abc").should.eql({bar1:"test1",bar2:"test2"});
|
||||
context.set("nodeX","foo.abc.bar1",undefined);
|
||||
context.get("nodeX","foo.abc").should.eql({bar2:"test2"});
|
||||
context.set("nodeX","foo.abc",undefined);
|
||||
should.not.exist(context.get("nodeX","foo.abc"));
|
||||
context.set("nodeX","foo",undefined);
|
||||
should.not.exist(context.get("nodeX","foo"));
|
||||
});
|
||||
|
||||
it('should not shared context with other scope', function() {
|
||||
should.not.exist(context.get("nodeX","foo"));
|
||||
should.not.exist(context.get("nodeY","foo"));
|
||||
context.set("nodeX","foo","testX");
|
||||
context.set("nodeY","foo","testY");
|
||||
|
||||
context.get("nodeX","foo").should.equal("testX");
|
||||
context.get("nodeY","foo").should.equal("testY");
|
||||
});
|
||||
|
||||
it('should throw the error if the error occurs', function() {
|
||||
try{
|
||||
context.set("nodeX",".foo","test");
|
||||
should.fail("Error was not thrown");
|
||||
}catch(err){
|
||||
should.exist(err);
|
||||
try{
|
||||
context.get("nodeX",".foo");
|
||||
should.fail("Error was not thrown");
|
||||
}catch(err){
|
||||
should.exist(err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('should get multiple values - all known', function() {
|
||||
context.set("nodeX","one","test1");
|
||||
context.set("nodeX","two","test2");
|
||||
context.set("nodeX","three","test3");
|
||||
context.set("nodeX","four","test4");
|
||||
|
||||
var values = context.get("nodeX",["one","two","four"]);
|
||||
values.should.eql(["test1","test2","test4"])
|
||||
})
|
||||
it('should get multiple values - include unknown', function() {
|
||||
context.set("nodeX","one","test1");
|
||||
context.set("nodeX","two","test2");
|
||||
context.set("nodeX","three","test3");
|
||||
context.set("nodeX","four","test4");
|
||||
|
||||
var values = context.get("nodeX",["one","unknown"]);
|
||||
values.should.eql(["test1",undefined])
|
||||
})
|
||||
it('should throw error if bad key included in multiple keys', function() {
|
||||
context.set("nodeX","one","test1");
|
||||
context.set("nodeX","two","test2");
|
||||
context.set("nodeX","three","test3");
|
||||
context.set("nodeX","four","test4");
|
||||
|
||||
try{
|
||||
var values = context.get("nodeX",["one",".foo","three"]);
|
||||
should.fail("Error was not thrown");
|
||||
}catch(err){
|
||||
should.exist(err);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('async',function() {
|
||||
it('should store property',function(done) {
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
should.not.exist(value);
|
||||
context.set("nodeX","foo","test",function(err){
|
||||
context.get("nodeX","foo",function(err, value){
|
||||
value.should.equal("test");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass the error to callback if the error occurs',function(done) {
|
||||
context.set("nodeX",".foo","test",function(err, value){
|
||||
should.exist(err);
|
||||
context.get("nodeX",".foo",function(err){
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get multiple values - all known', function(done) {
|
||||
context.set("nodeX","one","test1");
|
||||
context.set("nodeX","two","test2");
|
||||
context.set("nodeX","three","test3");
|
||||
context.set("nodeX","four","test4");
|
||||
|
||||
context.get("nodeX",["one","two","four"],function() {
|
||||
Array.prototype.slice.apply(arguments).should.eql([undefined,"test1","test2","test4"])
|
||||
done();
|
||||
});
|
||||
})
|
||||
it('should get multiple values - include unknown', function(done) {
|
||||
context.set("nodeX","one","test1");
|
||||
context.set("nodeX","two","test2");
|
||||
context.set("nodeX","three","test3");
|
||||
context.set("nodeX","four","test4");
|
||||
|
||||
context.get("nodeX",["one","unknown"],function() {
|
||||
Array.prototype.slice.apply(arguments).should.eql([undefined,"test1",undefined])
|
||||
done();
|
||||
});
|
||||
})
|
||||
it('should throw error if bad key included in multiple keys', function(done) {
|
||||
context.set("nodeX","one","test1");
|
||||
context.set("nodeX","two","test2");
|
||||
context.set("nodeX","three","test3");
|
||||
context.set("nodeX","four","test4");
|
||||
|
||||
context.get("nodeX",["one",".foo","three"], function(err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe('#keys',function() {
|
||||
describe('sync',function() {
|
||||
it('should enumerate context keys', function() {
|
||||
var keys = context.keys("nodeX");
|
||||
keys.should.be.an.Array();
|
||||
keys.should.be.empty();
|
||||
|
||||
context.set("nodeX","foo","bar");
|
||||
keys = context.keys("nodeX");
|
||||
keys.should.have.length(1);
|
||||
keys[0].should.equal("foo");
|
||||
|
||||
context.set("nodeX","abc.def","bar");
|
||||
keys = context.keys("nodeX");
|
||||
keys.should.have.length(2);
|
||||
keys[1].should.equal("abc");
|
||||
});
|
||||
|
||||
it('should enumerate context keys in each scopes', function() {
|
||||
var keysX = context.keys("nodeX");
|
||||
keysX.should.be.an.Array();
|
||||
keysX.should.be.empty();
|
||||
|
||||
var keysY = context.keys("nodeY");
|
||||
keysY.should.be.an.Array();
|
||||
keysY.should.be.empty();
|
||||
|
||||
context.set("nodeX","foo","bar");
|
||||
context.set("nodeY","hoge","piyo");
|
||||
keysX = context.keys("nodeX");
|
||||
keysX.should.have.length(1);
|
||||
keysX[0].should.equal("foo");
|
||||
|
||||
keysY = context.keys("nodeY");
|
||||
keysY.should.have.length(1);
|
||||
keysY[0].should.equal("hoge");
|
||||
});
|
||||
|
||||
it('should enumerate global context keys', function () {
|
||||
var keys = context.keys("global");
|
||||
keys.should.be.an.Array();
|
||||
keys.should.be.empty();
|
||||
|
||||
context.set("global", "foo", "bar");
|
||||
keys = context.keys("global");
|
||||
keys.should.have.length(1);
|
||||
keys[0].should.equal("foo");
|
||||
|
||||
context.set("global", "abc.def", "bar");
|
||||
keys = context.keys("global");
|
||||
keys.should.have.length(2);
|
||||
keys[1].should.equal("abc");
|
||||
});
|
||||
|
||||
it('should not return specific keys as global context keys', function () {
|
||||
var keys = context.keys("global");
|
||||
|
||||
context.set("global", "set", "bar");
|
||||
context.set("global", "get", "bar");
|
||||
context.set("global", "keys", "bar");
|
||||
keys = context.keys("global");
|
||||
keys.should.have.length(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('async',function() {
|
||||
it('should enumerate context keys', function(done) {
|
||||
context.keys("nodeX", function(err, keys) {
|
||||
keys.should.be.an.Array();
|
||||
keys.should.be.empty();
|
||||
context.set("nodeX", "foo", "bar", function(err) {
|
||||
context.keys("nodeX", function(err, keys) {
|
||||
keys.should.have.length(1);
|
||||
keys[0].should.equal("foo");
|
||||
context.set("nodeX","abc.def","bar",function(err){
|
||||
context.keys("nodeX",function(err, keys){
|
||||
keys.should.have.length(2);
|
||||
keys[1].should.equal("abc");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#delete',function() {
|
||||
it('should delete context',function() {
|
||||
should.not.exist(context.get("nodeX","foo"));
|
||||
should.not.exist(context.get("nodeY","foo"));
|
||||
context.set("nodeX","foo","abc");
|
||||
context.set("nodeY","foo","abc");
|
||||
context.get("nodeX","foo").should.equal("abc");
|
||||
context.get("nodeY","foo").should.equal("abc");
|
||||
|
||||
return context.delete("nodeX").then(function(){
|
||||
should.not.exist(context.get("nodeX","foo"));
|
||||
should.exist(context.get("nodeY","foo"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#clean',function() {
|
||||
it('should clean unnecessary context',function() {
|
||||
should.not.exist(context.get("nodeX","foo"));
|
||||
should.not.exist(context.get("nodeY","foo"));
|
||||
context.set("nodeX","foo","abc");
|
||||
context.set("nodeY","foo","abc");
|
||||
context.get("nodeX","foo").should.equal("abc");
|
||||
context.get("nodeY","foo").should.equal("abc");
|
||||
|
||||
return context.clean([]).then(function(){
|
||||
should.not.exist(context.get("nodeX","foo"));
|
||||
should.not.exist(context.get("nodeY","foo"));
|
||||
});
|
||||
});
|
||||
it('should not clean active context',function() {
|
||||
should.not.exist(context.get("nodeX","foo"));
|
||||
should.not.exist(context.get("nodeY","foo"));
|
||||
context.set("nodeX","foo","abc");
|
||||
context.set("nodeY","foo","abc");
|
||||
context.get("nodeX","foo").should.equal("abc");
|
||||
context.get("nodeY","foo").should.equal("abc");
|
||||
|
||||
return context.clean(["nodeX"]).then(function(){
|
||||
should.exist(context.get("nodeX","foo"));
|
||||
should.not.exist(context.get("nodeY","foo"));
|
||||
});
|
||||
});
|
||||
it('should not clean global context', function () {
|
||||
context.set("global", "foo", "abc");
|
||||
context.get("global", "foo").should.equal("abc");
|
||||
|
||||
return context.clean(["global"]).then(function () {
|
||||
should.exist(context.get("global", "foo"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@@ -1,144 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var should = require("should");
|
||||
var sinon = require('sinon');
|
||||
var Context = require("../../../../red/runtime/nodes/context");
|
||||
|
||||
describe('context', function() {
|
||||
beforeEach(function() {
|
||||
Context.init({});
|
||||
});
|
||||
afterEach(function() {
|
||||
Context.clean({allNodes:{}});
|
||||
});
|
||||
it('stores local property',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
should.not.exist(context1.get("foo"));
|
||||
context1.set("foo","test");
|
||||
context1.get("foo").should.eql("test");
|
||||
});
|
||||
it('stores local property - creates parent properties',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
context1.set("foo.bar","test");
|
||||
context1.get("foo").should.eql({bar:"test"});
|
||||
});
|
||||
it('deletes local property',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
context1.set("foo.abc.bar1","test1");
|
||||
context1.set("foo.abc.bar2","test2");
|
||||
context1.get("foo.abc").should.eql({bar1:"test1",bar2:"test2"});
|
||||
context1.set("foo.abc.bar1",undefined);
|
||||
context1.get("foo.abc").should.eql({bar2:"test2"});
|
||||
context1.set("foo.abc",undefined);
|
||||
should.not.exist(context1.get("foo.abc"));
|
||||
context1.set("foo",undefined);
|
||||
should.not.exist(context1.get("foo"));
|
||||
});
|
||||
it('stores flow property',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
should.not.exist(context1.flow.get("foo"));
|
||||
context1.flow.set("foo","test");
|
||||
context1.flow.get("foo").should.eql("test");
|
||||
});
|
||||
it('stores global property',function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
should.not.exist(context1.global.get("foo"));
|
||||
context1.global.set("foo","test");
|
||||
context1.global.get("foo").should.eql("test");
|
||||
});
|
||||
|
||||
it('keeps local context local', function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
var context2 = Context.get("2","flowA");
|
||||
|
||||
should.not.exist(context1.get("foo"));
|
||||
should.not.exist(context2.get("foo"));
|
||||
context1.set("foo","test");
|
||||
|
||||
context1.get("foo").should.eql("test");
|
||||
should.not.exist(context2.get("foo"));
|
||||
});
|
||||
it('flow context accessible to all flow nodes', function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
var context2 = Context.get("2","flowA");
|
||||
|
||||
should.not.exist(context1.flow.get("foo"));
|
||||
should.not.exist(context2.flow.get("foo"));
|
||||
|
||||
context1.flow.set("foo","test");
|
||||
context1.flow.get("foo").should.eql("test");
|
||||
context2.flow.get("foo").should.eql("test");
|
||||
});
|
||||
|
||||
it('flow context not shared to nodes on other flows', function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
var context2 = Context.get("2","flowB");
|
||||
|
||||
should.not.exist(context1.flow.get("foo"));
|
||||
should.not.exist(context2.flow.get("foo"));
|
||||
|
||||
context1.flow.set("foo","test");
|
||||
context1.flow.get("foo").should.eql("test");
|
||||
should.not.exist(context2.flow.get("foo"));
|
||||
});
|
||||
|
||||
it('global context shared to all nodes', function() {
|
||||
var context1 = Context.get("1","flowA");
|
||||
var context2 = Context.get("2","flowB");
|
||||
|
||||
should.not.exist(context1.global.get("foo"));
|
||||
should.not.exist(context2.global.get("foo"));
|
||||
|
||||
context1.global.set("foo","test");
|
||||
context1.global.get("foo").should.eql("test");
|
||||
context2.global.get("foo").should.eql("test");
|
||||
});
|
||||
|
||||
it('deletes context',function() {
|
||||
var context = Context.get("1","flowA");
|
||||
should.not.exist(context.get("foo"));
|
||||
context.set("foo","abc");
|
||||
context.get("foo").should.eql("abc");
|
||||
|
||||
Context.delete("1","flowA");
|
||||
context = Context.get("1","flowA");
|
||||
should.not.exist(context.get("foo"));
|
||||
})
|
||||
|
||||
it('enumerates context keys', function() {
|
||||
var context = Context.get("1","flowA");
|
||||
|
||||
var keys = context.keys();
|
||||
keys.should.be.an.Array();
|
||||
keys.should.be.empty();
|
||||
|
||||
context.set("foo","bar");
|
||||
keys = context.keys();
|
||||
keys.should.have.length(1);
|
||||
keys[0].should.eql("foo");
|
||||
|
||||
context.set("abc.def","bar");
|
||||
keys = context.keys();
|
||||
keys.should.have.length(2);
|
||||
keys[1].should.eql("abc");
|
||||
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
});
|
@@ -287,7 +287,7 @@ describe("storage/localfilesystem/projects/ssh", function() {
|
||||
});
|
||||
|
||||
it('should generate sshkey file with size data', function(done) {
|
||||
this.timeout(10000);
|
||||
this.timeout(20000);
|
||||
var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys');
|
||||
var username = 'test';
|
||||
var options = {
|
||||
@@ -311,7 +311,7 @@ describe("storage/localfilesystem/projects/ssh", function() {
|
||||
});
|
||||
|
||||
it('should generate sshkey file with password & size data', function(done) {
|
||||
this.timeout(10000);
|
||||
this.timeout(20000);
|
||||
var sshkeyDirPath = path.join(userDir, 'projects', '.sshkeys');
|
||||
var username = 'test';
|
||||
var options = {
|
||||
|
@@ -141,7 +141,15 @@ describe("red/util", function() {
|
||||
cloned.res.should.equal(msg.res);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getObjectProperty', function() {
|
||||
it('gets a property beginning with "msg."', function() {
|
||||
// getMessageProperty strips off `msg.` prefixes.
|
||||
// getObjectProperty does not
|
||||
var obj = { msg: { a: "foo"}, a: "bar"};
|
||||
var v = util.getObjectProperty(obj,"msg.a");
|
||||
v.should.eql("foo");
|
||||
})
|
||||
});
|
||||
describe('getMessageProperty', function() {
|
||||
it('retrieves a simple property', function() {
|
||||
var v = util.getMessageProperty({a:"foo"},"msg.a");
|
||||
@@ -169,7 +177,16 @@ describe("red/util", function() {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('setObjectProperty', function() {
|
||||
it('set a property beginning with "msg."', function() {
|
||||
// setMessageProperty strips off `msg.` prefixes.
|
||||
// setObjectProperty does not
|
||||
var obj = {};
|
||||
util.setObjectProperty(obj,"msg.a","bar");
|
||||
obj.should.have.property("msg");
|
||||
obj.msg.should.have.property("a","bar");
|
||||
})
|
||||
});
|
||||
describe('setMessageProperty', function() {
|
||||
it('sets a property', function() {
|
||||
var msg = {a:"foo"};
|
||||
@@ -191,6 +208,11 @@ describe("red/util", function() {
|
||||
util.setMessageProperty(msg,"msg.a.b.c","bar",false);
|
||||
should.not.exist(msg.a.b);
|
||||
})
|
||||
it('does not create missing parent properties with array', function () {
|
||||
var msg = {a:{}};
|
||||
util.setMessageProperty(msg, "msg.a.b[1].c", "bar", false);
|
||||
should.not.exist(msg.a.b);
|
||||
})
|
||||
it('deletes property if value is undefined', function() {
|
||||
var msg = {a:{b:{c:"foo"}}};
|
||||
util.setMessageProperty(msg,"msg.a.b.c",undefined);
|
||||
@@ -227,6 +249,11 @@ describe("red/util", function() {
|
||||
msg.a[2].should.be.instanceOf(Array);
|
||||
msg.a[2][2].should.eql("bar");
|
||||
});
|
||||
it('does not create missing array elements - mid property', function () {
|
||||
var msg = {a:[]};
|
||||
util.setMessageProperty(msg, "msg.a[1][1]", "bar", false);
|
||||
msg.a.should.empty();
|
||||
});
|
||||
it('does not create missing array elements - final property', function() {
|
||||
var msg = {a:{}};
|
||||
util.setMessageProperty(msg,"msg.a.b[2]","bar",false);
|
||||
@@ -275,10 +302,23 @@ describe("red/util", function() {
|
||||
var result = util.evaluateNodeProperty('','date');
|
||||
(Date.now() - result).should.be.approximately(0,50);
|
||||
});
|
||||
it('returns bin', function () {
|
||||
var result = util.evaluateNodeProperty('[1, 2]','bin');
|
||||
result[0].should.eql(1);
|
||||
result[1].should.eql(2);
|
||||
});
|
||||
it('returns msg property',function() {
|
||||
var result = util.evaluateNodeProperty('foo.bar','msg',{},{foo:{bar:"123"}});
|
||||
result.should.eql("123");
|
||||
});
|
||||
it('throws an error if callback is not defined', function (done) {
|
||||
try {
|
||||
util.evaluateNodeProperty(' ','msg',{},{foo:{bar:"123"}});
|
||||
done("should throw an error");
|
||||
} catch (err) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
it('returns flow property',function() {
|
||||
var result = util.evaluateNodeProperty('foo.bar','flow',{
|
||||
context:function() { return {
|
||||
@@ -307,6 +347,14 @@ describe("red/util", function() {
|
||||
},{});
|
||||
result.should.eql("123");
|
||||
});
|
||||
it('returns jsonata result', function () {
|
||||
var result = util.evaluateNodeProperty('$abs(-1)','jsonata',{},{});
|
||||
result.should.eql(1);
|
||||
});
|
||||
it('returns null', function() {
|
||||
var result = util.evaluateNodeProperty(null,'null');
|
||||
(result === null).should.be.true();
|
||||
})
|
||||
describe('environment variable', function() {
|
||||
before(function() {
|
||||
process.env.NR_TEST_A = "foo";
|
||||
@@ -444,6 +492,12 @@ describe("red/util", function() {
|
||||
var result = util.evaluateJSONataExpression(expr,{payload:"hello"});
|
||||
result.should.eql("bar");
|
||||
});
|
||||
it('accesses environment variable from an expression', function() {
|
||||
process.env.UTIL_ENV = 'foo';
|
||||
var expr = util.prepareJSONataExpression('$env("UTIL_ENV")',{});
|
||||
var result = util.evaluateJSONataExpression(expr,{});
|
||||
result.should.eql('foo');
|
||||
});
|
||||
it('handles non-existant flow context variable', function() {
|
||||
var expr = util.prepareJSONataExpression('$flowContext("nonExistant")',{context:function() { return {flow:{get: function(key) { return {'foo':'bar'}[key]}}}}});
|
||||
var result = util.evaluateJSONataExpression(expr,{payload:"hello"});
|
||||
@@ -454,7 +508,267 @@ describe("red/util", function() {
|
||||
var result = util.evaluateJSONataExpression(expr,{payload:"hello"});
|
||||
should.not.exist(result);
|
||||
});
|
||||
|
||||
it('handles async flow context access', function(done) {
|
||||
var expr = util.prepareJSONataExpression('$flowContext("foo")',{context:function() { return {flow:{get: function(key,store,callback) { setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}});
|
||||
util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) {
|
||||
try {
|
||||
should.not.exist(err);
|
||||
value.should.eql("bar");
|
||||
done();
|
||||
} catch(err2) {
|
||||
done(err2);
|
||||
}
|
||||
});
|
||||
})
|
||||
it('handles async global context access', function(done) {
|
||||
var expr = util.prepareJSONataExpression('$globalContext("foo")',{context:function() { return {global:{get: function(key,store,callback) { setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}});
|
||||
util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) {
|
||||
try {
|
||||
should.not.exist(err);
|
||||
value.should.eql("bar");
|
||||
done();
|
||||
} catch(err2) {
|
||||
done(err2);
|
||||
}
|
||||
});
|
||||
})
|
||||
it('handles persistable store in flow context access', function(done) {
|
||||
var storeName;
|
||||
var expr = util.prepareJSONataExpression('$flowContext("foo", "flowStoreName")',{context:function() { return {flow:{get: function(key,store,callback) { storeName = store;setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}});
|
||||
util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) {
|
||||
try {
|
||||
should.not.exist(err);
|
||||
value.should.eql("bar");
|
||||
storeName.should.equal("flowStoreName");
|
||||
done();
|
||||
} catch(err2) {
|
||||
done(err2);
|
||||
}
|
||||
});
|
||||
})
|
||||
it('handles persistable store in global context access', function(done) {
|
||||
var storeName;
|
||||
var expr = util.prepareJSONataExpression('$globalContext("foo", "globalStoreName")',{context:function() { return {global:{get: function(key,store,callback) { storeName = store;setTimeout(()=>{callback(null,{'foo':'bar'}[key])},10)}}}}});
|
||||
util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value) {
|
||||
try {
|
||||
should.not.exist(err);
|
||||
value.should.eql("bar");
|
||||
storeName.should.equal("globalStoreName");
|
||||
done();
|
||||
} catch(err2) {
|
||||
done(err2);
|
||||
}
|
||||
});
|
||||
})
|
||||
it('callbacks with error when invalid expression was specified', function (done) {
|
||||
var expr = util.prepareJSONataExpression('$abc(1)',{});
|
||||
var result = util.evaluateJSONataExpression(expr,{payload:"hello"},function(err,value){
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('encodeObject', function () {
|
||||
it('encodes Error with message', function() {
|
||||
var err = new Error("encode error");
|
||||
err.name = 'encodeError';
|
||||
var msg = {msg:err};
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("error");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.name.should.eql('encodeError');
|
||||
resultJson.message.should.eql('encode error');
|
||||
});
|
||||
it('encodes Error without message', function() {
|
||||
var err = new Error();
|
||||
err.name = 'encodeError';
|
||||
err.toString = function(){return 'error message';}
|
||||
var msg = {msg:err};
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("error");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.name.should.eql('encodeError');
|
||||
resultJson.message.should.eql('error message');
|
||||
});
|
||||
it('encodes Buffer', function() {
|
||||
var msg = {msg:Buffer.from("abc")};
|
||||
var result = util.encodeObject(msg,{maxLength:4});
|
||||
result.format.should.eql("buffer[3]");
|
||||
result.msg[0].should.eql('6');
|
||||
result.msg[1].should.eql('1');
|
||||
result.msg[2].should.eql('6');
|
||||
result.msg[3].should.eql('2');
|
||||
});
|
||||
it('encodes function', function() {
|
||||
var msg = {msg:function(){}};
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("function");
|
||||
result.msg.should.eql('[function]');
|
||||
});
|
||||
it('encodes boolean', function() {
|
||||
var msg = {msg:true};
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("boolean");
|
||||
result.msg.should.eql('true');
|
||||
});
|
||||
it('encodes number', function() {
|
||||
var msg = {msg:123};
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("number");
|
||||
result.msg.should.eql('123');
|
||||
});
|
||||
it('encodes 0', function() {
|
||||
var msg = {msg:0};
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("number");
|
||||
result.msg.should.eql('0');
|
||||
});
|
||||
it('encodes null', function() {
|
||||
var msg = {msg:null};
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("null");
|
||||
result.msg.should.eql('(undefined)');
|
||||
});
|
||||
it('encodes undefined', function() {
|
||||
var msg = {msg:undefined};
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("undefined");
|
||||
result.msg.should.eql('(undefined)');
|
||||
});
|
||||
it('encodes string', function() {
|
||||
var msg = {msg:'1234567890'};
|
||||
var result = util.encodeObject(msg,{maxLength:6});
|
||||
result.format.should.eql("string[10]");
|
||||
result.msg.should.eql('123456...');
|
||||
});
|
||||
describe('encode object', function() {
|
||||
it('object', function() {
|
||||
var msg = { msg:{"foo":"bar"} };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("Object");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.foo.should.eql('bar');
|
||||
});
|
||||
it('object whose name includes error', function() {
|
||||
function MyErrorObj(){
|
||||
this.name = 'my error obj';
|
||||
this.message = 'my error message';
|
||||
};
|
||||
var msg = { msg:new MyErrorObj() };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("MyErrorObj");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.name.should.eql('my error obj');
|
||||
resultJson.message.should.eql('my error message');
|
||||
});
|
||||
it('constructor of IncomingMessage', function() {
|
||||
function IncomingMessage(){};
|
||||
var msg = { msg:new IncomingMessage() };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("Object");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.should.empty();
|
||||
});
|
||||
it('_req key in msg', function() {
|
||||
function Socket(){};
|
||||
var msg = { msg:{"_req":123} };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("Object");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson._req.__enc__.should.eql(true);
|
||||
resultJson._req.type.should.eql('internal');
|
||||
});
|
||||
it('_res key in msg', function() {
|
||||
function Socket(){};
|
||||
var msg = { msg:{"_res":123} };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("Object");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson._res.__enc__.should.eql(true);
|
||||
resultJson._res.type.should.eql('internal');
|
||||
});
|
||||
it('array of error', function() {
|
||||
var msg = { msg:[new Error("encode error")] };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("array[1]");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson[0].should.eql('Error: encode error');
|
||||
});
|
||||
it('long array in msg', function() {
|
||||
var msg = {msg:{array:[1,2,3,4]}};
|
||||
var result = util.encodeObject(msg,{maxLength:2});
|
||||
result.format.should.eql("Object");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.array.__enc__.should.eql(true);
|
||||
resultJson.array.data[0].should.eql(1);
|
||||
resultJson.array.data[1].should.eql(2);
|
||||
resultJson.array.length.should.eql(4);
|
||||
});
|
||||
it('array of string', function() {
|
||||
var msg = { msg:["abcde","12345"] };
|
||||
var result = util.encodeObject(msg,{maxLength:3});
|
||||
result.format.should.eql("array[2]");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson[0].should.eql('abc...');
|
||||
resultJson[1].should.eql('123...');
|
||||
});
|
||||
it('array of function', function() {
|
||||
var msg = { msg:[function(){}] };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("array[1]");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson[0].__enc__.should.eql(true);
|
||||
resultJson[0].type.should.eql('function');
|
||||
});
|
||||
it('array of number', function() {
|
||||
var msg = { msg:[1,2,3] };
|
||||
var result = util.encodeObject(msg,{maxLength:2});
|
||||
result.format.should.eql("array[3]");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.__enc__.should.eql(true);
|
||||
resultJson.data[0].should.eql(1);
|
||||
resultJson.data[1].should.eql(2);
|
||||
resultJson.data.length.should.eql(2);
|
||||
resultJson.length.should.eql(3);
|
||||
});
|
||||
it('array of special number', function() {
|
||||
var msg = { msg:[NaN,Infinity,-Infinity] };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("array[3]");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson[0].__enc__.should.eql(true);
|
||||
resultJson[0].type.should.eql('number');
|
||||
resultJson[0].data.should.eql('NaN');
|
||||
resultJson[1].data.should.eql('Infinity');
|
||||
resultJson[2].data.should.eql('-Infinity');
|
||||
});
|
||||
it('constructor of Buffer in msg', function() {
|
||||
var msg = { msg:{buffer:new Buffer([1,2,3,4])} };
|
||||
var result = util.encodeObject(msg,{maxLength:2});
|
||||
result.format.should.eql("Object");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.buffer.__enc__.should.eql(true);
|
||||
resultJson.buffer.length.should.eql(4);
|
||||
resultJson.buffer.data[0].should.eql(1);
|
||||
resultJson.buffer.data[1].should.eql(2);
|
||||
});
|
||||
it('constructor of ServerResponse', function() {
|
||||
function ServerResponse(){};
|
||||
var msg = { msg: new ServerResponse() };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("Object");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.should.eql('[internal]');
|
||||
});
|
||||
it('constructor of Socket in msg', function() {
|
||||
function Socket(){};
|
||||
var msg = { msg: { socket: new Socket() } };
|
||||
var result = util.encodeObject(msg);
|
||||
result.format.should.eql("Object");
|
||||
var resultJson = JSON.parse(result.msg);
|
||||
resultJson.socket.should.eql('[internal]');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
1
test/resources/file-in-node/test.txt
Normal file
1
test/resources/file-in-node/test.txt
Normal file
@@ -0,0 +1 @@
|
||||
Text file
|
Reference in New Issue
Block a user