node-red/test/nodes/core/logic/19-batch_spec.js

361 lines
14 KiB
JavaScript

/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
var should = require("should");
var batchNode = require("../../../../nodes/core/logic/19-batch.js");
var helper = require("node-red-node-test-helper");
var RED = require("../../../../red/red.js");
describe('BATCH node', function() {
this.timeout(8000);
before(function(done) {
helper.startServer(done);
});
after(function(done) {
helper.stopServer(done);
});
afterEach(function() {
helper.unload();
RED.settings.nodeMessageBufferMaxLength = 0;
});
it('should be loaded with defaults', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", wires:[["n2"]]},
{id:"n2", type:"helper"}];
helper.load(batchNode, flow, function() {
var n1 = helper.getNode("n1");
n1.should.have.property('name', 'BatchNode');
done();
});
});
function check_parts(msg, id, idx, count) {
msg.should.have.property("parts");
var parts = msg.parts;
parts.should.have.property("id", id);
parts.should.have.property("index", idx);
parts.should.have.property("count", count);
}
function check_data(n1, n2, results, done) {
var id = undefined;
var ix0 = 0; // seq no
var ix1 = 0; // loc. in seq
var seq = undefined;
var msgs = [];
n2.on("input", function(msg) {
try {
for (var i = 0; i < msgs.length; i++) {
msg.should.not.equal(msgs[i]);
}
msgs.push(msg);
if (seq === undefined) {
seq = results[ix0];
}
var val = seq[ix1];
msg.should.have.property("payload", val);
if (id === undefined) {
id = msg.parts.id;
}
check_parts(msg, id, ix1, seq.length);
ix1++;
if (ix1 === seq.length) {
ix0++;
ix1 = 0;
seq = undefined;
id = undefined;
if (ix0 === results.length) {
done();
}
}
}
catch (e) {
done(e);
}
});
}
function check_count(flow, results, done) {
try {
helper.load(batchNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
check_data(n1, n2, results, done);
for(var i = 0; i < 6; i++) {
n1.receive({payload: i});
}
});
}
catch (e) {
done(e);
}
}
function delayed_send(receiver, index, count, delay) {
if (index < count) {
setTimeout(function() {
receiver.receive({payload: index});
delayed_send(receiver, index+1, count, delay);
}, delay);
}
}
function check_interval(flow, results, delay, done) {
helper.load(batchNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
check_data(n1, n2, results, done);
delayed_send(n1, 0, 4, delay);
});
}
function check_concat(flow, results, inputs, done) {
try {
helper.load(batchNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
check_data(n1, n2, results, done);
for(var data of inputs) {
var msg = {
topic: data[0],
payload: data[1],
parts: {
id: data[0],
index: data[2],
count: data[3]
}
};
n1.receive(msg);
}
});
}
catch (e) {
done(e);
}
}
describe('mode: count', function() {
it('should create seq. with count', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "count", count: 2, overlap: 0, interval: 10, allowEmptySequence: false, topics: [], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
[0, 1],
[2, 3],
[4, 5]
];
check_count(flow, results, done);
});
it('should create seq. with count and overlap', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "count", count: 3, overlap: 2, interval: 10, allowEmptySequence: false, topics: [], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
[0, 1, 2],
[1, 2, 3],
[2, 3, 4],
[3, 4, 5]
];
check_count(flow, results, done);
});
it('should handle too many pending messages', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "count", count: 5, overlap: 0, interval: 10, allowEmptySequence: false, topics: [], wires:[["n2"]]},
{id:"n2", type:"helper"}];
helper.load(batchNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
RED.settings.nodeMessageBufferMaxLength = 2;
setTimeout(function() {
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "batch";
});
var evt = logEvents[0][0];
evt.should.have.property('id', "n1");
evt.should.have.property('type', "batch");
evt.should.have.property('msg', "batch.too-many");
done();
}, 150);
for(var i = 0; i < 3; i++) {
n1.receive({payload: i});
}
});
});
});
describe('mode: interval', function() {
it('should create seq. with interval', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
[0, 1],
[2, 3]
];
check_interval(flow, results, 450, done);
});
it('should create seq. with interval (in float)', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 0.5, allowEmptySequence: false, topics: [], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
[0, 1],
[2, 3]
];
check_interval(flow, results, 225, done);
});
it('should create seq. with interval & not send empty seq', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
// 1300, 2600, 3900, 5200,
[0], [1], [2], [3]
];
check_interval(flow, results, 1300, done);
});
it('should create seq. with interval & send empty seq', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: true, topics: [], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
// 1300, 2600, 3900, 5200,
[null], [0], [1], [2], [null], [3]
];
check_interval(flow, results, 1300, done);
});
it('should handle too many pending messages', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "interval", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [], wires:[["n2"]]},
{id:"n2", type:"helper"}];
helper.load(batchNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
RED.settings.nodeMessageBufferMaxLength = 2;
setTimeout(function() {
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "batch";
});
var evt = logEvents[0][0];
evt.should.have.property('id', "n1");
evt.should.have.property('type', "batch");
evt.should.have.property('msg', "batch.too-many");
done();
}, 150);
for(var i = 0; i < 3; i++) {
n1.receive({payload: i});
}
});
});
});
describe('mode: concat', function() {
it('should concat two seq. (series)', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
[2, 3, 0, 1]
];
var inputs = [
["TB", 0, 0, 2],
["TB", 1, 1, 2],
["TA", 2, 0, 2],
["TA", 3, 1, 2]
];
check_concat(flow, results, inputs, done);
});
it('should concat two seq. (mixed)', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
[2, 3, 0, 1]
];
var inputs = [
["TA", 2, 0, 2],
["TB", 0, 0, 2],
["TA", 3, 1, 2],
["TB", 1, 1, 2]
];
check_concat(flow, results, inputs, done);
});
it('should concat three seq.', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}, {topic: "TC"}], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
[2, 3, 0, 1, 4]
];
var inputs = [
["TC", 4, 0, 1],
["TB", 0, 0, 2],
["TB", 1, 1, 2],
["TA", 2, 0, 2],
["TA", 3, 1, 2]
];
check_concat(flow, results, inputs, done);
});
it('should concat same seq.', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TA"}], wires:[["n2"]]},
{id:"n2", type:"helper"}];
var results = [
[9, 8, 9, 8]
];
var inputs = [
["TA", 9, 0, 2],
["TA", 8, 1, 2]
];
check_concat(flow, results, inputs, done);
});
it('should handle too many pending messages', function(done) {
var flow = [{id:"n1", type:"batch", name: "BatchNode", mode: "concat", count: 0, overlap: 0, interval: 1, allowEmptySequence: false, topics: [{topic: "TA"}, {topic: "TB"}], wires:[["n2"]]},
{id:"n2", type:"helper"}];
helper.load(batchNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
RED.settings.nodeMessageBufferMaxLength = 2;
setTimeout(function() {
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "batch";
});
var evt = logEvents[0][0];
evt.should.have.property('id', "n1");
evt.should.have.property('type', "batch");
evt.should.have.property('msg', "batch.too-many");
done();
}, 150);
var C = 3;
for(var i = 0; i < C; i++) {
var parts_a = {index:i, count:C, id:"A"};
var parts_b = {index:i, count:C, id:"B"};
n1.receive({payload: i, topic: "TA", parts:parts_a});
n1.receive({payload: i, topic: "TB", parts:parts_b});
}
});
});
});
});