Compare commits

...

22 Commits

Author SHA1 Message Date
Dave Conway-Jones
b053e02174 remove httpRoot from setting.js entirely 2021-04-23 16:38:45 +01:00
Dave Conway-Jones
3798167908 Update packages/node_modules/@node-red/runtime/locales/en-US/runtime.json
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2021-04-23 16:36:22 +01:00
Dave Conway-Jones
56fe2014e1 Update packages/node_modules/@node-red/runtime/lib/index.js
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2021-04-23 16:36:15 +01:00
Dave Conway-Jones
fdd0a93bad Deprecate use of httpRoot in settings and add warning
(no change is actual behaviour yet - just warning)
Should we remove option from settings ? or just label it ?
2021-04-23 15:42:57 +01:00
Nick O'Leary
dd12572b1d Allow node16 build to fail for now 2021-04-23 14:30:50 +01:00
Nick O'Leary
719aea2a58 Add Node 16 to travis 2021-04-20 18:38:35 +01:00
Nick O'Leary
68fef169f3 Merge pull request #2944 from node-red/Pull-in-RBE-and-push-out-tail
v2: Pull in RBE node and push out tail
2021-04-20 10:57:37 +01:00
Nick O'Leary
c668201df4 Merge pull request #2931 from node-red/join-default
Join: change default manual mode to object
2021-04-20 10:57:23 +01:00
Nick O'Leary
1d68c8cc87 Merge pull request #2940 from node-red/i18n-update
Update to latest i18n in editor and runtime
2021-04-20 10:57:08 +01:00
Nick O'Leary
b9ac8b42ea Use paletteLabel if set in help sidebar 2021-04-19 21:07:44 +01:00
Dave Conway-Jones
e0c7269b8e bump other refs to bcrypt up to 5.0.1 2021-04-19 13:21:12 +01:00
Dave Conway-Jones
73063df11b Pull in RBE node and push out tail 2021-04-19 13:09:13 +01:00
Nick O'Leary
f8855b83fa Update i18next in util package 2021-04-16 17:11:57 +01:00
Nick O'Leary
0d0459d83d Update to latest i18n in editor and runtime
Fixes #2924
2021-04-16 16:52:12 +01:00
Nick O'Leary
c021b4c368 Merge pull request #2922 from node-red/update-dependencies
Update dependencies
2021-04-15 14:57:07 +01:00
Nick O'Leary
8269490dd1 Join: change default manual mode to object 2021-04-12 14:22:27 +01:00
Nick O'Leary
82ced56bed Update package versions 2021-04-09 14:12:10 +01:00
Nick O'Leary
982b8ea51d Update fs-extra and semver 2021-04-09 13:53:06 +01:00
Nick O'Leary
877c463494 Update to latest sinon 2021-04-09 11:22:57 +01:00
Nick O'Leary
9882582903 Update to latest bcrypt 2021-04-09 10:50:35 +01:00
Nick O'Leary
ba566657f1 Set minimum node version to 12 2021-04-09 10:37:05 +01:00
Nick O'Leary
cb1a178fbf Set 2.0.0-beta.1 version 2021-04-09 10:35:19 +01:00
67 changed files with 1256 additions and 331 deletions

View File

@@ -13,9 +13,7 @@ matrix:
- node_js: "12"
script:
- ./node_modules/.bin/grunt no-coverage
- node_js: "10"
allow_failures:
- node_js: "16"
script:
- ./node_modules/.bin/grunt no-coverage
#- node_js: "8"
# script:
# - ./node_modules/.bin/grunt no-coverage

View File

