1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Debug to status option (#1499)

* Let debug optionally target the status line (32 chars only)

* Add batching of messages to debug ws comms

* let Debug handle simple case of NaN

would also close #1530

* Fixup debug tests for batch comms (no new tests yet)

* mixup comms/api test to match new batch mode (no new tests)

* Add test for NaN being sent OK.

* redo original fix to padding / labels for new debug options

* fix debug test (re-add fix from #1444)

* Fix up merge issues in debug tests
This commit is contained in:
Dave Conway-Jones 2018-01-13 16:14:03 +00:00 committed by Nick O'Leary
parent 7bd8d8c3ae
commit 7b1787fdbb
9 changed files with 260 additions and 134 deletions

View File

@ -64,27 +64,31 @@ RED.comms = (function() {
}
}
ws.onmessage = function(event) {
var msg = JSON.parse(event.data);
if (pendingAuth && msg.auth) {
if (msg.auth === "ok") {
pendingAuth = false;
completeConnection();
} else if (msg.auth === "fail") {
// anything else is an error...
active = false;
RED.user.login({updateMenu:true},function() {
connectWS();
})
var message = JSON.parse(event.data);
for (var m = 0; m < message.length; m++) {
var msg = message[m];
if (pendingAuth && msg.auth) {
if (msg.auth === "ok") {
pendingAuth = false;
completeConnection();
} else if (msg.auth === "fail") {
// anything else is an error...
active = false;
RED.user.login({updateMenu:true},function() {
connectWS();
})
}
}
} else if (msg.topic) {
for (var t in subscriptions) {
if (subscriptions.hasOwnProperty(t)) {
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
if (re.test(msg.topic)) {
var subscribers = subscriptions[t];
if (subscribers) {
for (var i=0;i<subscribers.length;i++) {
subscribers[i](msg.topic,msg.data);
else if (msg.topic) {
for (var t in subscriptions) {
if (subscriptions.hasOwnProperty(t)) {
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
if (re.test(msg.topic)) {
var subscribers = subscriptions[t];
if (subscribers) {
for (var i=0;i<subscribers.length;i++) {
subscribers[i](msg.topic,msg.data);
}
}
}
}

View File

@ -6,11 +6,22 @@
<input id="node-input-complete" type="hidden">
</div>
<div class="form-row">
<label for="node-input-console"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label>
<select type="text" id="node-input-console" style="display: inline-block; width: 250px; vertical-align: top;">
<option value="false" data-i18n="debug.debtab"></option>
<option value="true" data-i18n="debug.tabcon"></option>
</select>
<label for="node-input-tosidebar"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label>
<label for="node-input-tosidebar" style="width:70%">
<input type="checkbox" id="node-input-tosidebar" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toSidebar"></span>
</label>
</div>
<div class="form-row">
<label for="node-input-console"> </label>
<label for="node-input-console" style="width:70%">
<input type="checkbox" id="node-input-console" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toConsole"></span>
</label>
</div>
<div class="form-row" id="node-tostatus-line">
<label for="node-input-tostatus"> </label>
<label for="node-input-tostatus" style="width:70%">
<input type="checkbox" id="node-input-tostatus" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toStatus"></span>
</label>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
@ -26,7 +37,7 @@
<p>Alongside each message, the debug sidebar includes information about the time the message was received, the node that sent it and the type of the message.
Clicking on the source node id will reveal that node within the workspace.</p>
<p>The button on the node can be used to enable or disable its output. It is recommended to disable or remove any Debug nodes that are not being used.</p>
<p>The node can also be configured to send all messages to the runtime log.</p>
<p>The node can also be configured to send all messages to the runtime log, or to send short (32 characters) to the status text under the debug node.</p>
</script>
<script src="debug/view/debug-utils.js"></script>
@ -38,7 +49,9 @@
defaults: {
name: {value:""},
active: {value:true},
console: {value:"false"},
tosidebar: {value:true},
console: {value:false},
tostatus: {value:false},
complete: {value:"false", required:true}
},
label: function() {
@ -100,7 +113,6 @@
}
},
onpaletteadd: function() {
var options = {
messageMouseEnter: function(sourceId) {
if (sourceId) {
@ -148,7 +160,7 @@
var that = this;
RED._debug = function(msg) {
that.handleDebugMessage("",{
that.handleDebugMessage("", {
name:"debug",
msg:msg
});
@ -170,7 +182,6 @@
var sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z);
if (sourceNode) {
o._source = {id:sourceNode.id,z:sourceNode.z,name:sourceNode.name};
}
RED.debug.handleDebugMessage(o);
if (subWindow) {
@ -225,6 +236,15 @@
delete RED._debug;
},
oneditprepare: function() {
if (this.tosidebar === undefined) {
this.tosidebar = true;
$("#node-input-tosidebar").prop('checked', true);
}
if (typeof this.console === "string") {
this.console = (this.console == 'true');
$("#node-input-console").prop('checked', this.console);
$("#node-input-tosidebar").prop('checked', true);
}
$("#node-input-typed-complete").typedInput({types:['msg', {value:"full",label:RED._("node-red:debug.msgobj"),hasValue:false}]});
if (this.complete === "true" || this.complete === true) {
// show complete message object
@ -240,6 +260,16 @@
) {
$("#node-input-typed-complete").typedInput('value','payload');
}
if ($("#node-input-typed-complete").typedInput('type') === 'msg') {
$("#node-tostatus-line").show();
}
else { $("#node-tostatus-line").hide(); }
});
$("#node-input-complete").on('change',function() {
if ($("#node-input-typed-complete").typedInput('type') === 'msg') {
$("#node-tostatus-line").show();
}
else { $("#node-tostatus-line").hide(); }
});
},
oneditsave: function() {
@ -250,7 +280,6 @@
$("#node-input-complete").val($("#node-input-typed-complete").typedInput('value'));
}
}
});
})();
</script>

View File

@ -5,7 +5,7 @@ module.exports = function(RED) {
var events = require("events");
var path = require("path");
var safeJSONStringify = require("json-stringify-safe");
var debuglength = RED.settings.debugMaxLength||1000;
var debuglength = RED.settings.debugMaxLength || 1000;
var useColors = RED.settings.debugUseColors || false;
util.inspect.styles.boolean = "red";
@ -13,26 +13,49 @@ module.exports = function(RED) {
RED.nodes.createNode(this,n);
this.name = n.name;
this.complete = (n.complete||"payload").toString();
if (this.complete === "false") {
this.complete = "payload";
}
this.console = n.console;
if (this.complete === "false") { this.complete = "payload"; }
this.console = ""+(n.console || false);
this.tostatus = n.tostatus || false;
this.tosidebar = n.tosidebar;
if (this.tosidebar === undefined) { this.tosidebar = true; }
this.severity = n.severity || 40;
this.active = (n.active === null || typeof n.active === "undefined") || n.active;
this.status({});
var node = this;
var levels = {
off: 1,
fatal: 10,
error: 20,
warn: 30,
info: 40,
debug: 50,
trace: 60,
audit: 98,
metric: 99
};
var colors = {
"0": "grey",
"10": "grey",
"20": "red",
"30": "yellow",
"40": "grey",
"50": "green",
"60": "blue"
};
this.on("input",function(msg) {
if (this.complete === "true") {
// debug complete msg object
// debug complete msg object
if (this.console === "true") {
node.log("\n"+util.inspect(msg, {colors:useColors, depth:10}));
}
if (this.active) {
sendDebug({id:node.id,name:node.name,topic:msg.topic,msg:msg,_path:msg._path});
if (this.active && this.tosidebar) {
sendDebug({id:node.id, name:node.name, topic:msg.topic, msg:msg, _path:msg._path});
}
} else {
// debug user defined msg property
}
else {
// debug user defined msg property
var property = "payload";
var output = msg[property];
if (this.complete !== "false" && typeof this.complete !== "undefined") {
@ -53,7 +76,15 @@ module.exports = function(RED) {
}
}
if (this.active) {
sendDebug({id:node.id,z:node.z,name:node.name,topic:msg.topic,property:property,msg:output,_path:msg._path});
if (this.tosidebar == true) {
sendDebug({id:node.id, z:node.z, name:node.name, topic:msg.topic, property:property, msg:output, _path:msg._path});
}
if (this.tostatus === true) {
var st = util.inspect(output);
if (st.length > 32) { st = st.substr(0,32) + "..."; }
node.oldStatus = {fill:colors[node.severity], shape:"dot", text:st};
node.status(node.oldStatus);
}
}
}
});
@ -196,9 +227,14 @@ module.exports = function(RED) {
if (state === "enable") {
node.active = true;
res.sendStatus(200);
if (node.tostatus) { node.status({}); }
} else if (state === "disable") {
node.active = false;
res.sendStatus(201);
if (node.tostatus && node.hasOwnProperty("oldStatus")) {
node.oldStatus.shape = "ring";
node.status(node.oldStatus);
}
} else {
res.sendStatus(404);
}

View File

@ -439,7 +439,9 @@ RED.debug = (function() {
$('<span class="debug-message-name">'+name+'</span>').appendTo(metaRow);
}
if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) {
if ((format === 'number') && (payload === "NaN")) {
payload = Number.NaN;
} else if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) {
payload = JSON.parse(payload);
} else if (/error/i.test(format)) {
payload = JSON.parse(payload);

View File

@ -103,9 +103,13 @@
"output": "Output",
"msgprop": "message property",
"msgobj": "complete msg object",
"to": "to",
"to": "To",
"debtab": "debug tab",
"tabcon": "debug tab and console",
"toSidebar": "debug window",
"toConsole": "system console",
"toStatus": "node status (32 characters)",
"severity": "Level",
"notification": {
"activated": "Successfully activated: __label__",
"deactivated": "Successfully deactivated: __label__"

View File

@ -63,7 +63,7 @@ function start() {
// https://github.com/websockets/ws/pull/632
// that is fixed in the 1.x release of the ws module
// that we cannot currently pickup as it drops node 0.10 support
perMessageDeflate: false
//perMessageDeflate: false
});
wsServer.on('connection',function(ws) {
@ -189,15 +189,27 @@ function publish(topic,data,retain) {
}
}
var stack = [];
var ok2tx = true;
function publishTo(ws,topic,data) {
var msg = JSON.stringify({topic:topic,data:data});
try {
ws.send(msg);
} catch(err) {
removeActiveConnection(ws);
removePendingConnection(ws);
log.warn(log._("comms.error-send",{message:err.toString()}));
if (topic && data) { stack.push({topic:topic,data:data}); }
if (ok2tx && (stack.length > 0)) {
ok2tx = false;
try {
ws.send(JSON.stringify(stack));
} catch(err) {
removeActiveConnection(ws);
removePendingConnection(ws);
log.warn(log._("comms.error-send",{message:err.toString()}));
}
stack = [];
var txtout = setTimeout(function() {
ok2tx = true;
publishTo(ws);
}, 50); // TODO: OK so a 50mS update rate should prob not be hard-coded
}
}
function handleRemoteSubscription(ws,topic) {

View File

@ -51,10 +51,14 @@ describe('inject node', function() {
function() {
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
msg.should.have.property('topic', 't1');
msg.should.have.property('payload');
should(msg.payload).be.lessThan(timestamp.getTime());
done();
try {
msg.should.have.property('topic', 't1');
msg.should.have.property('payload');
should(msg.payload).be.lessThan(timestamp.getTime());
done();
} catch(err) {
done(err);
}
});
});
});

View File

@ -25,13 +25,19 @@ describe('debug node', function() {
helper.startServer(done);
});
beforeEach(function (done) {
setTimeout(function() {
done();
}, 55);
});
afterEach(function() {
helper.unload();
});
it('should be loaded', function(done) {
var flow = [{id:"n1", type:"debug", name: "Debug", complete:"false" }];
var flow = [{id:"n1", type:"debug", name:"Debug", complete:"false" }];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
n1.should.have.property('name', 'Debug');
@ -41,31 +47,31 @@ describe('debug node', function() {
});
it('should publish on input', function(done) {
var flow = [{id:"n1", type:"debug", name: "Debug" }];
var flow = [{id:"n1", type:"debug", name:"Debug" }];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload:"test"});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",name:"Debug",msg:"test",
format:"string[4]",property:"payload"}
});
}]);
}, done);
});
});
it('should publish to console', function(done) {
var flow = [{id:"n1", type:"debug", console: "true"}];
var flow = [{id:"n1", type:"debug", console:"true"}];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
var count = 0;
websocket_test(function() {
n1.emit("input", {payload:"test"});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:"test",property:"payload",format:"string[4]"}
});
}]);
count++;
}, function() {
try {
@ -86,31 +92,31 @@ describe('debug node', function() {
});
it('should publish complete message', function(done) {
var flow = [{id:"n1", type:"debug", complete: "true" }];
var flow = [{id:"n1", type:"debug", complete:"true" }];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload:"test"});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",
data:{id:"n1",msg:'{\n "payload": "test"\n}',format:"Object"}
});
}]);
}, done);
});
});
it('should publish complete message to console', function(done) {
var flow = [{id:"n1", type:"debug", complete: "true", console: "true" }];
var flow = [{id:"n1", type:"debug", complete:"true", console:"true" }];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload:"test"});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",
data:{id:"n1",msg:'{\n "payload": "test"\n}',format:"Object"}
});
}]);
}, function() {
try {
helper.log().called.should.be.true();
@ -129,29 +135,29 @@ describe('debug node', function() {
});
it('should publish other property', function(done) {
var flow = [{id:"n1", type:"debug", complete: "foo" }];
var flow = [{id:"n1", type:"debug", complete:"foo" }];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload:"test", foo:"bar"});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:"bar",property:"foo",format:"string[3]"}
});
}]);
}, done);
});
});
it('should publish multi-level properties', function(done) {
var flow = [{id:"n1", type:"debug", complete: "foo.bar" }];
var flow = [{id:"n1", type:"debug", complete:"foo.bar" }];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload:"test", foo: {bar: "bar"}});
n1.emit("input", {payload:"test", foo: {bar:"bar"}});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:"bar",property:"foo.bar",format:"string[3]"}
});
}]);
}, done);
});
});
@ -163,9 +169,9 @@ describe('debug node', function() {
websocket_test(function() {
n1.emit("input", {payload: new Error("oops")});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:'{"name":"Error","message":"oops"}',property:"payload",format:"error"}
});
}]);
}, done);
});
});
@ -177,9 +183,9 @@ describe('debug node', function() {
websocket_test(function() {
n1.emit("input", {payload: true});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg: 'true',property:"payload",format:"boolean"}
});
}]);
}, done);
});
});
@ -191,9 +197,23 @@ describe('debug node', function() {
websocket_test(function() {
n1.emit("input", {payload: 7});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:"7",property:"payload",format:"number"}
});
}]);
}, done);
});
});
it('should publish a NaN', function(done) {
var flow = [{id:"n1", type:"debug", console:"true" }];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload: Number.NaN});
}, function(msg) {
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:"NaN",property:"payload",format:"number"}
}]);
}, done);
});
});
@ -205,9 +225,9 @@ describe('debug node', function() {
websocket_test(function() {
n1.emit("input", {});
}, function(msg) {
JSON.parse(msg).should.eql({
topic:"debug",data:{id:"n1",msg: '(undefined)',property:"payload",format:"undefined"}
});
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:'(undefined)',property:"payload",format:"undefined"}
}]);
}, done);
});
});
@ -217,11 +237,11 @@ describe('debug node', function() {
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload: null});
n1.emit("input", {payload:null});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:'(undefined)',property:"payload",format:"null"}
});
}]);
}, done);
});
});
@ -233,10 +253,10 @@ describe('debug node', function() {
websocket_test(function() {
n1.emit("input", {payload: {type:'foo'}});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",
data:{id:"n1",msg:'{\n "type": "foo"\n}',property:"payload",format:"Object"}
});
}]);
}, done);
});
});
@ -248,11 +268,11 @@ describe('debug node', function() {
websocket_test(function() {
n1.emit("input", {payload: [0,1,2,3]});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",
data:{id:"n1",msg: '[\n 0,\n 1,\n 2,\n 3\n]',format:"array[4]",
property:"payload"}
});
}]);
}, done);
});
});
@ -266,28 +286,28 @@ describe('debug node', function() {
o.o = o;
n1.emit("input", {payload: o});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",
data:{
id:"n1",
msg:'{\n "name": "bar",\n "o": "[Circular ~]"\n}',
property:"payload",format:"Object"
}
});
}]);
}, done);
});
});
it('should publish an object to console', function(done) {
var flow = [{id:"n1", type:"debug", console: "true"}];
var flow = [{id:"n1", type:"debug", console:"true"}];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload: {type:'foo'}});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:'{\n "type": "foo"\n}',property:"payload",format:"Object"}
});
}]);
}, function() {
try {
helper.log().called.should.be.true();
@ -306,15 +326,15 @@ describe('debug node', function() {
});
it('should publish a string after a newline to console if the string contains \\n', function(done) {
var flow = [{id:"n1", type:"debug", console: "true"}];
var flow = [{id:"n1", type:"debug", console:"true"}];
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload: "test\ntest"});
n1.emit("input", {payload:"test\ntest"});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:"test\ntest",property:"payload",format:"string[9]"}
});
}]);
}, function() {
try {
helper.log().called.should.be.true();
@ -337,10 +357,10 @@ describe('debug node', function() {
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload: Array(1002).join("X")});
n1.emit("input", {payload:Array(1002).join("X")});
}, function(msg) {
var a = JSON.parse(msg);
a.should.eql({
a.should.eql([{
topic:"debug",
data:{
id:"n1",
@ -348,7 +368,7 @@ describe('debug node', function() {
property:"payload",
format:"string[1001]"
}
});
}]);
}, done);
});
});
@ -361,7 +381,7 @@ describe('debug node', function() {
n1.emit("input", {payload: {foo: Array(1002).join("X")}});
}, function(msg) {
var a = JSON.parse(msg);
a.should.eql({
a.should.eql([{
topic:"debug",
data:{
id:"n1",
@ -369,7 +389,7 @@ describe('debug node', function() {
property:"payload",
format:"Object"
}
});
}]);
}, done);
});
});
@ -382,7 +402,7 @@ describe('debug node', function() {
n1.emit("input", {payload: Array(1001).fill("X")});
}, function(msg) {
var a = JSON.parse(msg);
a.should.eql({
a.should.eql([{
topic:"debug",
data:{
id:"n1",
@ -391,11 +411,11 @@ describe('debug node', function() {
type: "array",
data: Array(1000).fill("X"),
length: 1001
},null," "),
},null," "),
property:"payload",
format:"array[1001]"
}
});
}]);
}, done);
});
});
@ -408,7 +428,7 @@ describe('debug node', function() {
n1.emit("input", {payload: {foo: Array(1001).fill("X")}});
}, function(msg) {
var a = JSON.parse(msg);
a.should.eql({
a.should.eql([{
topic:"debug",
data:{
id:"n1",
@ -423,7 +443,7 @@ describe('debug node', function() {
property:"payload",
format:"Object"
}
});
}]);
}, done);
});
});
@ -436,7 +456,7 @@ describe('debug node', function() {
n1.emit("input", {payload: Buffer(501).fill("\"")});
}, function(msg) {
var a = JSON.parse(msg);
a.should.eql({
a[0].should.eql({
topic:"debug",
data:{
id:"n1",
@ -457,7 +477,7 @@ describe('debug node', function() {
n1.emit("input", {payload: {foo: Buffer(1001).fill("X")}});
}, function(msg) {
var a = JSON.parse(msg);
a.should.eql({
a[0].should.eql({
topic:"debug",
data:{
id:"n1",
@ -482,17 +502,17 @@ describe('debug node', function() {
helper.load(debugNode, flow, function() {
var n1 = helper.getNode("n1");
websocket_test(function() {
n1.emit("input", {payload: new Buffer('HELLO', 'utf8')});
n1.emit("input", {payload: new Buffer.from('HELLO', 'utf8')});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",
data:{
id:"n1",
msg: '48454c4c4f',
msg:'48454c4c4f',
property:"payload",
format: "buffer[5]"
format:"buffer[5]"
}
});
}]);
}, done);
});
});
@ -510,9 +530,9 @@ describe('debug node', function() {
n1.emit("input", {payload:"message 2"});
});
}, function(msg) {
JSON.parse(msg).should.eql({
JSON.parse(msg).should.eql([{
topic:"debug",data:{id:"n1",msg:"message 2",property:"payload",format:"string[9]"}
});
}]);
}, done);
});
});
@ -577,8 +597,12 @@ function websocket_test(open_callback, message_callback, done_callback) {
var close_callback = function() { ws.close(); };
ws.on('open', function() { open_callback(close_callback); });
ws.on('message', function(msg) {
message_callback(msg, close_callback);
ws.close();
done_callback();
try {
message_callback(msg, close_callback);
ws.close();
done_callback();
} catch(err) {
done_callback(err);
}
});
}

View File

@ -31,6 +31,13 @@ var address = '127.0.0.1';
var listenPort = 0; // use ephemeral port
describe("api/comms", function() {
beforeEach(function (done) {
setTimeout(function() {
done();
}, 55);
});
describe("with default keepalive", function() {
var server;
var url;
@ -72,7 +79,7 @@ describe("api/comms", function() {
comms.publish('topic1', 'foo');
});
ws.on('message', function(msg) {
msg.should.equal('{"topic":"topic1","data":"foo"}');
msg.should.equal('[{"topic":"topic1","data":"foo"}]');
ws.close();
done();
});
@ -85,7 +92,8 @@ describe("api/comms", function() {
ws.send('{"subscribe":"topic2"}');
});
ws.on('message', function(msg) {
msg.should.equal('{"topic":"topic2","data":"bar"}');
console.log(msg);
msg.should.equal('[{"topic":"topic2","data":"bar"}]');
ws.close();
done();
});
@ -100,7 +108,8 @@ describe("api/comms", function() {
comms.publish('topic3', 'new');
});
ws.on('message', function(msg) {
msg.should.equal('{"topic":"topic3","data":"new"}');
console.log(msg);
msg.should.equal('[{"topic":"topic3","data":"new"}]');
ws.close();
done();
});
@ -115,7 +124,8 @@ describe("api/comms", function() {
comms.publish('topic3', 'correct');
});
ws.on('message', function(msg) {
msg.should.equal('{"topic":"topic3","data":"correct"}');
console.log(msg);
msg.should.equal('[{"topic":"topic3","data":"correct"}]');
ws.close();
done();
});
@ -133,7 +143,8 @@ describe("api/comms", function() {
comms.publish('topic4', 'bar');
});
ws.on('message', function(msg) {
msg.should.equal('{"topic":"topic4","data":"bar"}');
console.log(msg);
msg.should.equal('[{"topic":"topic4","data":"bar"}]');
ws.close();
done();
});
@ -325,7 +336,7 @@ describe("api/comms", function() {
var ws = new WebSocket(url);
var count = 0;
ws.on('message', function(data) {
var msg = JSON.parse(data);
var msg = JSON.parse(data)[0];
msg.should.have.property('topic','hb');
msg.should.have.property('data').be.a.Number;
count++;
@ -346,7 +357,7 @@ describe("api/comms", function() {
}, 50);
});
ws.on('message', function(data) {
var msg = JSON.parse(data);
var msg = JSON.parse(data)[0];
// It is possible a heartbeat message may arrive - so ignore them
if (msg.topic != "hb") {
msg.should.have.property('topic', 'foo');
@ -435,7 +446,7 @@ describe("api/comms", function() {
ws.send('{"subscribe":"foo"}');
comms.publish('foo', 'correct');
} else {
msg.should.equal('{"topic":"foo","data":"correct"}');
msg.should.equal('[{"topic":"foo","data":"correct"}]');
ws.close();
}
});
@ -509,7 +520,7 @@ describe("api/comms", function() {
},200);
});
ws.on('message', function(msg) {
msg.should.equal('{"topic":"foo","data":"correct"}');
msg.should.equal('[{"topic":"foo","data":"correct"}]');
count++;
ws.close();
});