Merge branch 'master' into context-store-logging

This commit is contained in:
Nick O'Leary
2018-07-20 20:23:19 +01:00
committed by GitHub
36 changed files with 1352 additions and 143 deletions

View File

@@ -27,7 +27,7 @@ util.inherits(injectNode, nodePage);
var payloadType = {
"flow": 1,
"global": 2,
"string": 3,
"str": 3,
"num": 4,
"bool": 5,
"json": 6,
@@ -43,6 +43,13 @@ var timeType = {
"atASpecificTime": 4,
};
var timeType = {
"none": 1,
"interval": 2,
"intervalBetweenTimes": 3,
"atASpecificTime": 4,
};
injectNode.prototype.setPayload = function(type, value) {
// Open a payload type list.
browser.clickWithWait('//*[contains(@class, "red-ui-typedInput-container")]');

View File

@@ -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;

View 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;

View 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;

View 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;

View 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;

View File

@@ -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;

View File

@@ -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) {

View 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;

View File

@@ -16,17 +16,30 @@
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 nodeCatalog = {
// input
"inject": injectNode,
"httpin": httpinNode,
// output
"debug": debugNode,
"httpResponse": httpResponseNode,
// function
"function": functionNode,
"template": templateNode,
"change": changeNode,
"range": rangeNode,
"httpRequest": httpRequestNode,
"html": htmlNode,
}
function create(type, id) {

View File

@@ -17,11 +17,17 @@
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",
};
function getId(type) {

View File

@@ -24,6 +24,8 @@ 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() {
@@ -46,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);
@@ -150,7 +152,7 @@ describe('cookbook', function() {
var debugNode = workspace.addNode("debug", nodeWidth * 2);
injectNode.edit();
injectNode.setPayload("string", "Started!")
injectNode.setPayload("str", "Started!")
injectNode.setOnce(true);
injectNode.clickOk();
injectNode.connect(debugNode);
@@ -185,4 +187,270 @@ describe('cookbook', function() {
// 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.be.equal('"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 changeNode_setPost = 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();
changeNode_setPost.edit();
changeNode_setPost.ruleSet("post", "msg", "payload", "msg");
changeNode_setPost.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(changeNode_setPost);
changeNode_setPost.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 changeNode_setHeader = 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();
changeNode_setHeader.edit();
changeNode_setHeader.ruleSet("headers", "msg", "{\"content-type\":\"application/json\"}", "json");
changeNode_setHeader.clickOk();
httpinNode.connect(templateNode);
templateNode.connect(changeNode_setHeader);
changeNode_setHeader.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"');
});
});
});

View File

@@ -36,6 +36,9 @@ describe('template node', function() {
function initContext(done) {
Context.init({
contextStorage: {
memory0: { // do not use (for excluding effect fallback)
module: "memory"
},
memory1: {
module: "memory"
},
@@ -337,7 +340,7 @@ describe('template node', function() {
msg.should.have.property('topic', 'bar');
msg.should.have.property('payload', 'foo');
// result is in flow context
n2.context().flow.get("payload", "memory", function (err, val) {
n2.context().flow.get("payload", "memory1", function (err, val) {
val.should.equal("payload=foo");
done();
});
@@ -375,7 +378,7 @@ describe('template node', function() {
msg.should.have.property('topic', 'bar');
msg.should.have.property('payload', 'foo');
// result is in global context
n2.context().global.get("payload", "memory", function (err, val) {
n2.context().global.get("payload", "memory1", function (err, val) {
val.should.equal("payload=foo");
done();
});

View File

@@ -35,6 +35,9 @@ describe('trigger node', function() {
},
memory1: {
module: "memory"
},
memory2: {
module: "memory"
}
}
});
@@ -96,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"} ];
@@ -336,8 +407,8 @@ describe('trigger node', function() {
});
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": "#:(memory0)::foo", "op1type": "flow",
"op2": "#:(memory0)::bar", "op2type": "global", "duration": "20", "wires": [["n2"]], "z": "flow" },
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 () {
@@ -360,8 +431,8 @@ describe('trigger node', function() {
var context = n1.context();
var flow = context.flow;
var global = context.global;
flow.set("foo", "foo", "memory0", function (err) {
global.set("bar", "bar", "memory0", function (err) {
flow.set("foo", "foo", "memory1", function (err) {
global.set("bar", "bar", "memory1", function (err) {
n1.emit("input", { payload: null });
});
});
@@ -372,8 +443,8 @@ describe('trigger node', function() {
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": "#:(memory0)::val", "op1type": "global",
"op2": "#:(memory1)::val", "op2type": "global"
"op1": "#:(memory1)::val", "op1type": "global",
"op2": "#:(memory2)::val", "op2type": "global"
},
{"id": "n2", "type": "helper"}];
helper.load(triggerNode, flow, function () {
@@ -399,8 +470,8 @@ describe('trigger node', function() {
}
});
var global = n1.context().global;
global.set("val", "foo", "memory0", function (err) {
global.set("val", "bar", "memory1", function (err) {
global.set("val", "foo", "memory1", function (err) {
global.set("val", "bar", "memory2", function (err) {
n1.emit("input", { payload: null });
});
});
@@ -411,8 +482,8 @@ describe('trigger node', function() {
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": "#:(memory0)::val", "op1type": "flow",
"op2": "#:(memory1)::val", "op2type": "flow"
"op1": "#:(memory1)::val", "op1type": "flow",
"op2": "#:(memory2)::val", "op2type": "flow"
},
{"id": "n2", "type": "helper"}];
helper.load(triggerNode, flow, function () {
@@ -438,8 +509,8 @@ describe('trigger node', function() {
}
});
var flow = n1.context().flow;
flow.set("val", "foo", "memory0", function (err) {
flow.set("val", "bar", "memory1", function (err) {
flow.set("val", "foo", "memory1", function (err) {
flow.set("val", "bar", "memory2", function (err) {
n1.emit("input", { payload: null });
});
});
@@ -450,8 +521,8 @@ describe('trigger node', function() {
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": "#:(memory0)::val", "op1type": "flow",
"op2": "#:(memory1)::val", "op2type": "global"
"op1": "#:(memory1)::val", "op1type": "flow",
"op2": "#:(memory2)::val", "op2type": "global"
},
{"id": "n2", "type": "helper"}];
helper.load(triggerNode, flow, function () {
@@ -479,8 +550,8 @@ describe('trigger node', function() {
var context = n1.context();
var flow = context.flow;
var global = context.flow;
flow.set("val", "foo", "memory0", function (err) {
global.set("val", "bar", "memory1", function (err) {
flow.set("val", "foo", "memory1", function (err) {
global.set("val", "bar", "memory2", function (err) {
n1.emit("input", { payload: null });
});
});

View File

@@ -379,7 +379,7 @@ describe('switch Node', function() {
singularSwitchTest("empty", true, false, undefined, done);
});
it('should check if payload is empty (0)', function(done) {
singularSwitchTest("empty", true, false, null, done);
singularSwitchTest("empty", true, false, 0, done);
});
it('should check if payload is not empty (string)', function(done) {
@@ -413,7 +413,7 @@ describe('switch Node', function() {
singularSwitchTest("nempty", true, false, undefined, done);
});
it('should check if payload is not empty (0)', function(done) {
singularSwitchTest("nempty", true, false, null, done);
singularSwitchTest("nempty", true, false, 0, done);
});

View File

@@ -1272,6 +1272,25 @@ describe('change Node', function() {
});
});
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';

View File

@@ -53,75 +53,143 @@ describe('file Nodes', function() {
});
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 n2 = helper.getNode("helperNode1");
n2.on("input", function(msg) {
var f = fs.readFileSync(fileToTest);
f.should.have.length(4);
fs.unlinkSync(fileToTest);
msg.should.have.property("payload", "test");
done();
},wait);
});
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) {
msg.should.have.property("payload", data[count]);
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++;
});
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");
// Send two messages to the file
n1.emit("input", {payload:"one"});
n1.emit("input", {payload:"two"});
setTimeout(function() {
var n2 = helper.getNode("helperNode1");
var data = ["one", "two", "three", "four"];
var count = 0;
n2.on("input", function (msg) {
msg.should.have.property("payload", data[count]);
try {
// Check they got appended as expected
var f = fs.readFileSync(fileToTest).toString();
f.should.equal("onetwo");
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);
// 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++;
});
// Send two messages to the file
n1.receive({payload:"one"});
n1.receive({payload:"two"});
});
});
// Send two more messages to the file
n1.emit("input", {payload:"three"});
n1.emit("input", {payload:"four"});
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 {
msg.should.have.property("payload", data[count]);
if (count == 1) {
// Check they got appended as expected
var f = fs.readFileSync(fileToTest).toString();
f.should.equal("onetwo");
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 +199,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,30 +219,23 @@ 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 n2 = helper.getNode("helperNode1");
n2.on("input", function (msg) {
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);
@@ -211,16 +246,20 @@ describe('file Nodes', function() {
f.should.equal("fine\r\n");
}
done();
},wait);
});
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 +269,9 @@ describe('file Nodes', function() {
e.code.should.equal("ENOENT");
done();
}
},wait);
});
n1.receive({payload:"fine"});
});
});

View File

@@ -308,13 +308,21 @@ describe('context', function() {
});
it('should fail when using invalid store name', function(done) {
Context.init({contextStorage:{'Invalid name':"noexist"}});
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(){
@@ -339,6 +347,20 @@ describe('context', 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(){
@@ -419,7 +441,7 @@ describe('context', function() {
Context.load().then(function(){
var context = Context.get("1","flow");
var cb = function(){done("An error occurred")}
context.set("foo","bar","defaultt",cb);
context.set("foo","bar","default",cb);
context.get("foo","default",cb);
context.keys("default",cb);
stubGet.called.should.be.false();
@@ -763,6 +785,93 @@ describe('context', function() {
});
}).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 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("should throw an error.");
}).catch(function () {
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 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("should throw an error.");
}).catch(function () {
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(){

View File

@@ -63,6 +63,15 @@ describe('localfilesystem',function() {
});
});
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){
@@ -240,6 +249,81 @@ describe('localfilesystem',function() {
});
});
});
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() {
@@ -286,6 +370,24 @@ describe('localfilesystem',function() {
});
});
});
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() {
@@ -497,4 +599,131 @@ describe('localfilesystem',function() {
});
});
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;
}
});
});
});

View File

@@ -144,6 +144,32 @@ describe('memory',function() {
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() {
@@ -212,6 +238,14 @@ describe('memory',function() {
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"));
});
});
});
});