@@ -208,7 +208,9 @@ module.exports = function(grunt) {
"node_modules/marked/marked.min.js",
"node_modules/dompurify/dist/purify.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/i18next/i18next.min.js",
"node_modules/i18next/i18next.min.js",
"node_modules/i18next-http-backend/i18nextHttpBackend.min.js",
"node_modules/jquery-i18next/jquery-i18next.min.js",
"node_modules/jsonata/jsonata-es5.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js",
"packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js",

View File

@@ -1,6 +1,6 @@
{
"name": "node-red",
"version": "1.3.1",
"version": "2.0.0-beta.1",
"description": "Low-code programming for event-driven applications",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
@@ -41,11 +41,11 @@
"denque": "1.5.0",
"express": "4.17.1",
"express-session": "1.17.1",
"fs-extra": "8.1.0",
"fs-extra": "9.1.0",
"fs.notify": "0.0.4",
"hash-sum": "2.0.0",
"https-proxy-agent": "5.0.0",
"i18next": "15.1.2",
"i18next": "20.2.1",
"iconv-lite": "0.6.2",
"is-utf8": "0.2.1",
"js-yaml": "3.14.0",
@@ -60,9 +60,6 @@
"multer": "1.4.2",
"mustache": "4.2.0",
"node-red-admin": "^0.2.6",
"node-red-node-rbe": "^0.5.0",
"node-red-node-sentiment": "^0.1.6",
"node-red-node-tail": "^0.3.0",
"nopt": "5.0.0",
"oauth2orize": "1.11.0",
"on-headers": "1.0.2",
@@ -71,14 +68,14 @@
"passport-oauth2-client-password": "0.1.2",
"raw-body": "2.4.1",
"request": "2.88.0",
"semver": "6.3.0",
"semver": "7.3.5",
"tar": "6.1.0",
"uglify-js": "3.13.3",
"ws": "6.2.1",
"xml2js": "0.4.23"
},
"optionalDependencies": {
"bcrypt": "3.0.8"
"bcrypt": "5.0.1"
},
"devDependencies": {
"dompurify": "2.2.7",
@@ -87,14 +84,14 @@
"grunt-cli": "~1.4.2",
"grunt-concurrent": "3.0.0",
"grunt-contrib-clean": "~2.0.0",
"grunt-contrib-compress": "1.6.0",
"grunt-contrib-compress": "2.0.0",
"grunt-contrib-concat": "~1.0.1",
"grunt-contrib-copy": "~1.0.0",
"grunt-contrib-jshint": "~2.1.0",
"grunt-contrib-uglify": "~4.0.1",
"grunt-contrib-jshint": "3.0.0",
"grunt-contrib-uglify": "5.0.1",
"grunt-contrib-watch": "~1.1.0",
"grunt-jsdoc": "2.4.1",
"grunt-jsdoc-to-markdown": "5.0.0",
"grunt-jsdoc-to-markdown": "6.0.0",
"grunt-jsonlint": "2.1.3",
"grunt-mkdir": "~1.1.0",
"grunt-npm-command": "~0.1.2",
@@ -102,19 +99,21 @@
"grunt-simple-mocha": "~0.4.1",
"grunt-simple-nyc": "^3.0.1",
"http-proxy": "1.18.1",
"i18next-http-backend": "1.2.1",
"jquery-i18next": "1.2.1",
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
"marked": "2.0.1",
"minami": "1.2.3",
"mocha": "^5.2.0",
"mocha": "8.3.2",
"node-red-node-test-helper": "^0.2.7",
"node-sass": "^5.0.0",
"nodemon": "2.0.7",
"should": "13.2.3",
"sinon": "1.17.7",
"sinon": "10.0.1",
"stoppable": "^1.1.0",
"supertest": "5.0.0"
"supertest": "6.1.3"
},
"engines": {
"node": ">=8"
"node": ">=12"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-api",
"version": "1.3.1",
"version": "2.0.0-beta.1",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,8 +16,8 @@
}
],
"dependencies": {
"@node-red/util": "1.3.1",
"@node-red/editor-client": "1.3.1",
"@node-red/util": "2.0.0-beta.1",
"@node-red/editor-client": "2.0.0-beta.1",
"bcryptjs": "2.4.3",
"body-parser": "1.19.0",
"clone": "2.1.2",
@@ -35,6 +35,6 @@
"ws": "6.2.1"
},
"optionalDependencies": {
"bcrypt": "3.0.6"
"bcrypt": "5.0.1"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-client",
"version": "1.3.1",
"version": "2.0.0-beta.1",
"license": "Apache-2.0",
"repository": {
"type": "git",

View File

@@ -18,53 +18,66 @@ RED.i18n = (function() {
var apiRootUrl;
function detectLanguage() {
return navigator.language
}
return {
init: function(options, done) {
apiRootUrl = options.apiRootUrl||"";
var preferredLanguage = localStorage.getItem("editor-language");
var opts = {
resGetPath: apiRootUrl+'locales/__ns__?lng=__lng__',
dynamicLoad: false,
load:'current',
ns: {
namespaces: ["editor","node-red","jsonata","infotips"],
defaultNs: "editor"
backend: {
loadPath: apiRootUrl+'locales/__ns__?lng=__lng__',
},
lng: 'en-US',
// debug: true,
preload:['en-US'],
ns: ["editor","node-red","jsonata","infotips"],
defaultNS: "editor",
fallbackLng: ['en-US'],
useCookie: false,
returnObjectTrees: true
returnObjects: true,
interpolation: {
unescapeSuffix: 'HTML',
escapeValue: false,
prefix: '__',
suffix: '__'
}
};
if (preferredLanguage) {
opts.lng = preferredLanguage;
}
i18n.init(opts,function() {
i18next.use(i18nextHttpBackend).init(opts,function() {
done();
});
jqueryI18next.init(i18next, $, { handleName: 'i18n' });
RED["_"] = function() {
var v = i18n.t.apply(null,arguments);
var v = i18next.t.apply(i18next,arguments);
if (typeof v === 'string') {
return v;
} else {
return arguments[0];
}
}
},
lang: function() {
// Gets the active message catalog language. This is based on what
// locale the editor is using and what languages are available.
//
var preferredLangs = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
var preferredLangs = [localStorage.getItem("editor-language")|| detectLanguage()].concat(i18next.languages);
var knownLangs = RED.settings.theme("languages")||["en-US"];
for (var i=0;i<preferredLangs.length;i++) {
if (knownLangs.indexOf(preferredLangs[i]) > -1) {
return preferredLangs[i]
}
}
return 'end-US'
return 'en-US'
},
loadNodeCatalog: function(namespace,done) {
var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
var languageList = [localStorage.getItem("editor-language")|| detectLanguage()].concat(i18next.languages);
var toLoad = languageList.length;
languageList.forEach(function(lang) {
$.ajax({
@@ -74,7 +87,7 @@ RED.i18n = (function() {
cache: false,
url: apiRootUrl+'nodes/'+namespace+'/messages?lng='+lang,
success: function(data) {
i18n.addResourceBundle(lang,namespace,data);
i18next.addResourceBundle(lang,namespace,data);
toLoad--;
if (toLoad === 0) {
done();
@@ -86,7 +99,7 @@ RED.i18n = (function() {
},
loadNodeCatalogs: function(done) {
var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
var languageList = [localStorage.getItem("editor-language")|| detectLanguage()].concat(i18next.languages);
var toLoad = languageList.length;
languageList.forEach(function(lang) {
@@ -99,7 +112,7 @@ RED.i18n = (function() {
success: function(data) {
var namespaces = Object.keys(data);
namespaces.forEach(function(ns) {
i18n.addResourceBundle(lang,ns,data[ns]);
i18next.addResourceBundle(lang,ns,data[ns]);
});
toLoad--;
if (toLoad === 0) {
@@ -111,7 +124,7 @@ RED.i18n = (function() {
},
loadPluginCatalogs: function(done) {
var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
var languageList = [localStorage.getItem("editor-language")|| detectLanguage()].concat(i18next.languages);
var toLoad = languageList.length;
languageList.forEach(function(lang) {
@@ -124,7 +137,7 @@ RED.i18n = (function() {
success: function(data) {
var namespaces = Object.keys(data);
namespaces.forEach(function(ns) {
i18n.addResourceBundle(lang,ns,data[ns]);
i18next.addResourceBundle(lang,ns,data[ns]);
});
toLoad--;
if (toLoad === 0) {
@@ -133,6 +146,7 @@ RED.i18n = (function() {
}
});
})
}
},
detectLanguage: detectLanguage
}
})();

View File

@@ -36,7 +36,7 @@ var RED = (function() {
}
function loadPlugins(done) {
loader.reportProgress(RED._("event.loadPlugins",{count:""}), 17)
var lang = localStorage.getItem("editor-language")||i18n.detectLanguage();
var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
$.ajax({
headers: {
@@ -176,7 +176,7 @@ var RED = (function() {
function loadNodes() {
loader.reportProgress(RED._("event.loadNodes",{count:""}), 30)
var lang = localStorage.getItem("editor-language")||i18n.detectLanguage();
var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
$.ajax({
headers: {

View File

@@ -233,7 +233,7 @@ RED.sidebar.help = (function() {
var div = $('<div>',{class:"red-ui-info-outline-item"});
RED.utils.createNodeIcon(n).appendTo(div);
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
$('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).text(n.name||n.type).appendTo(contentDiv);
$('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).text(n.name||n._def.paletteLabel||n.type).appendTo(contentDiv);
return div;
}
@@ -248,7 +248,8 @@ RED.sidebar.help = (function() {
title = subflowNode.name || nodeType;
} else {
helpText = RED.nodes.getNodeHelp(nodeType)||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
title = nodeType;
var _def = RED.nodes.registry.getNodeType(nodeType);
title = (_def && _def.paletteLabel)?_def.paletteLabel:nodeType;
}
setInfoText(title, helpText, helpSection);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,93 @@
<script type="text/html" data-template-name="rbe">
<div class="form-row">
<label for="node-input-func"><i class="fa fa-wrench"></i> <span data-i18n="rbe.label.func"></span></label>
<select type="text" id="node-input-func" style="width:70%;">
<option value="rbe" data-i18n="rbe.opts.rbe"></option>
<option value="rbei" data-i18n="rbe.opts.rbei"></option>
<option value="deadbandEq" data-i18n="rbe.opts.deadbandEq"></option>
<option value="deadband" data-i18n="rbe.opts.deadband"></option>
<option value="narrowbandEq" data-i18n="rbe.opts.narrowbandEq"></option>
<option value="narrowband" data-i18n="rbe.opts.narrowband"></option>
</select>
</div>
<div class="form-row" id="node-bandgap">
<label for="node-input-gap">&nbsp;</label>
<input type="text" id="node-input-gap" data-i18n="[placeholder]rbe.placeholder.bandgap" style="width:95px;">
<select type="text" id="node-input-inout" style="width:54%;">
<option value="out" data-i18n="rbe.opts.out"></option>
<option value="in" data-i18n="rbe.opts.in"></option>
</select>
</div>
<div class="form-row" id="node-startvalue">
<label for="node-input-start"><i class="fa fa-thumb-tack"></i> <span data-i18n="rbe.label.start"></span></label>
<input type="text" id="node-input-start" data-i18n="[placeholder]rbe.placeholder.start" style="width:70%;">
</div>
<div class="form-row">
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
<input type="text" id="node-input-property" style="width:70%;"/>
</div>
<div class="form-row">
<label> </label>
<input type="checkbox" id="node-input-septopics" style="display:inline-block; width:20px; vertical-align:baseline;">
<span data-i18n="rbe.label.septopics"></span> <input type="text" id="node-input-topi" style="width:27%;"/>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="rbe.label.name"></span></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]rbe.label.name" style="width:70%;">
</div>
</script>
<script type="text/javascript">
RED.nodes.registerType("rbe", {
color:"#E2D96E",
category: 'function',
defaults: {
name: {value:""},
func: {value:"rbe"},
gap: {value:"",validate:RED.validators.regex(/^(\d*[.]*\d*|)(%|)$/)},
start: {value:""},
inout: {value:"out"},
septopics: {value:true},
property: {value:"payload",required:true},
topi: {value:"topic",required:true}
},
inputs:1,
outputs:1,
icon: "rbe.png",
paletteLabel: "filter",
label: function() {
var ll = (this.func||"").replace("Eq","").replace("rbei",this._("rbe.rbe")).replace("rbe",this._("rbe.rbe"))||this._("rbe.rbe");
return this.name||ll||this._("rbe.rbe");
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
if (this.property === undefined) {
$("#node-input-property").val("payload");
}
if (this.septopics === undefined) {
$("#node-input-septopics").prop('checked', true);
}
$("#node-input-property").typedInput({default:'msg',types:['msg']});
$("#node-input-topi").typedInput({default:'msg',types:['msg']});
//$( "#node-input-gap" ).spinner({min:0});
if ($("#node-input-inout").val() === null) {
$("#node-input-inout").val("out");
}
$("#node-input-func").on("change",function() {
if (($("#node-input-func").val() === "rbe")||($("#node-input-func").val() === "rbei")) {
$("#node-bandgap").hide();
} else {
$("#node-bandgap").show();
}
if (($("#node-input-func").val() === "narrowband")||($("#node-input-func").val() === "narrowbandEq")) {
$("#node-startvalue").show();
} else {
$("#node-startvalue").hide();
}
});
}
});
</script>

View File

@@ -0,0 +1,97 @@
module.exports = function(RED) {
"use strict";
function RbeNode(n) {
RED.nodes.createNode(this,n);
this.func = n.func || "rbe";
this.gap = n.gap || "0";
this.start = n.start || '';
this.inout = n.inout || "out";
this.pc = false;
if (this.gap.substr(-1) === "%") {
this.pc = true;
this.gap = parseFloat(this.gap);
}
this.g = this.gap;
this.property = n.property || "payload";
this.topi = n.topi || "topic";
this.septopics = true;
if (n.septopics !== undefined && n.septopics === false) {
this.septopics = false;
}
var node = this;
node.previous = {};
this.on("input",function(msg) {
var topic;
try {
topic = RED.util.getMessageProperty(msg,node.topi);
}
catch(e) { }
if (msg.hasOwnProperty("reset")) {
if (node.septopics && topic && (typeof topic === "string") && (topic !== "")) {
delete node.previous[msg.topic];
}
else { node.previous = {}; }
}
var value = RED.util.getMessageProperty(msg,node.property);
if (value !== undefined) {
var t = "_no_topic";
if (node.septopics) { t = topic || t; }
if ((this.func === "rbe") || (this.func === "rbei")) {
var doSend = (this.func !== "rbei") || (node.previous.hasOwnProperty(t)) || false;
if (typeof(value) === "object") {
if (typeof(node.previous[t]) !== "object") { node.previous[t] = {}; }
if (!RED.util.compareObjects(value, node.previous[t])) {
node.previous[t] = RED.util.cloneMessage(value);
if (doSend) { node.send(msg); }
}
}
else {
if (value !== node.previous[t]) {
node.previous[t] = RED.util.cloneMessage(value);
if (doSend) { node.send(msg); }
}
}
}
else {
var n = parseFloat(value);
if (!isNaN(n)) {
if ((typeof node.previous[t] === 'undefined') && (this.func === "narrowband")) {
if (node.start === '') { node.previous[t] = n; }
else { node.previous[t] = node.start; }
}
if (node.pc) { node.gap = Math.abs(node.previous[t] * node.g / 100) || 0; }
else { node.gap = Number(node.gap); }
if ((node.previous[t] === undefined) && (node.func === "narrowbandEq")) { node.previous[t] = n; }
if (node.previous[t] === undefined) { node.previous[t] = n - node.gap - 1; }
if (Math.abs(n - node.previous[t]) === node.gap) {
if ((this.func === "deadbandEq")||(this.func === "narrowband")) {
if (node.inout === "out") { node.previous[t] = n; }
node.send(msg);
}
}
else if (Math.abs(n - node.previous[t]) > node.gap) {
if (this.func === "deadband" || this.func === "deadbandEq") {
if (node.inout === "out") { node.previous[t] = n; }
node.send(msg);
}
}
else if (Math.abs(n - node.previous[t]) < node.gap) {
if ((this.func === "narrowband")||(this.func === "narrowbandEq")) {
if (node.inout === "out") { node.previous[t] = n; }
node.send(msg);
}
}
if (node.inout === "in") { node.previous[t] = n; }
}
else {
node.warn(RED._("rbe.warn.nonumber"));
}
}
} // ignore msg with no payload property.
});
}
RED.nodes.registerType("rbe",RbeNode);
}

View File

@@ -201,7 +201,7 @@
defaults: {
name: {value:""},
mode: {value:"auto"},
build: { value:"string"},
build: { value:"object"},
property: { value:"payload", validate:RED.validators.typedInput("propertyType")},
propertyType: { value:"msg"},
key: {value:"topic"},

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

View File

@@ -0,0 +1,40 @@
<script type="text/html" data-help-name="rbe">
<p>Report by Exception (RBE) - Daten-Weiterleitung nur bei Änderung der Nutzdaten (Payload).
Der Node kann auch blockieren oder weiterleiten, wenn die Wertänderung eine Grenze überschreitet (Totband- und Nahband-Modus).</p>
<h3>Eingangsdaten</h3>
<dl class="message-properties">
<dt>payload
<span class="property-type">number | string | (object)</span>
</dt>
<dd>Der RBE-Modus mit Prüfung auf Wertänderung akzeptiert Zahlen (numbers), Zeichenfolgen (string) und einfache Objekte (object).
Bei den anderen wertvergleichenden Modies müssen analysierbare (parseable) Zahlenwerte übergeben werden.</dd>
<dt class="optional">topic <span class="property-type">string</span>
</dt>
<dd>Wenn vorgegeben erfolgt die Auswertung separat für jedes Topic</dd>
<dt class="optional">reset<span class="property-type">any</span></dt>
<dd>Wenn gesetzt wird/werden der/die gespeicherte(n) Wert(e) rückgesetzt</dd>
</dl>
<h3>Ausgangsdaten</h3>
<dl class="message-properties">
<dt>payload
<span class="property-type">wie Eingangsdaten</span>
</dt>
<dd>Wenn Bedingung erfüllt, sind die Ausgangsdaten gleich den Eingangsdaten</dd>
</dl>
<h3>Details</h3>
<p>Im <i>RBE</i>-Modus mit Prüfung auf Wertänderung blockiert dieser Node die Datenweitergabe bis
<code>msg.payload</code> (oder die eingestellte Eigenschaft) verändert ist gegenüber dessen vorherigen Wert.
Wenn benötigt, wird der Anfangswert ignoriert, sodass beim Start nichts gesendet wird.</p>
<p>In den <i>Totband</i>-Modies werden die Eingangswerte geblockt,
<i>bis</i> die Wertänderung größer oder größer-gleich ist als &plusmn; des Bandes um den voherigen Wert.</p>
<p>In den <i>Nahband</i>-Modies werden die Eingangswerte geblockt,
<i>wenn</i> die Wertänderung größer oder größer-gleich ist als &plusmn; des Bandes um den voherigen Wert.
Dies ist beispielsweise nützlich, um Ausreißer eines fehlerhaften Sensors zu ignorieren.</p>
<p>In den Totband und Nahband-Modies müssen die Eingangswerte analysierbare (parseable) Zahlenwerte sein und
beide unterstützen auch % (prozentuale Angabe), d.h. der Node sendet nur, wenn der Eingangswert mehr als x% vom vorherigen Wert abweicht.</p>
<p>Die Totband- und Nahband-Modies erlauben den Vergleich entweder gegen den letzten gültigen Ausgangswert,
dieses zum Ignorieren von Werten außerhalb des gültigen Bereichs, oder gegen den des vorherigen Eingangswertes,
welches den Sollwert rücksetzt, was einen allmähligen Drift (Totband) oder einen eine schrittweise Veränderung (Nahband) ermöglicht.</p>
<p><b>Hinweis</b>: Dieser Node arbeitet auf per-<code>msg.topic</code>-Basis.
Dies bedeutet, dass ein einzelner rbe-Node mehrere verschiedene Topics parallel bearbeiten kann.</p>
</script>

View File

@@ -1000,5 +1000,32 @@
"too-many": "Zu viele anstehende Nachrichten im <span style=\"background-color:Gainsboro\">batch</span>-Node",
"unexpected": "Unerwarteter Modus",
"no-parts": "Keine parts-Eigenschaft in Nachricht"
},
"rbe": {
"rbe": "filter",
"label": {
"func": "Modus",
"init": "Sende Anfangswert",
"start": "Startwert",
"name": "Name",
"septopics": "Modus für jedes msg.topic separat anwenden"
},
"placeholder":{
"bandgap": "z.B. 10 oder 5%",
"start": "Leer lassen, um erste empfangenen Daten zu nutzen"
},
"opts": {
"rbe": "Blockieren bis Wertänderung",
"rbei": "Blockieren bis Wertänderung (Anfangswert ignorieren)",
"deadband": "Blockieren bis Wertänderung ist größer als",
"deadbandEq": "Blockieren bis Wertänderung ist größer-gleich",
"narrowband": "Blockieren wenn Wertänderung ist größer als",
"narrowbandEq": "Blockieren wenn Wertänderung ist größer-gleich",
"in": "verglichen mit letzten Eingangswert",
"out": "verglichen mit letzten gültigen Ausgangswert"
},
"warn": {
"nonumber": "Keine Zahl gefunden in den Nutzdaten (Payload)"
}
}
}

View File

@@ -0,0 +1,41 @@
<script type="text/html" data-help-name="rbe">
<p>Report by Exception (RBE) node - only passes on data if the payload has changed.
It can also block unless, or ignore if the value changes by a specified amount (Dead- and Narrowband mode).</p>
<h3>Inputs</h3>
<dl class="message-properties">
<dt>payload
<span class="property-type">number | string | (object)</span>
</dt>
<dd>RBE mode will accept numbers, strings, and simple objects.
Other modes must provide a parseable number.</dd>
<dt class="optional">topic <span class="property-type">string</span>
</dt>
<dd>if specified the function will work on a per topic basis. This property can be set by configuration.</dd>
<dt class="optional">reset<span class="property-type">any</span></dt>
<dd>if set clears the stored value for the specified msg.topic, or
all topics if msg.topic is not specified.</dd>
</dl>
<h3>Outputs</h3>
<dl class="message-properties">
<dt>payload
<span class="property-type">as per input</span>
</dt>
<dd>If triggered the output will be the same as the input.</dd>
</dl>
<h3>Details</h3>
<p>In RBE mode this node will block until the <code>msg.payload</code>,
(or selected property) value is different to the previous one.
If required it can ignore the intial value, so as not to send anything at start.</p>
<p>The <a href="https://en.wikipedia.org/wiki/Deadband" target="_blank">Deadband</a> modes will block the incoming value
<i>unless</i> its change is greater or greater-equal than &plusmn; the band gap away from a previous value.</p>
<p>The Narrowband modes will block the incoming value,
<i>if</i> its change is greater or greater-equal than &plusmn; the band gap away from the previous value.
It is useful for ignoring outliers from a faulty sensor for example.</p>
<p>Both in Deadband and Narrowband modes the incoming value must contain a parseable number and
both also supports % - only sends if/unless the input differs by more than x% of the original value.</p>
<p>Both Deadband and Narrowband allow comparison against either the previous valid output value, thus
ignoring any values out of range, or the previous input value, which resets the set point, thus allowing
gradual drift (deadband), or a step change (narrowband).</p>
<p><b>Note:</b> This works on a per <code>msg.topic</code> basis, though this can be changed to another property if desired.
This means that a single rbe node can handle multiple different topics at the same time.</p>
</script>

View File

@@ -1001,5 +1001,32 @@
"too-many" : "too many pending messages in batch node",
"unexpected" : "unexpected mode",
"no-parts" : "no parts property in message"
},
"rbe": {
"rbe": "filter",
"label": {
"func": "Mode",
"init": "Send initial value",
"start": "Start value",
"name": "Name",
"septopics": "Apply mode separately for each "
},
"placeholder":{
"bandgap": "e.g. 10 or 5%",
"start": "leave blank to use first data received"
},
"opts": {
"rbe": "block unless value changes",
"rbei": "block unless value changes (ignore initial value)",
"deadband": "block unless value change is greater than",
"deadbandEq": "block unless value change is greater or equal to",
"narrowband": "block if value change is greater than",
"narrowbandEq": "block if value change is greater or equal to",
"in": "compared to last input value",
"out": "compared to last valid output value"
},
"warn": {
"nonumber": "no number found in payload"
}
}
}

View File

@@ -0,0 +1,31 @@
<!-- Source revision: https://github.com/node-red/node-red-nodes/commit/467907776088422882076f46d85e25601449564d -->
<script type="text/html" data-help-name="rbe">
<p>Report by Exception(例外データの報告)ノード - ペイロードの値が変化した場合だけデータを送信</p>
<p>値が指定した量変化するまでブロックすることもできます- 不感帯(deadband)モード</p>
<h3>入力</h3> <dl class="message-properties">
<dt>payload
<span class="property-type">数値 | 文字列 | (オブジェクト)</span>
</dt>
<dd>RBEモードでは数値文字列シンプルなオブジェクトを受け付けます他のモードではパース可能な数値を指定します</dd>
<dt class="optional">topic <span class="property-type">文字列</span>
</dt>
<dd>指定するとトピックごとに動作します</dd>
<dt class="optional">reset<span class="property-type">任意</span></dt>
<dd>値を設定すると保存した値をクリアしますmsg.topicを指定した場合は対応する値指定しなければ全てのトピックが対象となります</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload
<span class="property-type">入力と同じ</span>
</dt>
<dd>トリガー条件を満たした場合入力を出力として送信</dd>
</dl>
<h3>詳細</h3>
<p>RBEモードでは<code>msg.payload</code></p>
<p>不感帯モードでは入力データはパース可能な数値でなければなりません以前の入力値に対する差分が指定値より大きな場合にのみメッセージを出力します</p>
<p>不感帯モードでは%による指定もサポートしています入力と前の値の差分がX%より大きな場合に出力を行います</p>
<p>狭帯域(narrowband)モードでは前の値に対する差分が一定値より大きな場合に入力ペイロードをブロックしますこのモードは故障したセンサから発生する外れ値を無視する時などに有用です</p>
<p>不感帯モードと狭帯域モードでは以前の有効出力値もしくは以前の入力値との比較ができます有効出力値を用いると範囲外の値を無視することが入力値を用いると設定点がリセットされるため漸次的変化(不感帯モード)もしくは段階的変化(狭帯域モード)が可能です</p>
<p><b>:</b> <code>msg.topic</code>rbe</p>
</script>

View File

@@ -999,5 +999,30 @@
"too-many": "batchード内で保持しているメッセージが多すぎます",
"unexpected": "想定外のモード",
"no-parts": "メッセージにpartsプロパティがありません"
},
"rbe": {
"label": {
"func": "動作",
"init": "初期値を送付",
"start": "初期値",
"name": "名前"
},
"placeholder": {
"bandgap": "例:10、5%",
"start": "最初に受け取った値を用いる場合は空欄"
},
"opts": {
"rbe": "値が変化した時のみメッセージを中継",
"rbei": "値が変化した時のみメッセージを中継(初期値を無視)",
"deadband": "値が指定した変化量を超える時のみメッセージを中継",
"deadbandEq": "値が指定した変化量以上の時のみメッセージを中継",
"narrowband": "値が指定した変化量を超えない時のみメッセージを中継",
"narrowbandEq": "値が指定した変化量以上でない時のみメッセージを中継",
"in": "最後の入力値と比較",
"out": "最後の出力値と比較"
},
"warn": {
"nonumber": "ペイロードに数値が含まれていません"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/nodes",
"version": "1.3.1",
"version": "2.0.0-beta.1",
"license": "Apache-2.0",
"repository": {
"type": "git",
@@ -24,7 +24,7 @@
"cors": "2.8.5",
"cron": "1.7.2",
"denque": "1.5.0",
"fs-extra": "8.1.0",
"fs-extra": "9.1.0",
"fs.notify": "0.0.4",
"hash-sum": "2.0.0",
"https-proxy-agent": "5.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/registry",
"version": "1.3.1",
"version": "2.0.0-beta.1",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,8 +16,8 @@
}
],
"dependencies": {
"@node-red/util": "1.3.1",
"semver": "6.3.0",
"@node-red/util": "2.0.0-beta.1",
"semver": "7.3.5",
"tar": "6.1.0",
"uglify-js": "3.13.3"
}

View File

@@ -181,6 +181,9 @@ function start() {
if (settings.settingsFile) {
log.info(log._("runtime.paths.settings",{path:settings.settingsFile}));
}
if (settings.httpRoot !== undefined) {
log.warn(log._("server.deprecatedOption",{old:"httpRoot", new: "httpNodeRoot/httpAdminRoot"));
}
if (settings.httpStatic) {
log.info(log._("runtime.paths.httpStatic",{path:path.resolve(settings.httpStatic)}));
}

View File

@@ -42,7 +42,7 @@
"uninstall-failed-long": "Uninstall of module __name__ failed:",
"uninstalled": "Uninstalled module: __name__"
},
"deprecatedOption": "Use of __old__ is deprecated. Use __new__ instead",
"deprecatedOption": "Use of __old__ is DEPRECATED. Use __new__ instead",
"unable-to-listen": "Unable to listen on __listenpath__",
"port-in-use": "Error: port in use",
"uncaught-exception": "Uncaught Exception:",
@@ -50,7 +50,7 @@
"now-running": "Server now running at __listenpath__",
"failed-to-start": "Failed to start server:",
"headless-mode": "Running in headless mode",
"httpadminauth-deprecated": "use of httpAdminAuth is deprecated. Use adminAuth instead",
"httpadminauth-deprecated": "Use of httpAdminAuth is DEPRECATED. Use adminAuth instead",
"https": {
"refresh-interval": "Refreshing https settings every __interval__ hours",
"settings-refreshed": "Server https settings have been refreshed",

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/runtime",
"version": "1.3.1",
"version": "2.0.0-beta.1",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,12 +16,12 @@
}
],
"dependencies": {
"@node-red/registry": "1.3.1",
"@node-red/util": "1.3.1",
"@node-red/registry": "2.0.0-beta.1",
"@node-red/util": "2.0.0-beta.1",
"async-mutex": "0.3.1",
"clone": "2.1.2",
"express": "4.17.1",
"fs-extra": "8.1.0",
"fs-extra": "9.1.0",
"json-stringify-safe": "5.0.1"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/util",
"version": "1.3.1",
"version": "2.0.0-beta.1",
"license": "Apache-2.0",
"repository": {
"type": "git",
@@ -16,7 +16,7 @@
],
"dependencies": {
"clone": "2.1.2",
"i18next": "15.1.2",
"i18next": "20.2.1",
"json-stringify-safe": "5.0.1",
"jsonata": "1.8.4",
"lodash.clonedeep": "^4.5.0",

View File

@@ -1,6 +1,6 @@
{
"name": "node-red",
"version": "1.3.1",
"version": "2.0.0-beta.1",
"description": "Low-code programming for event-driven applications",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
@@ -31,24 +31,22 @@
"flow"
],
"dependencies": {
"@node-red/editor-api": "1.3.1",
"@node-red/runtime": "1.3.1",
"@node-red/util": "1.3.1",
"@node-red/nodes": "1.3.1",
"@node-red/editor-api": "2.0.0-beta.1",
"@node-red/runtime": "2.0.0-beta.1",
"@node-red/util": "2.0.0-beta.1",
"@node-red/nodes": "2.0.0-beta.1",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"express": "4.17.1",
"fs-extra": "8.1.0",
"fs-extra": "9.1.0",
"node-red-admin": "^0.2.6",
"node-red-node-rbe": "^0.5.0",
"node-red-node-tail": "^0.3.0",
"nopt": "5.0.0",
"semver": "6.3.0"
"semver": "7.3.5"
},
"optionalDependencies": {
"bcrypt": "3.0.6"
"bcrypt": "5.0.1"
},
"engines": {
"node": ">=8"
"node": ">=12"
}
}

View File

@@ -96,10 +96,6 @@ module.exports = {
// disabled.
//httpNodeRoot: '/red-nodes',
// The following property can be used in place of 'httpAdminRoot' and 'httpNodeRoot',
// to apply the same root to both parts.
//httpRoot: '/red',
// When httpAdminRoot is used to move the UI to a different root path, the
// following property can be used to identify a directory of static content
// that should be served at http://localhost:1880/.

View File

@@ -483,7 +483,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',
var spy = sinon.stub(RED.util, 'evaluateNodeProperty').callsFake(
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"]] },
@@ -742,7 +742,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',
var spy = sinon.stub(RED.util, 'evaluateNodeProperty').callsFake(
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"]] },

View File

@@ -53,7 +53,7 @@ describe('exec node', function() {
it('should exec a simple command', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:false, append:"", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
var spy = sinon.stub(child_process, 'exec',
var spy = sinon.stub(child_process, 'exec').callsFake(
function(arg1, arg2, arg3, arg4) {
// arg3(error,stdout,stderr);
arg3(null,arg1,arg1.toUpperCase());
@@ -137,7 +137,7 @@ describe('exec node', function() {
it('should exec a simple command with extra parameters', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:"payload", append:"more", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
var spy = sinon.stub(child_process, 'exec',
var spy = sinon.stub(child_process, 'exec').callsFake(
function(arg1, arg2, arg3, arg4) {
//console.log(arg1);
// arg3(error,stdout,stderr);
@@ -193,7 +193,7 @@ describe('exec node', function() {
it('should be able to return a binary buffer', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:true, append:"more", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
var spy = sinon.stub(child_process, 'exec',
var spy = sinon.stub(child_process, 'exec').callsFake(
function(arg1, arg2, arg3, arg4) {
//console.log(arg1);
// arg3(error,stdout,stderr);
@@ -325,7 +325,7 @@ describe('exec node', function() {
it('should return the rc for a failing command', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"error", addpay:false, append:"", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
var spy = sinon.stub(child_process, 'exec',
var spy = sinon.stub(child_process, 'exec').callsFake(
function(arg1, arg2, arg3, arg4) {
//console.log(arg1);
// arg3(error,stdout,stderr);
@@ -388,7 +388,7 @@ describe('exec node', function() {
it('should preserve existing properties on msg object', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"echo", addpay:false, append:"", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
var spy = sinon.stub(child_process, 'exec',
var spy = sinon.stub(child_process, 'exec').callsFake(
function(arg1, arg2, arg3, arg4) {
// arg3(error,stdout,stderr);
arg3(null,arg1,arg1.toUpperCase());
@@ -455,7 +455,7 @@ describe('exec node', function() {
it('should preserve existing properties on msg object for a failing command', function(done) {
var flow = [{id:"n1",type:"exec",wires:[["n2"],["n3"],["n4"]],command:"error", addpay:false, append:"", oldrc:"false"},
{id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}];
var spy = sinon.stub(child_process, 'exec',
var spy = sinon.stub(child_process, 'exec').callsFake(
function(arg1, arg2, arg3, arg4) {
// arg3(error,stdout,stderr);
arg3({code: 1},arg1,arg1.toUpperCase());

View File

@@ -0,0 +1,538 @@
var should = require("should");
var helper = require("node-red-node-test-helper");
var testNode = require("nr-test-utils").require("@node-red/nodes/core/function/rbe.js");
describe('rbe node', function() {
"use strict";
beforeEach(function(done) {
helper.startServer(done);
});
afterEach(function(done) {
helper.unload().then(function() {
helper.stopServer(done);
});
});
it("should be loaded with correct defaults", function(done) {
var flow = [{"id":"n1", "type":"rbe", "name":"rbe1", "wires":[[]]}];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
n1.should.have.property("name", "rbe1");
n1.should.have.property("func", "rbe");
n1.should.have.property("gap", "0");
done();
});
});
it('should only send output if payload changes - with multiple topics (rbe)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"rbe", gap:"0", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.a.property("payload", "a");
c+=1;
}
else if (c === 1) {
msg.should.have.a.property("payload", 2);
c+=1;
}
else if (c == 2) {
msg.should.have.a.property("payload");
msg.payload.should.have.a.property("b",1);
msg.payload.should.have.a.property("c",2);
c+=1;
}
else if (c == 3) {
msg.should.have.a.property("payload",true);
c+=1;
}
else if (c == 4) {
msg.should.have.a.property("payload",false);
c+=1;
}
else if (c == 5) {
msg.should.have.a.property("payload",true);
c+=1;
}
else if (c == 6) {
msg.should.have.a.property("topic","a");
msg.should.have.a.property("payload",1);
c+=1;
}
else if (c == 7) {
msg.should.have.a.property("topic","b");
msg.should.have.a.property("payload",1);
c+=1;
}
else {
c += 1;
msg.should.have.a.property("topic","c");
msg.should.have.a.property("payload",1);
done();
}
});
n1.emit("input", {payload:"a"});
n1.emit("input", {payload:"a"});
n1.emit("input", {payload:"a"});
n1.emit("input", {payload:2});
n1.emit("input", {payload:2});
n1.emit("input", {payload:{b:1,c:2}});
n1.emit("input", {payload:{c:2,b:1}});
n1.emit("input", {payload:{c:2,b:1}});
n1.emit("input", {payload:true});
n1.emit("input", {payload:false});
n1.emit("input", {payload:false});
n1.emit("input", {payload:true});
n1.emit("input", {topic:"a",payload:1});
n1.emit("input", {topic:"b",payload:1});
n1.emit("input", {topic:"b",payload:1});
n1.emit("input", {topic:"a",payload:1});
n1.emit("input", {topic:"c",payload:1});
});
});
it('should ignore multiple topics if told to (rbe)', function(done) {
var flow = [{id:"n1", type:"rbe", func:"rbe", gap:"0", septopics:false, wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.a.property("payload", "a");
c+=1;
}
else if (c === 1) {
msg.should.have.a.property("payload", 2);
c+=1;
}
else if (c == 2) {
msg.should.have.a.property("payload");
msg.payload.should.have.a.property("b",1);
msg.payload.should.have.a.property("c",2);
c+=1;
}
else if (c == 3) {
msg.should.have.a.property("payload",true);
c+=1;
}
else if (c == 4) {
msg.should.have.a.property("payload",false);
c+=1;
}
else if (c == 5) {
msg.should.have.a.property("payload",true);
c+=1;
}
else if (c == 6) {
msg.should.have.a.property("topic","a");
msg.should.have.a.property("payload",1);
c+=1;
}
else {
msg.should.have.a.property("topic","a");
msg.should.have.a.property("payload",2);
done();
}
});
n1.emit("input", {topic:"a",payload:"a"});
n1.emit("input", {topic:"b",payload:"a"});
n1.emit("input", {topic:"c",payload:"a"});
n1.emit("input", {topic:"a",payload:2});
n1.emit("input", {topic:"b",payload:2});
n1.emit("input", {payload:{b:1,c:2}});
n1.emit("input", {payload:{c:2,b:1}});
n1.emit("input", {payload:{c:2,b:1}});
n1.emit("input", {topic:"a",payload:true});
n1.emit("input", {topic:"b",payload:false});
n1.emit("input", {topic:"c",payload:false});
n1.emit("input", {topic:"d",payload:true});
n1.emit("input", {topic:"a",payload:1});
n1.emit("input", {topic:"b",payload:1});
n1.emit("input", {topic:"c",payload:1});
n1.emit("input", {topic:"d",payload:1});
n1.emit("input", {topic:"a",payload:2});
});
});
it('should only send output if another chosen property changes - foo (rbe)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"rbe", gap:"0", property:"foo", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.a.property("foo", "a");
c+=1;
}
else if (c === 1) {
msg.should.have.a.property("foo", "b");
c+=1;
}
else {
msg.should.have.a.property("foo");
msg.foo.should.have.a.property("b",1);
msg.foo.should.have.a.property("c",2);
done();
}
});
n1.emit("input", {foo:"a"});
n1.emit("input", {payload:"a"});
n1.emit("input", {foo:"a"});
n1.emit("input", {payload:"a"});
n1.emit("input", {foo:"a"});
n1.emit("input", {foo:"b"});
n1.emit("input", {foo:{b:1,c:2}});
n1.emit("input", {foo:{c:2,b:1}});
n1.emit("input", {payload:{c:2,b:1}});
});
});
it('should only send output if payload changes - ignoring first value (rbei)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"rbei", gap:"0", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.a.property("payload", "b");
msg.should.have.a.property("topic", "a");
c+=1;
}
else if (c === 1) {
msg.should.have.a.property("payload", "b");
msg.should.have.a.property("topic", "b");
c+=1;
}
else if (c === 2) {
msg.should.have.a.property("payload", "c");
msg.should.have.a.property("topic", "a");
c+=1;
}
else {
msg.should.have.a.property("payload", "c");
msg.should.have.a.property("topic", "b");
done();
}
});
n1.emit("input", {payload:"a", topic:"a"});
n1.emit("input", {payload:"a", topic:"b"});
n1.emit("input", {payload:"a", topic:"a"});
n1.emit("input", {payload:"b", topic:"a"});
n1.emit("input", {payload:"b", topic:"b"});
n1.emit("input", {payload:"c", topic:"a"});
n1.emit("input", {payload:"c", topic:"b"});
});
});
it('should send output if queue is reset (rbe)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"rbe", gap:"0", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.a.property("payload", "a");
c+=1;
}
else if (c === 1) {
msg.should.have.a.property("payload", "b");
c+=1;
}
else if (c === 2) {
msg.should.have.a.property("payload", "a");
c+=1;
}
else if (c === 3) {
msg.should.have.a.property("payload", "b");
c+=1;
}
else if (c === 4) {
msg.should.have.a.property("payload", "b");
c+=1;
}
else if (c === 5) {
msg.should.have.a.property("payload", "b");
c+=1;
}
else if (c === 6) {
msg.should.have.a.property("payload", "a");
c+=1;
}
else {
msg.should.have.a.property("payload", "c");
done();
}
});
n1.emit("input", {topic:"a", payload:"a"});
n1.emit("input", {topic:"a", payload:"a"});
n1.emit("input", {topic:"b", payload:"b"});
n1.emit("input", {reset:true}); // reset all
n1.emit("input", {topic:"a", payload:"a"});
n1.emit("input", {topic:"b", payload:"b"});
n1.emit("input", {topic:"b", payload:"b"});
n1.emit("input", {topic:"b", reset:""}); // reset b
n1.emit("input", {topic:"b", payload:"b"});
n1.emit("input", {topic:"a", payload:"a"});
n1.emit("input", {reset:""}); // reset all
n1.emit("input", {topic:"b", payload:"b"});
n1.emit("input", {topic:"a", payload:"a"});
n1.emit("input", {topic:"c"}); // don't reset a non topic
n1.emit("input", {topic:"b", payload:"b"});
n1.emit("input", {topic:"a", payload:"a"});
n1.emit("input", {topic:"c", payload:"c"});
});
});
it('should only send output if x away from original value (deadbandEq)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"deadbandEq", gap:"10", inout:"out", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
c = c + 1;
if (c === 1) {
msg.should.have.a.property("payload", 0);
}
else if (c === 2) {
msg.should.have.a.property("payload", 10);
}
else if (c == 3) {
msg.should.have.a.property("payload", 20);
done();
}
});
n1.emit("input", {payload:0});
n1.emit("input", {payload:2});
n1.emit("input", {payload:4});
n1.emit("input", {payload:6});
n1.emit("input", {payload:8});
n1.emit("input", {payload:10});
n1.emit("input", {payload:15});
n1.emit("input", {payload:20});
});
});
it('should only send output if more than x away from original value (deadband)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"deadband", gap:"10", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
c = c + 1;
//console.log(c,msg);
if (c === 1) {
msg.should.have.a.property("payload", 0);
}
else if (c === 2) {
msg.should.have.a.property("payload", 20);
}
else {
msg.should.have.a.property("payload", "5 deg");
done();
}
});
n1.emit("input", {payload:0});
n1.emit("input", {payload:2});
n1.emit("input", {payload:4});
n1.emit("input", {payload:"6 deg"});
n1.emit("input", {payload:8});
n1.emit("input", {payload:20});
n1.emit("input", {payload:15});
n1.emit("input", {payload:"5 deg"});
});
});
it('should only send output if more than x% away from original value (deadband)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"deadband", gap:"10%", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
c = c + 1;
if (c === 1) {
msg.should.have.a.property("payload", 100);
}
else if (c === 2) {
msg.should.have.a.property("payload", 111);
}
else if (c === 3) {
msg.should.have.a.property("payload", 135);
done();
}
});
n1.emit("input", {payload:100});
n1.emit("input", {payload:95});
n1.emit("input", {payload:105});
n1.emit("input", {payload:111});
n1.emit("input", {payload:120});
n1.emit("input", {payload:135});
});
});
it('should warn if no number found in deadband mode', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"deadband", gap:"10", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
c += 1;
});
setTimeout( function() {
c.should.equal(0);
helper.log().called.should.be.true;
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "rbe";
});
logEvents.should.have.length(1);
var msg = logEvents[0][0];
msg.should.have.property('level', helper.log().WARN);
msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'rbe');
msg.should.have.property('msg', 'rbe.warn.nonumber');
done();
},50);
n1.emit("input", {payload:"banana"});
});
});
it('should not send output if x away or greater from original value (narrowbandEq)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"narrowbandEq", gap:"10", inout:"out", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
c = c + 1;
//console.log(c,msg);
if (c === 1) {
msg.should.have.a.property("payload", 0);
}
else if (c === 2) {
msg.should.have.a.property("payload", 5);
}
else if (c === 3) {
msg.should.have.a.property("payload", 10);
done();
}
});
n1.emit("input", {payload:0});
n1.emit("input", {payload:10});
n1.emit("input", {payload:5});
n1.emit("input", {payload:15});
n1.emit("input", {payload:10});
n1.emit("input", {payload:20});
n1.emit("input", {payload:25});
});
});
it('should not send output if more than x away from original value (narrowband)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"narrowband", gap:"10", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.a.property("payload", 0);
}
else if (c === 1) {
msg.should.have.a.property("payload","6 deg");
}
else {
msg.should.have.a.property("payload", "5 deg");
done();
}
c += 1;
});
n1.emit("input", {payload:0});
n1.emit("input", {payload:20});
n1.emit("input", {payload:40});
n1.emit("input", {payload:"6 deg"});
n1.emit("input", {payload:18});
n1.emit("input", {payload:20});
n1.emit("input", {payload:50});
n1.emit("input", {payload:"5 deg"});
});
});
it('should send output if gap is 0 and input doesnt change (narrowband)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"narrowband", gap:"0", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.a.property("payload", 1);
}
else if (c === 4) {
msg.should.have.a.property("payload",1);
done();
}
c += 1;
});
n1.emit("input", {payload:1});
n1.emit("input", {payload:1});
n1.emit("input", {payload:1});
n1.emit("input", {payload:1});
n1.emit("input", {payload:0});
n1.emit("input", {payload:1});
});
});
it('should not send output if more than x away from original value (narrowband in step mode)', function(done) {
var flow = [{"id":"n1", "type":"rbe", func:"narrowband", gap:"10", inout:"in", start:"500", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(testNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
var c = 0;
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.a.property("payload", 55);
}
else if (c === 1) {
msg.should.have.a.property("payload", 205);
done();
}
c += 1;
});
n1.emit("input", {payload:50});
n1.emit("input", {payload:55});
n1.emit("input", {payload:200});
n1.emit("input", {payload:205});
});
});
});

View File

@@ -391,7 +391,7 @@ describe('file Nodes', function() {
it('should fail to write to a ro file', function(done) {
// Stub file write so we can make writes fail
var spy = sinon.stub(fs, 'createWriteStream', function(arg1,arg2) {
var spy = sinon.stub(fs, 'createWriteStream').callsFake(function(arg1,arg2) {
var ws = {};
ws.on = function(e,d) { throw("Stub error message"); }
ws.write = function(e,d) { }
@@ -421,7 +421,7 @@ describe('file Nodes', function() {
it('should fail to append to a ro file', function(done) {
// Stub file write so we can make writes fail
var spy = sinon.stub(fs, 'createWriteStream', function(arg1,arg2) {
var spy = sinon.stub(fs, 'createWriteStream').callsFake(function(arg1,arg2) {
var ws = {};
ws.on = function(e,d) { throw("Stub error message"); }
ws.write = function(e,d) { }
@@ -451,7 +451,7 @@ describe('file Nodes', function() {
it('should cope with failing to delete a file', function(done) {
// Stub file write so we can make writes fail
var spy = sinon.stub(fs, 'unlink', function(arg,arg2) { arg2(new Error("Stub error message")); });
var spy = sinon.stub(fs, 'unlink').callsFake(function(arg,arg2) { arg2(new Error("Stub error message")); });
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":"delete"}];
helper.load(fileNode, flow, function() {
@@ -477,7 +477,7 @@ describe('file Nodes', function() {
it('should fail to create a new directory if not asked to do so (append)', function(done) {
// 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, 'appendFile', function(arg,arg2,arg3,arg4){ arg4(new Error("Stub error message")); });
//var spy = sinon.stub(fs, 'appendFile').callsFake(function(arg,arg2,arg3,arg4){ arg4(new Error("Stub error message")); });
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest2, "appendNewline":true, "overwriteFile":false}];
helper.load(fileNode, flow, function() {
@@ -508,7 +508,7 @@ describe('file Nodes', function() {
}
// 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); });
var spy = sinon.stub(fs, "ensureDir").callsFake(function(arg1,arg2,arg3,arg4) { arg2(null); });
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest2, "appendNewline":true, "overwriteFile":false, "createDir":true}];
helper.load(fileNode, flow, function() {
var n1 = helper.getNode("fileNode1");
@@ -531,7 +531,7 @@ describe('file Nodes', function() {
it('should fail to create a new directory if not asked to do so (overwrite)', function(done) {
// 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, 'appendFile', function(arg,arg2,arg3,arg4){ arg4(new Error("Stub error message")); });
//var spy = sinon.stub(fs, 'appendFile').callsFake(function(arg,arg2,arg3,arg4){ arg4(new Error("Stub error message")); });
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest2, "appendNewline":false, "overwriteFile":true}];
helper.load(fileNode, flow, function() {
@@ -557,7 +557,7 @@ describe('file Nodes', function() {
it('should try to create a new directory if asked to do so (overwrite)', function(done) {
// 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); });
var spy = sinon.stub(fs, "ensureDir").callsFake(function(arg1,arg2,arg3,arg4) { arg2(null); });
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest2, "appendNewline":true, "overwriteFile":true, "createDir":true}];
helper.load(fileNode, flow, function() {

View File

@@ -45,35 +45,35 @@ describe("api/admin/index", function() {
};
before(function() {
mockList.forEach(function(m) {
sinon.stub(m,"init",function(){});
sinon.stub(m,"init").callsFake(function(){});
});
sinon.stub(auth,"needsPermission", function(permission) {
sinon.stub(auth,"needsPermission").callsFake(function(permission) {
return function(req,res,next) {
permissionChecks[permission] = (permissionChecks[permission]||0)+1;
next();
};
});
sinon.stub(flows,"get",stubApp);
sinon.stub(flows,"post",stubApp);
sinon.stub(flows,"get").callsFake(stubApp);
sinon.stub(flows,"post").callsFake(stubApp);
sinon.stub(flow,"get",stubApp);
sinon.stub(flow,"post",stubApp);
sinon.stub(flow,"delete",stubApp);
sinon.stub(flow,"put",stubApp);
sinon.stub(flow,"get").callsFake(stubApp);
sinon.stub(flow,"post").callsFake(stubApp);
sinon.stub(flow,"delete").callsFake(stubApp);
sinon.stub(flow,"put").callsFake(stubApp);
sinon.stub(nodes,"getAll",stubApp);
sinon.stub(nodes,"post",stubApp);
sinon.stub(nodes,"getModule",stubApp);
sinon.stub(nodes,"putModule",stubApp);
sinon.stub(nodes,"delete",stubApp);
sinon.stub(nodes,"getSet",stubApp);
sinon.stub(nodes,"putSet",stubApp);
sinon.stub(nodes,"getModuleCatalog",stubApp);
sinon.stub(nodes,"getModuleCatalogs",stubApp);
sinon.stub(nodes,"getAll").callsFake(stubApp);
sinon.stub(nodes,"post").callsFake(stubApp);
sinon.stub(nodes,"getModule").callsFake(stubApp);
sinon.stub(nodes,"putModule").callsFake(stubApp);
sinon.stub(nodes,"delete").callsFake(stubApp);
sinon.stub(nodes,"getSet").callsFake(stubApp);
sinon.stub(nodes,"putSet").callsFake(stubApp);
sinon.stub(nodes,"getModuleCatalog").callsFake(stubApp);
sinon.stub(nodes,"getModuleCatalogs").callsFake(stubApp);
sinon.stub(context,"get",stubApp);
sinon.stub(context,"delete",stubApp);
sinon.stub(context,"get").callsFake(stubApp);
sinon.stub(context,"delete").callsFake(stubApp);
});
after(function() {
mockList.forEach(function(m) {

View File

@@ -41,7 +41,7 @@ describe("api/admin/nodes", function() {
app.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,nodes.putSet);
app.get("/getIcons",nodes.getIcons);
app.delete(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,nodes.delete);
sinon.stub(apiUtil,"determineLangFromHeaders", function() {
sinon.stub(apiUtil,"determineLangFromHeaders").callsFake(function() {
return "en-US";
});
});

View File

@@ -29,7 +29,7 @@ var theme = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme");
describe("api/editor/settings", function() {
before(function() {
sinon.stub(theme,"settings",function() { return { existing: 123, test: 456 };});
sinon.stub(theme,"settings").callsFake(function() { return { existing: 123, test: 456 };});
app = express();
app.use(bodyParser.json());
app.get("/settings",info.runtimeSettings);

View File

@@ -58,7 +58,7 @@ describe("api/auth/index",function() {
describe("revoke", function() {
it("revokes a token", function(done) {
var revokeToken = sinon.stub(Tokens,"revoke",function() {
var revokeToken = sinon.stub(Tokens,"revoke").callsFake(function() {
return Promise.resolve();
});
@@ -79,8 +79,8 @@ describe("api/auth/index",function() {
describe("login", function() {
beforeEach(function() {
sinon.stub(Tokens,"init",function(){});
sinon.stub(Users,"init",function(){});
sinon.stub(Tokens,"init").callsFake(function(){});
sinon.stub(Users,"init").callsFake(function(){});
});
afterEach(function() {
Tokens.init.restore();
@@ -119,8 +119,8 @@ describe("api/auth/index",function() {
});
describe("needsPermission", function() {
beforeEach(function() {
sinon.stub(Tokens,"init",function(){});
sinon.stub(Users,"init",function(){});
sinon.stub(Tokens,"init").callsFake(function(){});
sinon.stub(Users,"init").callsFake(function(){});
});
afterEach(function() {
Tokens.init.restore();
@@ -135,7 +135,7 @@ describe("api/auth/index",function() {
it('no-ops if adminAuth not set', function(done) {
sinon.stub(passport,"authenticate",function(scopes,opts) {
sinon.stub(passport,"authenticate").callsFake(function(scopes,opts) {
return function(req,res,next) {
}
});
@@ -147,12 +147,12 @@ describe("api/auth/index",function() {
})
});
it('skips auth if req.user undefined', function(done) {
sinon.stub(passport,"authenticate",function(scopes,opts) {
sinon.stub(passport,"authenticate").callsFake(function(scopes,opts) {
return function(req,res,next) {
next();
}
});
sinon.stub(Permissions,"hasPermission",function(perm) { return true });
sinon.stub(Permissions,"hasPermission").callsFake(function(perm) { return true });
auth.init({adminAuth:{}});
var func = auth.needsPermission("foo");
func({user:null},{},function() {
@@ -167,12 +167,12 @@ describe("api/auth/index",function() {
});
it('passes for valid user permission', function(done) {
sinon.stub(passport,"authenticate",function(scopes,opts) {
sinon.stub(passport,"authenticate").callsFake(function(scopes,opts) {
return function(req,res,next) {
next();
}
});
sinon.stub(Permissions,"hasPermission",function(perm) { return true });
sinon.stub(Permissions,"hasPermission").callsFake(function(perm) { return true });
auth.init({adminAuth:{}});
var func = auth.needsPermission("foo");
func({user:true,authInfo: { scope: "read"}},{},function() {
@@ -189,12 +189,12 @@ describe("api/auth/index",function() {
});
it('rejects for invalid user permission', function(done) {
sinon.stub(passport,"authenticate",function(scopes,opts) {
sinon.stub(passport,"authenticate").callsFake(function(scopes,opts) {
return function(req,res,next) {
next();
}
});
sinon.stub(Permissions,"hasPermission",function(perm) { return false });
sinon.stub(Permissions,"hasPermission").callsFake(function(perm) { return false });
auth.init({adminAuth:{}});
var func = auth.needsPermission("foo");
func({user:true,authInfo: { scope: "read"}},{

View File

@@ -35,7 +35,7 @@ describe("api/auth/strategies", function() {
});
it('Handles authentication failure',function(done) {
userAuthentication = sinon.stub(Users,"authenticate",function(username,password) {
userAuthentication = sinon.stub(Users,"authenticate").callsFake(function(username,password) {
return Promise.resolve(null);
});
@@ -51,7 +51,7 @@ describe("api/auth/strategies", function() {
});
it('Handles scope overreach',function(done) {
userAuthentication = sinon.stub(Users,"authenticate",function(username,password) {
userAuthentication = sinon.stub(Users,"authenticate").callsFake(function(username,password) {
return Promise.resolve({username:"user",permissions:"read"});
});
@@ -67,11 +67,11 @@ describe("api/auth/strategies", function() {
});
it('Creates new token on authentication success',function(done) {
userAuthentication = sinon.stub(Users,"authenticate",function(username,password) {
userAuthentication = sinon.stub(Users,"authenticate").callsFake(function(username,password) {
return Promise.resolve({username:"user",permissions:"*"});
});
var tokenDetails = {};
var tokenCreate = sinon.stub(Tokens,"create",function(username,client,scope) {
var tokenCreate = sinon.stub(Tokens,"create").callsFake(function(username,client,scope) {
tokenDetails.username = username;
tokenDetails.client = client;
tokenDetails.scope = scope;
@@ -98,7 +98,7 @@ describe("api/auth/strategies", function() {
describe("Anonymous Strategy", function() {
it('Succeeds if anon user enabled',function(done) {
var userDefault = sinon.stub(Users,"default",function() {
var userDefault = sinon.stub(Users,"default").callsFake(function() {
return Promise.resolve("anon");
});
strategies.anonymousStrategy._success = strategies.anonymousStrategy.success;
@@ -111,7 +111,7 @@ describe("api/auth/strategies", function() {
strategies.anonymousStrategy.authenticate({});
});
it('Fails if anon user not enabled',function(done) {
var userDefault = sinon.stub(Users,"default",function() {
var userDefault = sinon.stub(Users,"default").callsFake(function() {
return Promise.resolve(null);
});
strategies.anonymousStrategy._fail = strategies.anonymousStrategy.fail;
@@ -130,10 +130,10 @@ describe("api/auth/strategies", function() {
describe("Tokens Strategy", function() {
it('Succeeds if tokens user enabled custom header',function(done) {
var userTokens = sinon.stub(Users,"tokens",function(token) {
var userTokens = sinon.stub(Users,"tokens").callsFake(function(token) {
return Promise.resolve("tokens-"+token);
});
var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
var userTokenHeader = sinon.stub(Users,"tokenHeader").callsFake(function(token) {
return "x-test-token";
});
strategies.tokensStrategy._success = strategies.tokensStrategy.success;
@@ -146,10 +146,10 @@ describe("api/auth/strategies", function() {
strategies.tokensStrategy.authenticate({headers:{"x-test-token":"1234"}});
});
it('Succeeds if tokens user enabled default header',function(done) {
var userTokens = sinon.stub(Users,"tokens",function(token) {
var userTokens = sinon.stub(Users,"tokens").callsFake(function(token) {
return Promise.resolve("tokens-"+token);
});
var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
var userTokenHeader = sinon.stub(Users,"tokenHeader").callsFake(function(token) {
return "authorization";
});
strategies.tokensStrategy._success = strategies.tokensStrategy.success;
@@ -162,10 +162,10 @@ describe("api/auth/strategies", function() {
strategies.tokensStrategy.authenticate({headers:{"authorization":"Bearer 1234"}});
});
it('Fails if tokens user not enabled',function(done) {
var userTokens = sinon.stub(Users,"tokens",function() {
var userTokens = sinon.stub(Users,"tokens").callsFake(function() {
return Promise.resolve(null);
});
var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
var userTokenHeader = sinon.stub(Users,"tokenHeader").callsFake(function(token) {
return "authorization";
});
strategies.tokensStrategy._fail = strategies.tokensStrategy.fail;
@@ -185,7 +185,7 @@ describe("api/auth/strategies", function() {
describe("Bearer Strategy", function() {
it('Rejects invalid token',function(done) {
var getToken = sinon.stub(Tokens,"get",function(token) {
var getToken = sinon.stub(Tokens,"get").callsFake(function(token) {
return Promise.resolve(null);
});
@@ -202,10 +202,10 @@ describe("api/auth/strategies", function() {
});
});
it('Accepts valid token',function(done) {
var getToken = sinon.stub(Tokens,"get",function(token) {
var getToken = sinon.stub(Tokens,"get").callsFake(function(token) {
return Promise.resolve({user:"user",scope:"scope"});
});
var getUser = sinon.stub(Users,"get",function(username) {
var getUser = sinon.stub(Users,"get").callsFake(function(username) {
return Promise.resolve("aUser");
});
@@ -224,10 +224,10 @@ describe("api/auth/strategies", function() {
});
});
it('Fail if no user for token',function(done) {
var getToken = sinon.stub(Tokens,"get",function(token) {
var getToken = sinon.stub(Tokens,"get").callsFake(function(token) {
return Promise.resolve({user:"user",scope:"scope"});
});
var getUser = sinon.stub(Users,"get",function(username) {
var getUser = sinon.stub(Users,"get").callsFake(function(username) {
return Promise.resolve(null);
});
@@ -250,7 +250,7 @@ describe("api/auth/strategies", function() {
describe("Client Password Strategy", function() {
it('Accepts valid client',function(done) {
var testClient = {id:"node-red-editor",secret:"not_available"};
var getClient = sinon.stub(Clients,"get",function(client) {
var getClient = sinon.stub(Clients,"get").callsFake(function(client) {
return Promise.resolve(testClient);
});
@@ -268,7 +268,7 @@ describe("api/auth/strategies", function() {
});
it('Rejects invalid client secret',function(done) {
var testClient = {id:"node-red-editor",secret:"not_available"};
var getClient = sinon.stub(Clients,"get",function(client) {
var getClient = sinon.stub(Clients,"get").callsFake(function(client) {
return Promise.resolve(testClient);
});
@@ -285,7 +285,7 @@ describe("api/auth/strategies", function() {
});
});
it('Rejects invalid client id',function(done) {
var getClient = sinon.stub(Clients,"get",function(client) {
var getClient = sinon.stub(Clients,"get").callsFake(function(client) {
return Promise.resolve(null);
});
strategies.clientPasswordStrategy("invalid_id","invalid_secret",function(err,client) {
@@ -303,7 +303,7 @@ describe("api/auth/strategies", function() {
var userAuthentication;
it('Blocks after 5 failures',function(done) {
userAuthentication = sinon.stub(Users,"authenticate",function(username,password) {
userAuthentication = sinon.stub(Users,"authenticate").callsFake(function(username,password) {
return Promise.resolve(null);
});
for (var z=0; z<5; z++) {

View File

@@ -58,7 +58,7 @@ describe("api/editor/comms", function() {
var url;
var port;
before(function(done) {
sinon.stub(Users,"default",function() { return Promise.resolve(null);});
sinon.stub(Users,"default").callsFake(function() { return Promise.resolve(null);});
server = stoppable(http.createServer(function(req,res){app(req,res)}));
comms.init(server, {}, {comms: mockComms});
server.listen(listenPort, address);
@@ -126,7 +126,7 @@ describe("api/editor/comms", function() {
var url;
var port;
before(function(done) {
sinon.stub(Users,"default",function() { return Promise.resolve(null);});
sinon.stub(Users,"default").callsFake(function() { return Promise.resolve(null);});
server = stoppable(http.createServer(function(req,res){app(req,res)}));
comms.init(server, {disableEditor:true}, {comms: mockComms});
server.listen(listenPort, address);
@@ -164,7 +164,7 @@ describe("api/editor/comms", function() {
var url;
var port;
before(function(done) {
sinon.stub(Users,"default",function() { return Promise.resolve(null);});
sinon.stub(Users,"default").callsFake(function() { return Promise.resolve(null);});
server = stoppable(http.createServer(function(req,res){app(req,res)}));
comms.init(server, {httpAdminRoot:"/adminPath"}, {comms: mockComms});
server.listen(listenPort, address);
@@ -202,7 +202,7 @@ describe("api/editor/comms", function() {
var url;
var port;
before(function(done) {
sinon.stub(Users,"default",function() { return Promise.resolve(null);});
sinon.stub(Users,"default").callsFake(function() { return Promise.resolve(null);});
server = stoppable(http.createServer(function(req,res){app(req,res)}));
comms.init(server, {httpAdminRoot:"/adminPath/"}, {comms: mockComms});
server.listen(listenPort, address);
@@ -240,7 +240,7 @@ describe("api/editor/comms", function() {
var url;
var port;
before(function(done) {
sinon.stub(Users,"default",function() { return Promise.resolve(null);});
sinon.stub(Users,"default").callsFake(function() { return Promise.resolve(null);});
server = stoppable(http.createServer(function(req,res){app(req,res)}));
comms.init(server, {httpAdminRoot:"adminPath"}, {comms: mockComms});
server.listen(listenPort, address);
@@ -278,7 +278,7 @@ describe("api/editor/comms", function() {
var url;
var port;
before(function(done) {
sinon.stub(Users,"default",function() { return Promise.resolve(null);});
sinon.stub(Users,"default").callsFake(function() { return Promise.resolve(null);});
server = stoppable(http.createServer(function(req,res){app(req,res)}));
comms.init(server, {webSocketKeepAliveTime: 100}, {comms: mockComms});
server.listen(listenPort, address);
@@ -344,22 +344,22 @@ describe("api/editor/comms", function() {
var getToken;
var getUserToken;
before(function(done) {
getDefaultUser = sinon.stub(Users,"default",function() { return Promise.resolve(null);});
getUser = sinon.stub(Users,"get", function(username) {
getDefaultUser = sinon.stub(Users,"default").callsFake(function() { return Promise.resolve(null);});
getUser = sinon.stub(Users,"get").callsFake(function(username) {
if (username == "fred") {
return Promise.resolve({permissions:"read"});
} else {
return Promise.resolve(null);
}
});
getUserToken = sinon.stub(Users,"tokens", function(token) {
getUserToken = sinon.stub(Users,"tokens").callsFake(function(token) {
if (token == "abcde") {
return Promise.resolve({user:"wilma", permissions:"*"})
} else {
return Promise.resolve(null);
}
});
getToken = sinon.stub(Tokens,"get",function(token) {
getToken = sinon.stub(Tokens,"get").callsFake(function(token) {
if (token == "1234") {
return Promise.resolve({user:"fred",scope:["*"]});
} else if (token == "5678") {
@@ -483,7 +483,7 @@ describe("api/editor/comms", function() {
var port;
var getDefaultUser;
before(function(done) {
getDefaultUser = sinon.stub(Users,"default",function() { return Promise.resolve({permissions:"read"});});
getDefaultUser = sinon.stub(Users,"default").callsFake(function() { return Promise.resolve({permissions:"read"});});
server = stoppable(http.createServer(function(req,res){app(req,res)}));
comms.init(server, {adminAuth:{}}, {comms: mockComms});
server.listen(listenPort, address);

View File

@@ -32,8 +32,8 @@ describe("api/editor/index", function() {
var app;
describe("disabled the editor", function() {
beforeEach(function() {
sinon.stub(comms,'init', function(){});
sinon.stub(info,'init', function(){});
sinon.stub(comms,'init').callsFake(function(){});
sinon.stub(info,'init').callsFake(function(){});
});
afterEach(function() {
comms.init.restore();
@@ -54,13 +54,13 @@ describe("api/editor/index", function() {
var errors = [];
var session_data = {};
before(function() {
sinon.stub(auth,'needsPermission',function(permission) {
sinon.stub(auth,'needsPermission').callsFake(function(permission) {
return function(req,res,next) { next(); }
});
mockList.forEach(function(m) {
sinon.stub(NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/"+m),"init",function(){});
sinon.stub(NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/"+m),"init").callsFake(function(){});
});
sinon.stub(NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme"),"app",function(){ return express()});
sinon.stub(NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme"),"app").callsFake(function(){ return express()});
});
after(function() {
mockList.forEach(function(m) {
@@ -72,7 +72,7 @@ describe("api/editor/index", function() {
});
before(function() {
sinon.stub(log,"error",function(err) { errors.push(err)})
sinon.stub(log,"error").callsFake(function(err) { errors.push(err)})
app = editorApi.init({},{httpNodeRoot:true, httpAdminRoot: true,disableEditor:false,exportNodeSettings:function(){}},{
isStarted: () => Promise.resolve(isStarted)
});

View File

@@ -50,9 +50,9 @@ describe("api/editor/locales", function() {
locales.init({});
// bit of a mess of internal workings
sinon.stub(i18n.i,'changeLanguage',function(lang,callback) { if (callback) {callback();}});
sinon.stub(i18n.i,'changeLanguage').callsFake(function(lang,callback) { if (callback) {callback();}});
if (i18n.i.getResourceBundle) {
sinon.stub(i18n.i,'getResourceBundle',function(lang, namespace) {return {namespace:namespace, lang:lang};});
sinon.stub(i18n.i,'getResourceBundle').callsFake(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
@@ -121,7 +121,7 @@ describe("api/editor/locales", function() {
// var app;
// before(function() {
// // bit of a mess of internal workings
// sinon.stub(i18n,'catalog',function(namespace, lang) {
// sinon.stub(i18n,'catalog').callsFake(function(namespace, lang) {
// return {
// "node-red": "should not return",
// "test-module-a-id": "test-module-a-catalog",

View File

@@ -29,7 +29,7 @@ var theme = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme");
describe("api/editor/settings", function() {
before(function() {
sinon.stub(theme,"settings",function() { return { existing: 123, test: 456 };});
sinon.stub(theme,"settings").callsFake(function() { return { existing: 123, test: 456 };});
app = express();
app.use(bodyParser.json());
app.get("/settings/user",function(req,res,next) {req.user = "fred"; next()}, info.userSettings);

View File

@@ -27,7 +27,7 @@ var theme = NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme");
describe("api/editor/theme", function () {
beforeEach(function () {
sinon.stub(fs, "statSync", function () { return true; });
sinon.stub(fs, "statSync").callsFake(function () { return true; });
});
afterEach(function () {
theme.init({settings: {}});

View File

@@ -31,18 +31,18 @@ var apiAdmin = NR_TEST_UTILS.require("@node-red/editor-api/lib/admin");
describe("api/index", function() {
var beforeEach = function() {
sinon.stub(apiAuth,"init",function(){});
sinon.stub(apiEditor,"init",function(){
sinon.stub(apiAuth,"init").callsFake(function(){});
sinon.stub(apiEditor,"init").callsFake(function(){
var app = express();
app.get("/editor",function(req,res) { res.status(200).end(); });
return app;
});
sinon.stub(apiAdmin,"init",function(){
sinon.stub(apiAdmin,"init").callsFake(function(){
var app = express();
app.get("/admin",function(req,res) { res.status(200).end(); });
return app;
});
sinon.stub(apiAuth,"login",function(req,res){
sinon.stub(apiAuth,"login").callsFake(function(req,res){
res.status(200).end();
});
};
@@ -115,7 +115,7 @@ describe("api/index", function() {
describe('initialises api with authentication enabled', function(done) {
it('enables an oauth/openID based authentication mechanism',function(done) {
const stub = sinon.stub(apiAuth, 'genericStrategy', function(){});
const stub = sinon.stub(apiAuth, 'genericStrategy').callsFake(function(){});
const adminAuth = { type: 'strategy', strategy: {} }
api.init({ httpAdminRoot: true, adminAuth },{},{},{});
should(stub.called).be.ok();
@@ -159,7 +159,7 @@ describe("api/index", function() {
describe('editor start', function (done) {
it('cannot be started when editor is disabled', function (done) {
const stub = sinon.stub(apiEditor, 'start', function () {
const stub = sinon.stub(apiEditor, 'start').callsFake(function () {
return Promise.resolve(true);
});
api.init({ httpAdminRoot: true, disableEditor: true }, {}, {}, {});

View File

@@ -33,8 +33,8 @@ describe("api/util", function() {
var app;
before(function() {
app = express();
sinon.stub(log,'error',function(msg) {loggedError = msg;});
sinon.stub(log,'audit',function(event) {loggedEvent = event;});
sinon.stub(log,'error').callsFake(function(msg) {loggedError = msg;});
sinon.stub(log,'audit').callsFake(function(event) {loggedEvent = event;});
app.get("/tooLarge", function(req,res) {
var err = new Error();
err.message = "request entity too large";

View File

@@ -44,7 +44,7 @@ describe("externalModules api", function() {
})
describe("checkFlowDependencies", function() {
beforeEach(function() {
sinon.stub(exec,"run", async function(cmd, args, options) {
sinon.stub(exec,"run").callsFake(async function(cmd, args, options) {
let error;
if (args[1] === "moduleNotFound") {
error = new Error();

View File

@@ -49,10 +49,10 @@ describe('red/registry/index', function() {
describe('#addModule', function() {
it('loads the module and returns its info', function(done) {
stubs.push(sinon.stub(loader,"addModule",function(module) {
stubs.push(sinon.stub(loader,"addModule").callsFake(function(module) {
return Promise.resolve();
}));
stubs.push(sinon.stub(typeRegistry,"getModuleInfo", function(module) {
stubs.push(sinon.stub(typeRegistry,"getModuleInfo").callsFake(function(module) {
return "info";
}));
registry.addModule("foo").then(function(info) {
@@ -61,10 +61,10 @@ describe('red/registry/index', function() {
}).catch(function(err) { done(err); });
});
it('rejects if loader rejects', function(done) {
stubs.push(sinon.stub(loader,"addModule",function(module) {
stubs.push(sinon.stub(loader,"addModule").callsFake(function(module) {
return Promise.reject("error");
}));
stubs.push(sinon.stub(typeRegistry,"getModuleInfo", function(module) {
stubs.push(sinon.stub(typeRegistry,"getModuleInfo").callsFake(function(module) {
return "info";
}));
registry.addModule("foo").then(function(info) {
@@ -78,10 +78,10 @@ describe('red/registry/index', function() {
describe('#enableNode',function() {
it('enables a node set',function(done) {
stubs.push(sinon.stub(typeRegistry,"enableNodeSet",function() {
stubs.push(sinon.stub(typeRegistry,"enableNodeSet").callsFake(function() {
return Promise.resolve();
}));
stubs.push(sinon.stub(typeRegistry,"getNodeInfo", function() {
stubs.push(sinon.stub(typeRegistry,"getNodeInfo").callsFake(function() {
return {id:"node-set",loaded:true};
}));
registry.enableNode("node-set").then(function(ns) {
@@ -92,7 +92,7 @@ describe('red/registry/index', function() {
});
it('rejects if node unknown',function() {
stubs.push(sinon.stub(typeRegistry,"enableNodeSet",function() {
stubs.push(sinon.stub(typeRegistry,"enableNodeSet").callsFake(function() {
throw new Error('failure');
}));
/*jshint immed: false */
@@ -102,15 +102,15 @@ describe('red/registry/index', function() {
});
it('triggers a node load',function(done) {
stubs.push(sinon.stub(typeRegistry,"enableNodeSet",function() {
stubs.push(sinon.stub(typeRegistry,"enableNodeSet").callsFake(function() {
return Promise.resolve();
}));
var calls = 0;
stubs.push(sinon.stub(typeRegistry,"getNodeInfo", function() {
stubs.push(sinon.stub(typeRegistry,"getNodeInfo").callsFake(function() {
// loaded=false on first call, true on subsequent
return {id:"node-set",loaded:(calls++>0)};
}));
stubs.push(sinon.stub(loader,"loadNodeSet",function(){return Promise.resolve();}));
stubs.push(sinon.stub(loader,"loadNodeSet").callsFake(function(){return Promise.resolve();}));
stubs.push(sinon.stub(typeRegistry,"getFullNodeInfo"));
registry.enableNode("node-set").then(function(ns) {

View File

@@ -42,7 +42,7 @@ describe('nodes/registry/installer', function() {
var execResponse;
beforeEach(function() {
sinon.stub(exec,"run", () => execResponse || Promise.resolve(""))
sinon.stub(exec,"run").callsFake(() => execResponse || Promise.resolve(""))
installer.init({})
});
@@ -118,7 +118,7 @@ describe('nodes/registry/installer', function() {
var p = Promise.reject(res);
p.catch((err)=>{});
execResponse = p;
sinon.stub(typeRegistry,"getModuleInfo", function() {
sinon.stub(typeRegistry,"getModuleInfo").callsFake(function() {
return {
version: "0.1.1"
}
@@ -129,7 +129,7 @@ describe('nodes/registry/installer', function() {
}).catch(done);
});
it("rejects when update requested to existing version", function(done) {
sinon.stub(typeRegistry,"getModuleInfo", function() {
sinon.stub(typeRegistry,"getModuleInfo").callsFake(function() {
return {
user: true,
version: "0.1.1"
@@ -141,7 +141,7 @@ describe('nodes/registry/installer', function() {
}).catch(done);
});
it("rejects when update requested to existing version and url", function(done) {
sinon.stub(typeRegistry,"getModuleInfo", function() {
sinon.stub(typeRegistry,"getModuleInfo").callsFake(function() {
return {
user: true,
version: "0.1.1"
@@ -180,7 +180,7 @@ describe('nodes/registry/installer', function() {
p.catch((err)=>{});
execResponse = p;
var addModule = sinon.stub(registry,"addModule",function(md) {
var addModule = sinon.stub(registry,"addModule").callsFake(function(md) {
return Promise.resolve(nodeInfo);
});
@@ -211,7 +211,7 @@ describe('nodes/registry/installer', function() {
});
it("succeeds when path is valid node-red module", function(done) {
var nodeInfo = {nodes:{module:"foo",types:["a"]}};
var addModule = sinon.stub(registry,"addModule",function(md) {
var addModule = sinon.stub(registry,"addModule").callsFake(function(md) {
return Promise.resolve(nodeInfo);
});
var resourcesDir = path.resolve(path.join(__dirname,"resources","local","TestNodeModule","node_modules","TestNodeModule"));
@@ -241,7 +241,7 @@ describe('nodes/registry/installer', function() {
p.catch((err)=>{});
execResponse = p;
var addModule = sinon.stub(registry,"addModule",function(md) {
var addModule = sinon.stub(registry,"addModule").callsFake(function(md) {
return Promise.resolve(nodeInfo);
});
@@ -267,7 +267,7 @@ describe('nodes/registry/installer', function() {
it("rejects with generic error", function(done) {
var nodeInfo = [{module:"foo",types:["a"]}];
var removeModule = sinon.stub(registry,"removeModule",function(md) {
var removeModule = sinon.stub(registry,"removeModule").callsFake(function(md) {
return Promise.resolve(nodeInfo);
});
var res = {
@@ -288,10 +288,10 @@ describe('nodes/registry/installer', function() {
});
it("succeeds when module is found", function(done) {
var nodeInfo = [{module:"foo",types:["a"]}];
var removeModule = sinon.stub(typeRegistry,"removeModule",function(md) {
var removeModule = sinon.stub(typeRegistry,"removeModule").callsFake(function(md) {
return nodeInfo;
});
var getModuleInfo = sinon.stub(registry,"getModuleInfo",function(md) {
var getModuleInfo = sinon.stub(registry,"getModuleInfo").callsFake(function(md) {
return {nodes:[]};
});
var res = {
@@ -303,7 +303,7 @@ describe('nodes/registry/installer', function() {
p.catch((err)=>{});
execResponse = p;
sinon.stub(fs,"statSync", function(fn) { return {}; });
sinon.stub(fs,"statSync").callsFake(function(fn) { return {}; });
installer.uninstallModule("this_wont_exist").then(function(info) {
info.should.eql(nodeInfo);

View File

@@ -46,8 +46,8 @@ describe("red/nodes/registry/loader",function() {
describe("#load",function() {
it("load empty set without settings available", function(done) {
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};}));
stubs.push(sinon.stub(localfilesystem,"getNodeFiles").callsFake(function(){ return {};}));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return {};}));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return false;}}});
loader.load(true).then(function() {
localfilesystem.getNodeFiles.called.should.be.true();
@@ -57,8 +57,8 @@ describe("red/nodes/registry/loader",function() {
})
});
it("load empty set with settings available triggers registery save", function(done) {
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};}));
stubs.push(sinon.stub(localfilesystem,"getNodeFiles").callsFake(function(){ return {};}));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return {};}));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
loader.load(true).then(function() {
registry.saveNodeList.called.should.be.true();
@@ -69,7 +69,7 @@ describe("red/nodes/registry/loader",function() {
});
it("load core node files scanned by lfs - single node single file", function(done) {
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
stubs.push(sinon.stub(localfilesystem,"getNodeFiles").callsFake(function(){
var result = {};
result["node-red"] = {
"name": "node-red",
@@ -85,10 +85,10 @@ describe("red/nodes/registry/loader",function() {
return result;
}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return }));
stubs.push(sinon.stub(registry,"addModule").callsFake(function(){ return }));
// This module isn't already loaded
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
stubs.push(sinon.stub(registry,"getNodeInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(nodes,"registerType"));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
@@ -126,7 +126,7 @@ describe("red/nodes/registry/loader",function() {
});
it("load core node files scanned by lfs - ignore html if disableEditor true", function(done) {
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
stubs.push(sinon.stub(localfilesystem,"getNodeFiles").callsFake(function(){
var result = {};
result["node-red"] = {
"name": "node-red",
@@ -142,10 +142,10 @@ describe("red/nodes/registry/loader",function() {
return result;
}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return }));
stubs.push(sinon.stub(registry,"addModule").callsFake(function(){ return }));
// This module isn't already loaded
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
stubs.push(sinon.stub(registry,"getNodeInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(nodes,"registerType"));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{disableEditor: true, available:function(){return true;}}});
@@ -190,7 +190,7 @@ describe("red/nodes/registry/loader",function() {
});
it("load core node files scanned by lfs - multiple nodes single file", function(done) {
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
stubs.push(sinon.stub(localfilesystem,"getNodeFiles").callsFake(function(){
var result = {};
result["node-red"] = {
"name": "node-red",
@@ -206,10 +206,10 @@ describe("red/nodes/registry/loader",function() {
return result;
}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return }));
stubs.push(sinon.stub(registry,"addModule").callsFake(function(){ return }));
// This module isn't already loaded
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
stubs.push(sinon.stub(registry,"getNodeInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(nodes,"registerType"));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
loader.load().then(function(result) {
@@ -250,7 +250,7 @@ describe("red/nodes/registry/loader",function() {
it("load core node files scanned by lfs - node with promise", function(done) {
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
stubs.push(sinon.stub(localfilesystem,"getNodeFiles").callsFake(function(){
var result = {};
result["node-red"] = {
"name": "node-red",
@@ -266,10 +266,10 @@ describe("red/nodes/registry/loader",function() {
return result;
}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return }));
stubs.push(sinon.stub(registry,"addModule").callsFake(function(){ return }));
// This module isn't already loaded
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
stubs.push(sinon.stub(registry,"getNodeInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(nodes,"registerType"));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
@@ -308,7 +308,7 @@ describe("red/nodes/registry/loader",function() {
it("load core node files scanned by lfs - node with rejecting promise", function(done) {
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
stubs.push(sinon.stub(localfilesystem,"getNodeFiles").callsFake(function(){
var result = {};
result["node-red"] = {
"name": "node-red",
@@ -324,10 +324,10 @@ describe("red/nodes/registry/loader",function() {
return result;
}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return }));
stubs.push(sinon.stub(registry,"addModule").callsFake(function(){ return }));
// This module isn't already loaded
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
stubs.push(sinon.stub(registry,"getNodeInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(nodes,"registerType"));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
@@ -362,7 +362,7 @@ describe("red/nodes/registry/loader",function() {
});
it("load core node files scanned by lfs - missing file", function(done) {
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
stubs.push(sinon.stub(localfilesystem,"getNodeFiles").callsFake(function(){
var result = {};
result["node-red"] = {
"name": "node-red",
@@ -378,10 +378,10 @@ describe("red/nodes/registry/loader",function() {
return result;
}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return }));
stubs.push(sinon.stub(registry,"addModule").callsFake(function(){ return }));
// This module isn't already loaded
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
stubs.push(sinon.stub(registry,"getNodeInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(nodes,"registerType"));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
@@ -416,7 +416,7 @@ describe("red/nodes/registry/loader",function() {
// it("load core node files scanned by lfs - missing html file", function(done) {
// // This is now an okay situation
// stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
// stubs.push(sinon.stub(localfilesystem,"getNodeFiles").callsFake(function(){
// var result = {};
// result["node-red"] = {
// "name": "node-red",
@@ -432,10 +432,10 @@ describe("red/nodes/registry/loader",function() {
// return result;
// }));
//
// stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
// stubs.push(sinon.stub(registry,"addModule", function(){ return }));
// stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return }));
// stubs.push(sinon.stub(registry,"addModule").callsFake(function(){ return }));
// // This module isn't already loaded
// stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
// stubs.push(sinon.stub(registry,"getNodeInfo").callsFake(function(){ return null; }));
//
// stubs.push(sinon.stub(nodes,"registerType"));
// loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
@@ -481,7 +481,7 @@ describe("red/nodes/registry/loader",function() {
});
it("returns rejected error if module already loaded", function(done) {
stubs.push(sinon.stub(registry,"getModuleInfo",function(){return{}}));
stubs.push(sinon.stub(registry,"getModuleInfo").callsFake(function(){return{}}));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
loader.addModule("test-module").catch(function(err) {
@@ -490,8 +490,8 @@ describe("red/nodes/registry/loader",function() {
});
});
it("returns rejected error if module not found", function(done) {
stubs.push(sinon.stub(registry,"getModuleInfo",function(){return null}));
stubs.push(sinon.stub(localfilesystem,"getModuleFiles",function() {
stubs.push(sinon.stub(registry,"getModuleInfo").callsFake(function(){return null}));
stubs.push(sinon.stub(localfilesystem,"getModuleFiles").callsFake(function() {
throw new Error("failure");
}));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
@@ -504,9 +504,9 @@ describe("red/nodes/registry/loader",function() {
it("loads module by name", function(done) {
// This module isn't already loaded
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
stubs.push(sinon.stub(registry,"getModuleInfo",function(){ return null; }));
stubs.push(sinon.stub(localfilesystem,"getModuleFiles", function(){
stubs.push(sinon.stub(registry,"getNodeInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(registry,"getModuleInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(localfilesystem,"getModuleFiles").callsFake(function(){
var result = {};
result["TestNodeModule"] = {
"name": "TestNodeModule",
@@ -523,8 +523,8 @@ describe("red/nodes/registry/loader",function() {
return result;
}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" }));
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return "a node list" }));
stubs.push(sinon.stub(registry,"addModule").callsFake(function(){ return }));
stubs.push(sinon.stub(nodes,"registerType"));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{available:function(){return true;}}});
loader.addModule("TestNodeModule").then(function(result) {
@@ -560,9 +560,9 @@ describe("red/nodes/registry/loader",function() {
it("skips module that fails version check", function(done) {
// This module isn't already loaded
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));
stubs.push(sinon.stub(registry,"getModuleInfo",function(){ return null; }));
stubs.push(sinon.stub(localfilesystem,"getModuleFiles", function(){
stubs.push(sinon.stub(registry,"getNodeInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(registry,"getModuleInfo").callsFake(function(){ return null; }));
stubs.push(sinon.stub(localfilesystem,"getModuleFiles").callsFake(function(){
var result = {};
result["TestNodeModule"] = {
"name": "TestNodeModule",
@@ -580,8 +580,8 @@ describe("red/nodes/registry/loader",function() {
return result;
}));
stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" }));
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
stubs.push(sinon.stub(registry,"saveNodeList").callsFake(function(){ return "a node list" }));
stubs.push(sinon.stub(registry,"addModule").callsFake(function(){ return }));
stubs.push(sinon.stub(nodes,"registerType"));
loader.init({log:{"_":function(){},warn:function(){}},nodes:nodes,version: function() { return "0.12.0"}, settings:{available:function(){return true;}}});
loader.addModule("TestNodeModule").then(function(result) {
@@ -643,7 +643,7 @@ describe("red/nodes/registry/loader",function() {
},"en").should.eql("foo");
});
it("loads help, caching result", function() {
stubs.push(sinon.stub(fs,"readFileSync", function(path) {
stubs.push(sinon.stub(fs,"readFileSync").callsFake(function(path) {
return 'bar';
}))
var node = {
@@ -660,7 +660,7 @@ describe("red/nodes/registry/loader",function() {
fs.readFileSync.calledOnce.should.be.true();
});
it("loads help, defaulting to en-US content", function() {
stubs.push(sinon.stub(fs,"readFileSync", function(path) {
stubs.push(sinon.stub(fs,"readFileSync").callsFake(function(path) {
throw new Error("not found");
}))
var node = {
@@ -677,7 +677,7 @@ describe("red/nodes/registry/loader",function() {
fs.readFileSync.calledOnce.should.be.true();
});
it("loads help, defaulting to en-US content for extra nodes", function() {
stubs.push(sinon.stub(fs,"readFileSync", function(path) {
stubs.push(sinon.stub(fs,"readFileSync").callsFake(function(path) {
if (path.indexOf("en-US") >= 0) {
return 'bar';
}
@@ -698,7 +698,7 @@ describe("red/nodes/registry/loader",function() {
fs.readFileSync.calledTwice.should.be.true();
});
it("fails to load en-US help content", function() {
stubs.push(sinon.stub(fs,"readFileSync", function(path) {
stubs.push(sinon.stub(fs,"readFileSync").callsFake(function(path) {
throw new Error("not found");
}));
var node = {

View File

@@ -30,7 +30,7 @@ var i18n = NR_TEST_UTILS.require("@node-red/util").i18n;
describe("red/nodes/registry/localfilesystem",function() {
beforeEach(function() {
stubs.push(sinon.stub(i18n,"registerMessageCatalog", function() { return Promise.resolve(); }));
stubs.push(sinon.stub(i18n,"registerMessageCatalog").callsFake(function() { return Promise.resolve(); }));
})
var stubs = [];
@@ -131,7 +131,7 @@ describe("red/nodes/registry/localfilesystem",function() {
});
it("Finds nodes module path",function(done) {
var _join = path.join;
stubs.push(sinon.stub(path,"join",function() {
stubs.push(sinon.stub(path,"join").callsFake(function() {
if (arguments[0] == resourcesDir) {
// This stops the module tree scan from going any higher
// up the tree than resourcesDir.
@@ -206,7 +206,7 @@ describe("red/nodes/registry/localfilesystem",function() {
describe("#getModuleFiles",function() {
it("gets a nodes module files",function(done) {
var _join = path.join;
stubs.push(sinon.stub(path,"join",function() {
stubs.push(sinon.stub(path,"join").callsFake(function() {
if (arguments[0] == resourcesDir) {
// This stops the module tree scan from going any higher
// up the tree than resourcesDir.
@@ -232,7 +232,7 @@ describe("red/nodes/registry/localfilesystem",function() {
});
it("throws an error if a node isn't found",function(done) {
var _join = path.join;
stubs.push(sinon.stub(path,"join",function() {
stubs.push(sinon.stub(path,"join").callsFake(function() {
if (arguments[0] == resourcesDir) {
// This stops the module tree scan from going any higher
// up the tree than resourcesDir.
@@ -251,7 +251,7 @@ describe("red/nodes/registry/localfilesystem",function() {
it.skip("finds icon path directory");
it("scans icon files with a module file",function(done) {
var _join = path.join;
stubs.push(sinon.stub(path,"join",function() {
stubs.push(sinon.stub(path,"join").callsFake(function() {
if (arguments[0] == resourcesDir) {
// This stops the module tree scan from going any higher
// up the tree than resourcesDir.

View File

@@ -37,8 +37,8 @@ describe("red/nodes/registry/plugins",function() {
}
}
events.on("registry:plugin-added",handleEvent);
sinon.stub(registry,"getModule", moduleId => modules[moduleId]);
sinon.stub(registry,"getModuleList", () => modules)
sinon.stub(registry,"getModule").callsFake(moduleId => modules[moduleId]);
sinon.stub(registry,"getModuleList").callsFake(() => modules)
});
afterEach(function() {
events.removeListener("registry:plugin-added",handleEvent);

View File

@@ -31,8 +31,8 @@ describe("runtime-api/comms", function() {
}
var eventHandlers = {};
before(function(done) {
sinon.stub(events,"removeListener", function() {})
sinon.stub(events,"on", function(evt,handler) { eventHandlers[evt] = handler })
sinon.stub(events,"removeListener").callsFake(function() {})
sinon.stub(events,"on").callsFake(function(evt,handler) { eventHandlers[evt] = handler })
comms.init({
log: {
trace: function(){}
@@ -97,8 +97,8 @@ describe("runtime-api/comms", function() {
}
}
before(function() {
sinon.stub(events,"removeListener", function() {})
sinon.stub(events,"on", function(evt,handler) { eventHandlers[evt] = handler })
sinon.stub(events,"removeListener").callsFake(function() {})
sinon.stub(events,"on").callsFake(function(evt,handler) { eventHandlers[evt] = handler })
comms.init({
log: {
trace: function(){}
@@ -177,8 +177,8 @@ describe("runtime-api/comms", function() {
}
var eventHandlers = {};
before(function() {
sinon.stub(events,"removeListener", function() {})
sinon.stub(events,"on", function(evt,handler) { eventHandlers[evt] = handler })
sinon.stub(events,"removeListener").callsFake(function() {})
sinon.stub(events,"on").callsFake(function(evt,handler) { eventHandlers[evt] = handler })
comms.init({
log: {
trace: function(){}

View File

@@ -24,7 +24,7 @@ var index = NR_TEST_UTILS.require("@node-red/runtime/lib/api/index");
describe("runtime-api/index", function() {
before(function() {
["comms","flows","nodes","settings","library","projects"].forEach(n => {
sinon.stub(NR_TEST_UTILS.require(`@node-red/runtime/lib/api/${n}`),"init",()=>{});
sinon.stub(NR_TEST_UTILS.require(`@node-red/runtime/lib/api/${n}`),"init").callsFake(()=>{});
})
});
after(function() {

View File

@@ -217,7 +217,7 @@ describe("api/admin/nodes", function() {
app.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,nodes.putSet);
app.get("/getIcons",nodes.getIcons);
app.delete("/nodes/:id",nodes.delete);
sinon.stub(apiUtil,"determineLangFromHeaders", function() {
sinon.stub(apiUtil,"determineLangFromHeaders").callsFake(function() {
return "en-US";
});
});

View File

@@ -173,7 +173,7 @@ describe('Flow', function() {
util.inherits(TestDoneNode,Node);
before(function() {
getType = sinon.stub(typeRegistry,"get",function(type) {
getType = sinon.stub(typeRegistry,"get").callsFake(function(type) {
if (type=="test") {
return TestNode;
} else if (type=="testError"){

View File

@@ -202,7 +202,7 @@ describe('Subflow', function() {
util.inherits(TestEnvNode,Node);
before(function() {
getType = sinon.stub(typeRegistry,"get",function(type) {
getType = sinon.stub(typeRegistry,"get").callsFake(function(type) {
if (type=="test") {
return TestNode;
} else if (type=="testError"){

View File

@@ -51,10 +51,10 @@ describe('flows/index', function() {
before(function() {
getType = sinon.stub(typeRegistry,"get",function(type) {
getType = sinon.stub(typeRegistry,"get").callsFake(function(type) {
return type.indexOf('missing') === -1;
});
checkFlowDependencies = sinon.stub(typeRegistry, "checkFlowDependencies", async function(flow) {
checkFlowDependencies = sinon.stub(typeRegistry, "checkFlowDependencies").callsFake(async function(flow) {
if (flow[0].id === "node-with-missing-modules") {
throw new Error("Missing module");
}
@@ -69,20 +69,20 @@ describe('flows/index', function() {
beforeEach(function() {
eventsOn = sinon.spy(events,"on");
credentialsClean = sinon.stub(credentials,"clean",function(conf) {
credentialsClean = sinon.stub(credentials,"clean").callsFake(function(conf) {
conf.forEach(function(n) {
delete n.credentials;
});
return Promise.resolve();
});
credentialsLoad = sinon.stub(credentials,"load",function(creds) {
credentialsLoad = sinon.stub(credentials,"load").callsFake(function(creds) {
if (creds && creds.hasOwnProperty("$") && creds['$'] === "fail") {
return Promise.reject("creds error");
}
return Promise.resolve();
});
credentialsAdd = sinon.stub(credentials,"add", async function(id, conf){})
flowCreate = sinon.stub(Flow,"create",function(parent, global, flow) {
credentialsAdd = sinon.stub(credentials,"add").callsFake(async function(id, conf){})
flowCreate = sinon.stub(Flow,"create").callsFake(function(parent, global, flow) {
var id;
if (typeof flow === 'undefined') {
flow = global;
@@ -551,7 +551,7 @@ describe('flows/index', function() {
describe('#checkTypeInUse', function() {
before(function() {
sinon.stub(typeRegistry,"getNodeInfo",function(id) {
sinon.stub(typeRegistry,"getNodeInfo").callsFake(function(id) {
if (id === 'unused-module') {
return {types:['one','two','three']}
} else {

View File

@@ -26,7 +26,7 @@ describe('flows/util', function() {
var getType;
before(function() {
getType = sinon.stub(typeRegistry,"get",function(type) {
getType = sinon.stub(typeRegistry,"get").callsFake(function(type) {
return type!=='missing';
});
});

View File

@@ -44,13 +44,13 @@ describe("runtime", function() {
delete process.env.NODE_RED_HOME;
});
function mockUtil(metrics) {
sinon.stub(log,"log",function(){})
sinon.stub(log,"warn",function(){})
sinon.stub(log,"info",function(){})
sinon.stub(log,"trace",function(){})
sinon.stub(log,"metric",function(){ return !!metrics })
sinon.stub(log,"_",function(){ return "abc"})
sinon.stub(i18n,"registerMessageCatalog",function(){ return Promise.resolve()})
sinon.stub(log,"log").callsFake(function(){})
sinon.stub(log,"warn").callsFake(function(){})
sinon.stub(log,"info").callsFake(function(){})
sinon.stub(log,"trace").callsFake(function(){})
sinon.stub(log,"metric").callsFake(function(){ return !!metrics })
sinon.stub(log,"_").callsFake(function(){ return "abc"})
sinon.stub(i18n,"registerMessageCatalog").callsFake(function(){ return Promise.resolve()})
}
function unmockUtil() {
log.log.restore && log.log.restore();
@@ -63,9 +63,9 @@ describe("runtime", function() {
}
describe("init", function() {
beforeEach(function() {
sinon.stub(log,"init",function() {});
sinon.stub(settings,"init",function() {});
sinon.stub(redNodes,"init",function() {})
sinon.stub(log,"init").callsFake(function() {});
sinon.stub(settings,"init").callsFake(function() {});
sinon.stub(redNodes,"init").callsFake(function() {})
mockUtil();
});
afterEach(function() {
@@ -103,13 +103,13 @@ describe("runtime", function() {
var redNodesLoadContextsPlugin;
beforeEach(function() {
storageInit = sinon.stub(storage,"init",function(settings) {return Promise.resolve();});
redNodesInit = sinon.stub(redNodes,"init", function() {});
redNodesLoad = sinon.stub(redNodes,"load", function() {return Promise.resolve()});
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()});
storageInit = sinon.stub(storage,"init").callsFake(function(settings) {return Promise.resolve();});
redNodesInit = sinon.stub(redNodes,"init").callsFake(function() {});
redNodesLoad = sinon.stub(redNodes,"load").callsFake(function() {return Promise.resolve()});
redNodesCleanModuleList = sinon.stub(redNodes,"cleanModuleList").callsFake(function(){});
redNodesLoadFlows = sinon.stub(redNodes,"loadFlows").callsFake(function() {return Promise.resolve()});
redNodesStartFlows = sinon.stub(redNodes,"startFlows").callsFake(function() {});
redNodesLoadContextsPlugin = sinon.stub(redNodes,"loadContextsPlugin").callsFake(function() {return Promise.resolve()});
mockUtil();
});
afterEach(function() {
@@ -124,7 +124,7 @@ describe("runtime", function() {
unmockUtil();
});
it("reports errored/missing modules",function(done) {
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) {
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList").callsFake(function(cb) {
return [
{ err:"errored",name:"errName" }, // error
{ module:"module",enabled:true,loaded:false,types:["typeA","typeB"]} // missing
@@ -151,7 +151,7 @@ describe("runtime", function() {
}).catch(err=>{done(err)});
});
it("initiates load of missing modules",function(done) {
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) {
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList").callsFake(function(cb) {
return [
{ err:"errored",name:"errName" }, // error
{ err:"errored",name:"errName" }, // error
@@ -159,7 +159,7 @@ describe("runtime", function() {
{ module:"node-red",enabled:true,loaded:false,types:["typeC","typeD"]} // missing
].filter(cb);
});
var serverInstallModule = sinon.stub(redNodes,"installModule",function(name) { return Promise.resolve({nodes:[]});});
var serverInstallModule = sinon.stub(redNodes,"installModule").callsFake(function(name) { return Promise.resolve({nodes:[]});});
runtime.init({testSettings: true, autoInstallModules:true, httpAdminRoot:"/", load:function() { return Promise.resolve();}});
sinon.stub(console,"log");
runtime.start().then(function() {
@@ -181,7 +181,7 @@ describe("runtime", function() {
}).catch(err=>{done(err)});
});
it("reports errored modules when verbose is enabled",function(done) {
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function(cb) {
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList").callsFake(function(cb) {
return [
{ err:"errored",name:"errName" } // error
].filter(cb);
@@ -201,8 +201,8 @@ describe("runtime", function() {
});
it("reports runtime metrics",function(done) {
var stopFlows = sinon.stub(redNodes,"stopFlows",function() { return Promise.resolve();} );
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList", function() {return []});
var stopFlows = sinon.stub(redNodes,"stopFlows").callsFake(function() { return Promise.resolve();} );
redNodesGetNodeList = sinon.stub(redNodes,"getNodeList").callsFake(function() {return []});
unmockUtil();
mockUtil(true);
runtime.init(
@@ -233,8 +233,8 @@ describe("runtime", function() {
});
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();} );
var stopFlows = sinon.stub(redNodes,"stopFlows").callsFake(function() { return Promise.resolve();} );
var closeContextsPlugin = sinon.stub(redNodes,"closeContextsPlugin").callsFake(function() { return Promise.resolve();} );
runtime.stop().then(function(){
stopFlows.called.should.be.true();
closeContextsPlugin.called.should.be.true();

View File

@@ -65,7 +65,7 @@ describe("runtime/library/examples", function() {
}
}
});
sinon.stub(fs,"readFile", function(path,opts,callback) {
sinon.stub(fs,"readFile").callsFake(function(path,opts,callback) {
if (path === "/tmp/test-module/abc") {
callback(null,"Example flow result");
} else if (path === "/tmp/@scope/test-module/abc") {

View File

@@ -37,14 +37,14 @@ var mockLog = {
describe("runtime/library", function() {
before(function() {
sinon.stub(localLibrary,"getEntry",function(type,path) {
sinon.stub(localLibrary,"getEntry").callsFake(function(type,path) {
return Promise.resolve({
library: "local",
type:type,
path:path
})
});
sinon.stub(localLibrary,"saveEntry",function(type, path, meta, body) {
sinon.stub(localLibrary,"saveEntry").callsFake(function(type, path, meta, body) {
return Promise.resolve({
library: "local",
type:type,
@@ -53,7 +53,7 @@ describe("runtime/library", function() {
body:body
})
});
sinon.stub(examplesLibrary,"getEntry",function(type,path) {
sinon.stub(examplesLibrary,"getEntry").callsFake(function(type,path) {
return Promise.resolve({
library: "_examples_",
type:type,

View File

@@ -151,7 +151,7 @@ describe('Node', function() {
it('handles thrown errors', function(done) {
var n = new RedNode({id:'123',type:'abc'});
sinon.stub(n,"error",function(err,msg) {});
sinon.stub(n,"error").callsFake(function(err,msg) {});
var message = {payload:"hello world"};
n.on('input',function(msg) {
throw new Error("test error");
@@ -271,7 +271,7 @@ describe('Node', function() {
});
it('logs error if callback provides error', function(done) {
var n = new RedNode({id:'123',type:'abc'});
sinon.stub(n,"error",function(err,msg) {});
sinon.stub(n,"error").callsFake(function(err,msg) {});
var message = {payload:"hello world"};
n.on('input',function(msg, nodeSend, nodeDone) {
@@ -723,7 +723,7 @@ describe('Node', function() {
it('produces a metric message', function(done) {
var n = new RedNode({id:'123',type:'abc'});
var loginfo = {};
sinon.stub(Log, 'log', function(msg) {
sinon.stub(Log, 'log').callsFake(function(msg) {
loginfo = msg;
});
var msg = {payload:"foo", _msgid:"987654321"};
@@ -739,7 +739,7 @@ describe('Node', function() {
it('returns metric value if eventname undefined', function(done) {
var n = new RedNode({id:'123',type:'abc'});
var loginfo = {};
sinon.stub(Log, 'log', function(msg) {
sinon.stub(Log, 'log').callsFake(function(msg) {
loginfo = msg;
});
var msg = {payload:"foo", _msgid:"987654321"};
@@ -751,7 +751,7 @@ describe('Node', function() {
it('returns not defined if eventname defined', function(done) {
var n = new RedNode({id:'123',type:'abc'});
var loginfo = {};
sinon.stub(Log, 'log', function(msg) {
sinon.stub(Log, 'log').callsFake(function(msg) {
loginfo = msg;
});
var msg = {payload:"foo", _msgid:"987654321"};

View File

@@ -320,7 +320,7 @@ describe('context', function() {
describe('external context storage',function() {
var resourcesDir = path.resolve(path.join(__dirname,"..","resources","context"));
var sandbox = sinon.sandbox.create();
var sandbox = sinon.createSandbox();
var stubGet = sandbox.stub();
var stubSet = sandbox.stub();
var stubKeys = sandbox.stub();

View File

@@ -177,15 +177,15 @@ describe("red/nodes/index", function() {
var userDir = path.join(__dirname,".testUserHome");
before(function(done) {
sinon.stub(log,"log",function(){});
sinon.stub(log,"log").callsFake(function(){});
fs.remove(userDir,function(err) {
fs.mkdir(userDir,function() {
sinon.stub(index, 'load', function() {
sinon.stub(index, 'load').callsFake(function() {
return new Promise(function(resolve,reject){
resolve([]);
});
});
sinon.stub(localfilesystem, 'getCredentials', function() {
sinon.stub(localfilesystem, 'getCredentials').callsFake(function() {
return new Promise(function(resolve,reject) {
resolve({"tab1":{"b":1,"c":2}});
});
@@ -271,7 +271,7 @@ describe("red/nodes/index", function() {
var randomNodeInfo = {id:"5678",types:["random"]};
beforeEach(function() {
sinon.stub(registry,"getNodeInfo",function(id) {
sinon.stub(registry,"getNodeInfo").callsFake(function(id) {
if (id == "test") {
return {id:"1234",types:["test"]};
} else if (id == "doesnotexist") {
@@ -280,7 +280,7 @@ describe("red/nodes/index", function() {
return randomNodeInfo;
}
});
sinon.stub(registry,"disableNode",function(id) {
sinon.stub(registry,"disableNode").callsFake(function(id) {
return Promise.resolve(randomNodeInfo);
});
});
@@ -343,7 +343,7 @@ describe("red/nodes/index", function() {
};
before(function() {
sinon.stub(registry,"getNodeInfo",function(id) {
sinon.stub(registry,"getNodeInfo").callsFake(function(id) {
if (id == "node-red/foo") {
return {id:"1234",types:["test"]};
} else if (id == "doesnotexist") {
@@ -352,7 +352,7 @@ describe("red/nodes/index", function() {
return randomNodeInfo;
}
});
sinon.stub(registry,"getModuleInfo",function(module) {
sinon.stub(registry,"getModuleInfo").callsFake(function(module) {
if (module == "node-red") {
return {nodes:[{name:"foo"}]};
} else if (module == "doesnotexist") {
@@ -361,7 +361,7 @@ describe("red/nodes/index", function() {
return randomModuleInfo;
}
});
sinon.stub(registry,"removeModule",function(id) {
sinon.stub(registry,"removeModule").callsFake(function(id) {
return randomModuleInfo;
});
});

View File

@@ -313,7 +313,7 @@ describe('storage/localfilesystem', function() {
var flowFile = 'test.json';
var flowFilePath = path.join(userDir,flowFile);
localfilesystem.init({userDir:userDir, flowFile:flowFilePath,getUserSettings: () => {{}}}, mockRuntime).then(function() {
sinon.stub(fs,"fsync", function(fd, cb) {
sinon.stub(fs,"fsync").callsFake(function(fd, cb) {
cb(new Error());
});
sinon.spy(log,"warn");

View File

@@ -34,7 +34,7 @@ describe("localfilesystem/projects/ssh/keygen", function() {
var command;
var args;
var opts;
sinon.stub(child_process,"spawn", function(_command,_args,_opts) {
sinon.stub(child_process,"spawn").callsFake(function(_command,_args,_opts) {
_command = command;
_args = args;
_opts = opts;

View File

@@ -41,7 +41,7 @@ describe("runtime/exec", function() {
mockProcess = new EventEmitter();
mockProcess.stdout = new EventEmitter();
mockProcess.stderr = new EventEmitter();
sinon.stub(child_process,'spawn',function(command,args,options) {
sinon.stub(child_process,'spawn').callsFake(function(command,args,options) {
mockProcess._args = {command,args,options};
return mockProcess;
});

View File

@@ -24,7 +24,7 @@ var log = NR_TEST_UTILS.require("@node-red/util").log;
describe("@node-red/util/log", function() {
beforeEach(function () {
var spy = sinon.stub(util, 'log', function(arg){});
var spy = sinon.stub(util, 'log').callsFake(function(arg){});
var settings = {logging: { console: { level: 'metric', metrics: true } } };
log.init(settings);
});

View File

@@ -33,9 +33,9 @@ describe("red/red", function() {
// describe("check build", function() {
// beforeEach(function() {
// sinon.stub(runtime,"init",function() {});
// sinon.stub(api,"init",function() {});
// // sinon.stub(RED,"version",function() { return "version";});
// sinon.stub(runtime,"init").callsFake(function() {});
// sinon.stub(api,"init").callsFake(function() {});
// // sinon.stub(RED,"version").callsFake(function() { return "version";});
// });
// afterEach(function() {
// runtime.init.restore();
@@ -44,7 +44,7 @@ describe("red/red", function() {
// // RED.version.restore();
// });
// it.skip('warns if build has not been run',function() {
// sinon.stub(fs,"statSync",function() { throw new Error();});
// sinon.stub(fs,"statSync").callsFake(function() { throw new Error();});
//
// /*jshint immed: false */
// (function() {
@@ -52,7 +52,7 @@ describe("red/red", function() {
// }).should.throw("Node-RED not built");
// });
// it('passed if build has been run',function() {
// sinon.stub(fs,"statSync",function() { });
// sinon.stub(fs,"statSync").callsFake(function() { });
// RED.init({},{});
// });
// });