/* * osc.js: An Open Sound Control library for JavaScript that works in both the browser and Node.js * * Node.js Transport Tests * * Copyright 2014-2016, Colin Clark * Licensed under the MIT and GPL 3 licenses. */ /*global require*/ /*jshint node:true*/ "use strict"; var fluid = fluid || require("infusion"), jqUnit = jqUnit || fluid.require("node-jqunit"), osc = osc || require("../src/platforms/osc-node.js"); var QUnit = fluid.registerNamespace("QUnit"); jqUnit.module("Node.js transport tests"); var testOSCMessage = { address: "/test/freq", args: [440] }; /************* * UDP Tests * *************/ function createUDPReceiver(onMessage, o) { o = o || {}; var oscUDP = new osc.UDPPort(o); if (onMessage) { oscUDP.on("message", function (msg, timeTag, rinfo) { onMessage(msg, oscUDP, rinfo); }); } oscUDP.open(); return oscUDP; } function testReadUDP(msg, receiverOptions, senderOptions) { if (!receiverOptions) { receiverOptions = { localAddress: "127.0.0.1", localPort: 57121 }; } if (!senderOptions) { senderOptions = { localAddress: "127.0.0.1", localPort: 57122, remoteAddress: "127.0.0.1", remotePort: 57121 }; } var receiverPort, senderPort; var receiveFn = function (receivedOSCMessage) { QUnit.deepEqual(receivedOSCMessage, testOSCMessage, msg); receiverPort.close(); senderPort.close(); jqUnit.start(); }; receiverPort = createUDPReceiver(receiveFn, receiverOptions); senderPort = new osc.UDPPort(senderOptions); senderPort.open(); // TODO: When Ports support Promises, make sure that this // only executes after both Ports are ready. receiverPort.on("ready", function () { senderPort.send(testOSCMessage); }); } jqUnit.asyncTest("Send a message via a UDP socket", function () { testReadUDP("The message should have been sent and received successfully."); }); jqUnit.asyncTest("Send a multicast message via a UDP socket", function () { var receiverOptions = { localAddress: "0.0.0.0", localPort: 57121, multicastMembership: ["239.255.255.250"] }; var senderOptions = { multicastTTL: 2, localAddress: "0.0.0.0", localPort: 57122, remoteAddress: "239.255.255.250", remotePort: 57121 }; testReadUDP("The message should have been sent and received successfully when multicast is enabled.", receiverOptions, senderOptions); }); jqUnit.asyncTest("Send a broadcast message via a UDP socket", function () { var receiverOptions = { broadcast: true, localAddress: "0.0.0.0", localPort: 57121 }; var senderOptions = { broadcast: true, localAddress: "0.0.0.0", localPort: 57122, remoteAddress: "255.255.255.255", remotePort: 57121 }; testReadUDP("The message should have been sent and received successfully when multicast is enabled.", receiverOptions, senderOptions); }); jqUnit.asyncTest("Read from a UDP socket with metadata: true", function () { var expected = { address: "/sl/1/down", args: [ { type: "f", // OSC type tag string value: 444.4 } ] }; var udpListener = function (msg, udpPort, rinfo) { QUnit.equal(msg.address, expected.address); QUnit.ok(Object.prototype.toString.call(msg.args) === "[object Array]", "The message arguments should be in an array."); QUnit.equal(msg.args.length, 1, "There should only be one argument."); QUnit.equal(msg.args[0].type, expected.args[0].type, "Type metadata should have been included."); QUnit.equal(typeof msg.args[0].value, "number", "The argument type should be a number."); jqUnit.assertLeftHand( "A remote information object should have been passed to the onMessage callback.", { address: "127.0.0.1", port: 57121 }, rinfo ); udpPort.close(); jqUnit.start(); }; var oscUDP = createUDPReceiver(udpListener, { metadata: true }); oscUDP.on("ready", function () { oscUDP.send(expected); }); }); /******************** * Web Socket Tests * ********************/ var ws = require("ws"); function createWSServer(onConnection) { // Setup the Web Socket server. var wss = new ws.Server({ port: 8081 }); wss.on("connection", function (socket) { var serverWebSocketPort = new osc.WebSocketPort({ socket: socket }); serverWebSocketPort.on("error", function (err) { console.error("A server error occurred while running the Web Socket tests: "); console.error(err.stack); }); onConnection(serverWebSocketPort); }); return wss; } function createWSClient(onMessage) { // Create a Web Socket client and connect it to the server. var wsc = new osc.WebSocketPort({ url: "ws://localhost:8081" }); wsc.on("message", onMessage); wsc.on("error", function (err) { console.error("A client error occurred while running the Web Socket tests: ", err); }); wsc.open(); return wsc; } function checkMessageReceived(oscMessage, wss, wsc, assertMessage) { QUnit.deepEqual(oscMessage, testOSCMessage, assertMessage); wsc.close(); wss.close(); } jqUnit.asyncTest("Send OSC messages both directions via a Web Socket", function () { var wss = createWSServer(function (oscServerPort) { oscServerPort.on("message", function (oscMessage) { QUnit.deepEqual(oscMessage, testOSCMessage, "The message should have been sent to the web socket server."); oscServerPort.send(testOSCMessage); }); }); var wsc = createWSClient(function (msg) { checkMessageReceived(msg, wss, wsc, "The message should have been sent to the web socket client."); jqUnit.start(); }); wsc.on("ready", function () { wsc.send(testOSCMessage); }); }); function testRelay(isRaw) { var udpPort = createUDPReceiver(), relay; udpPort.on("ready", function () { var wss = createWSServer(function (wsServerPort) { relay = new osc.Relay(udpPort, wsServerPort, { raw: isRaw }); udpPort.send(testOSCMessage); }); var wsc = createWSClient(function (msg) { checkMessageReceived(msg, wss, wsc, "The message should have been proxied from UDP to the web socket."); udpPort.close(); jqUnit.start(); }); }); } jqUnit.asyncTest("Parsed message relaying between UDP and Web Sockets", function () { testRelay(false); }); jqUnit.asyncTest("Raw relaying between UDP and Web Sockets", function () { testRelay(true); }); jqUnit.asyncTest("Relay closes when first port closes", function () { var firstPort = new osc.UDPPort({ localPort: 57121 }); var secondPort = new osc.UDPPort({ localPort: 57122 }); var relay = new osc.Relay(firstPort, secondPort); relay.on("close", function () { QUnit.ok(true, "The relay emitted its close event as a result of the first port closing."); jqUnit.start(); }); firstPort.on("ready", function () { secondPort.on("ready", function () { firstPort.close(); }); }); firstPort.open(); secondPort.open(); }); /************* * TCP Tests * *************/ var net = require("net"); jqUnit.asyncTest("Send an OSC message via TCP", function () { var port = 57122; var tcpServer = net.createServer(function (socket) { var tcpServerPort = new osc.TCPSocketPort({ socket: socket }); tcpServerPort.on("error", function (err) { console.error(err); }); tcpServerPort.on("message", function (msg) { QUnit.deepEqual(msg, testOSCMessage, "The message should have been sent to the TCP server."); tcpServer.close(); jqUnit.start(); }); }); var tcpClientPort = new osc.TCPSocketPort({ address: "127.0.0.1", port: port }); tcpClientPort.on("ready", function () { tcpClientPort.send(testOSCMessage); }); tcpClientPort.on("error", function (err) { console.error(err); }); tcpServer.listen(port, function () { tcpClientPort.open(); }); /**************** * Serial Tests * ****************/ QUnit.test("Serial port support has been loaded.", function () { QUnit.expect(1); QUnit.ok(osc.supportsSerial); }); });