| Index: extensions/test/data/serial_unittest.js
|
| diff --git a/extensions/test/data/serial_unittest.js b/extensions/test/data/serial_unittest.js
|
| index dc7bbea56e06cddd8453f3a73358d177fe90f9fb..c3cc504bd6132814736930a0a11e7a92b1a0c185 100644
|
| --- a/extensions/test/data/serial_unittest.js
|
| +++ b/extensions/test/data/serial_unittest.js
|
| @@ -6,29 +6,69 @@
|
| * Unit tests for the JS serial service client.
|
| *
|
| * These test that configuration and data are correctly transmitted between the
|
| - * client and the service.
|
| + * client and the service. They are launched by
|
| + * extensions/renderer/api/serial/serial_api_unittest.cc.
|
| */
|
|
|
| var test = require('test').binding;
|
| var serial = require('serial').binding;
|
| var unittestBindings = require('test_environment_specific_bindings');
|
| +var utils = require('utils');
|
| +
|
| +var timeoutManager = new unittestBindings.TimeoutManager();
|
| +timeoutManager.installGlobals();
|
| +
|
| +var BUFFER_SIZE = 10;
|
|
|
| var connectionId = null;
|
|
|
| function connect(callback, options) {
|
| options = options || {
|
| name: 'test connection',
|
| - bufferSize: 8192,
|
| + bufferSize: BUFFER_SIZE,
|
| receiveTimeout: 12345,
|
| sendTimeout: 6789,
|
| persistent: true,
|
| - }
|
| + };
|
| serial.connect('device', options, test.callbackPass(function(connectionInfo) {
|
| connectionId = connectionInfo.connectionId;
|
| - callback(connectionInfo);
|
| + if (callback)
|
| + callback(connectionInfo);
|
| }));
|
| }
|
|
|
| +// Sets a function to be called once when data is received. Returns a promise
|
| +// that will resolve once the hook is installed.
|
| +function addReceiveHook(callback) {
|
| + return requireAsync('serial_service').then(function(serialService) {
|
| + var called = false;
|
| + var dataReceived = serialService.Connection.prototype.onDataReceived_;
|
| + serialService.Connection.prototype.onDataReceived_ = function() {
|
| + var result = $Function.apply(dataReceived, this, arguments);
|
| + if (!called)
|
| + callback();
|
| + called = true;
|
| + return result;
|
| + };
|
| + });
|
| +}
|
| +
|
| +// Sets a function to be called once when a receive error is received. Returns a
|
| +// promise that will resolve once the hook is installed.
|
| +function addReceiveErrorHook(callback) {
|
| + return requireAsync('serial_service').then(function(serialService) {
|
| + var called = false;
|
| + var receiveError = serialService.Connection.prototype.onReceiveError_;
|
| + serialService.Connection.prototype.onReceiveError_ = function() {
|
| + var result = $Function.apply(receiveError, this, arguments);
|
| + if (!called)
|
| + callback();
|
| + called = true;
|
| + return result;
|
| + };
|
| + });
|
| +}
|
| +
|
| function disconnect() {
|
| serial.disconnect(connectionId, test.callbackPass(function(success) {
|
| test.assertTrue(success);
|
| @@ -41,7 +81,7 @@ function checkClientConnectionInfo(connectionInfo) {
|
| test.assertEq('test connection', connectionInfo.name);
|
| test.assertEq(12345, connectionInfo.receiveTimeout);
|
| test.assertEq(6789, connectionInfo.sendTimeout);
|
| - test.assertEq(8192, connectionInfo.bufferSize);
|
| + test.assertEq(BUFFER_SIZE, connectionInfo.bufferSize);
|
| test.assertFalse(connectionInfo.paused);
|
| }
|
|
|
| @@ -58,7 +98,52 @@ function checkConnectionInfo(connectionInfo) {
|
| checkServiceConnectionInfo(connectionInfo);
|
| }
|
|
|
| +function runReceiveErrorTest(expectedError) {
|
| + connect();
|
| + test.listenOnce(serial.onReceiveError, function(result) {
|
| + serial.getInfo(connectionId, test.callbackPass(function(connectionInfo) {
|
| + disconnect();
|
| + test.assertTrue(connectionInfo.paused);
|
| + }));
|
| + test.assertEq(connectionId, result.connectionId);
|
| + test.assertEq(expectedError, result.error);
|
| + });
|
| +}
|
| +
|
| +function runSendErrorTest(expectedError) {
|
| + connect(function() {
|
| + var buffer = new ArrayBuffer(1);
|
| + serial.send(connectionId, buffer, test.callbackPass(function(sendInfo) {
|
| + disconnect();
|
| + test.assertEq(0, sendInfo.bytesSent);
|
| + test.assertEq(expectedError, sendInfo.error);
|
| + }));
|
| + });
|
| +}
|
| +
|
| +function sendData() {
|
| + var data = 'data';
|
| + var buffer = new ArrayBuffer(data.length);
|
| + var byteBuffer = new Int8Array(buffer);
|
| + for (var i = 0; i < data.length; i++) {
|
| + byteBuffer[i] = data.charCodeAt(i);
|
| + }
|
| + return utils.promise(serial.send, connectionId, buffer);
|
| +}
|
| +
|
| +function checkReceivedData(result) {
|
| + var data = 'data';
|
| + test.assertEq(connectionId, result.connectionId);
|
| + test.assertEq(data.length, result.data.byteLength);
|
| + var resultByteBuffer = new Int8Array(result.data);
|
| + for (var i = 0; i < data.length; i++) {
|
| + test.assertEq(data.charCodeAt(i), resultByteBuffer[i]);
|
| + }
|
| +}
|
| +
|
| unittestBindings.exportTests([
|
| + // Test that getDevices correctly transforms the data returned by the
|
| + // SerialDeviceEnumerator.
|
| function testGetDevices() {
|
| serial.getDevices(test.callbackPass(function(devices) {
|
| test.assertEq(3, devices.length);
|
| @@ -74,21 +159,29 @@ unittestBindings.exportTests([
|
| }));
|
| },
|
|
|
| + // Test that the correct error message is returned when an error occurs in
|
| + // connecting to the port. This test uses an IoHandler that fails to connect.
|
| function testConnectFail() {
|
| serial.connect('device',
|
| test.callbackFail('Failed to connect to the port.'));
|
| },
|
|
|
| + // Test that the correct error message is returned when an error occurs in
|
| + // calling getPortInfo after connecting to the port. This test uses an
|
| + // IoHandler that fails on calls to GetPortInfo.
|
| function testGetInfoFailOnConnect() {
|
| serial.connect('device',
|
| test.callbackFail('Failed to connect to the port.'));
|
| },
|
|
|
| + // Test that the correct error message is returned when an invalid bit-rate
|
| + // value is passed to connect.
|
| function testConnectInvalidBitrate() {
|
| serial.connect('device', {bitrate: -1}, test.callbackFail(
|
| 'Failed to connect to the port.'));
|
| },
|
|
|
| + // Test that a successful connect returns the expected connection info.
|
| function testConnect() {
|
| connect(function(connectionInfo) {
|
| disconnect();
|
| @@ -96,6 +189,8 @@ unittestBindings.exportTests([
|
| });
|
| },
|
|
|
| + // Test that a connection created with no options has the correct default
|
| + // options.
|
| function testConnectDefaultOptions() {
|
| connect(function(connectionInfo) {
|
| disconnect();
|
| @@ -112,6 +207,8 @@ unittestBindings.exportTests([
|
| }, {});
|
| },
|
|
|
| + // Test that a getInfo call correctly converts the service-side info from the
|
| + // Mojo format and returns both it and the client-side configuration.
|
| function testGetInfo() {
|
| connect(function() {
|
| serial.getInfo(connectionId,
|
| @@ -122,6 +219,9 @@ unittestBindings.exportTests([
|
| });
|
| },
|
|
|
| + // Test that only client-side options are returned when the service fails a
|
| + // getInfo call. This test uses an IoHandler that fails GetPortInfo calls
|
| + // after the initial call during connect.
|
| function testGetInfoFailToGetPortInfo() {
|
| connect(function() {
|
| serial.getInfo(connectionId,
|
| @@ -137,6 +237,7 @@ unittestBindings.exportTests([
|
| });
|
| },
|
|
|
| + // Test that getConnections returns an array containing the open connection.
|
| function testGetConnections() {
|
| connect(function() {
|
| serial.getConnections(test.callbackPass(function(connections) {
|
| @@ -147,6 +248,9 @@ unittestBindings.exportTests([
|
| });
|
| },
|
|
|
| + // Test that getControlSignals correctly converts the Mojo format result. This
|
| + // test uses an IoHandler that returns values matching the pattern being
|
| + // tested.
|
| function testGetControlSignals() {
|
| connect(function() {
|
| var calls = 0;
|
| @@ -169,6 +273,9 @@ unittestBindings.exportTests([
|
| });
|
| },
|
|
|
| + // Test that setControlSignals correctly converts to the Mojo format result.
|
| + // This test uses an IoHandler that returns values following the same table of
|
| + // values as |signalsValues|.
|
| function testSetControlSignals() {
|
| connect(function() {
|
| var signalsValues = [
|
| @@ -197,6 +304,10 @@ unittestBindings.exportTests([
|
| });
|
| },
|
|
|
| + // Test that update correctly passes values to the service only for
|
| + // service-side options and that all update calls are reflected by the result
|
| + // of getInfo calls. This test uses an IoHandler that expects corresponding
|
| + // ConfigurePort calls.
|
| function testUpdate() {
|
| connect(function() {
|
| var optionsValues = [
|
| @@ -240,6 +351,7 @@ unittestBindings.exportTests([
|
| });
|
| },
|
|
|
| + // Test that passing an invalid bit-rate reslts in an error.
|
| function testUpdateInvalidBitrate() {
|
| connect(function() {
|
| serial.update(connectionId,
|
| @@ -251,16 +363,19 @@ unittestBindings.exportTests([
|
| });
|
| },
|
|
|
| + // Test flush. This test uses an IoHandler that counts the number of flush
|
| + // calls.
|
| function testFlush() {
|
| connect(function() {
|
| - serial.flush(connectionId,
|
| - test.callbackPass(function(success) {
|
| + serial.flush(connectionId, test.callbackPass(function(success) {
|
| disconnect();
|
| test.assertTrue(success);
|
| }));
|
| });
|
| },
|
|
|
| + // Test that setPaused values are reflected by the results returned by getInfo
|
| + // calls.
|
| function testSetPaused() {
|
| connect(function() {
|
| serial.setPaused(connectionId, true, test.callbackPass(function() {
|
| @@ -277,36 +392,283 @@ unittestBindings.exportTests([
|
| });
|
| },
|
|
|
| + // Test that a send and a receive correctly echoes data. This uses an
|
| + // IoHandler that echoes data sent to it.
|
| + function testEcho() {
|
| + connect(function() {
|
| + sendData().then(test.callbackPass(function(sendInfo) {
|
| + test.assertEq(4, sendInfo.bytesSent);
|
| + test.assertEq(undefined, sendInfo.error);
|
| + }));
|
| + test.listenOnce(serial.onReceive, function(result) {
|
| + checkReceivedData(result);
|
| + disconnect();
|
| + });
|
| + });
|
| + },
|
| +
|
| + // Test that a send while another send is in progress returns a pending error.
|
| + function testSendDuringExistingSend() {
|
| + connect(function() {
|
| + sendData().then(test.callbackPass(function(sendInfo) {
|
| + test.assertEq(4, sendInfo.bytesSent);
|
| + test.assertEq(undefined, sendInfo.error);
|
| + disconnect();
|
| + }));
|
| + sendData().then(test.callbackPass(function(sendInfo) {
|
| + test.assertEq(0, sendInfo.bytesSent);
|
| + test.assertEq('pending', sendInfo.error);
|
| + }));
|
| + });
|
| + },
|
| +
|
| + // Test that a second send after the first finishes is successful. This uses
|
| + // an IoHandler that echoes data sent to it.
|
| + function testSendAfterSuccessfulSend() {
|
| + connect(function() {
|
| + sendData().then(test.callbackPass(function(sendInfo) {
|
| + test.assertEq(4, sendInfo.bytesSent);
|
| + test.assertEq(undefined, sendInfo.error);
|
| + return sendData();
|
| + })).then(test.callbackPass(function(sendInfo) {
|
| + test.assertEq(4, sendInfo.bytesSent);
|
| + test.assertEq(undefined, sendInfo.error);
|
| + }));
|
| + // Check that the correct data is echoed twice.
|
| + test.listenOnce(serial.onReceive, function(result) {
|
| + checkReceivedData(result);
|
| + test.listenOnce(serial.onReceive, function(result) {
|
| + checkReceivedData(result);
|
| + disconnect();
|
| + });
|
| + });
|
| + });
|
| + },
|
| +
|
| + // Test that a second send after the first fails is successful. This uses an
|
| + // IoHandler that returns system_error for only the first send.
|
| + function testSendPartialSuccessWithError() {
|
| + connect(function() {
|
| + sendData().then(test.callbackPass(function(sendInfo) {
|
| + test.assertEq(2, sendInfo.bytesSent);
|
| + test.assertEq('system_error', sendInfo.error);
|
| + return sendData();
|
| + })).then(test.callbackPass(function(sendInfo) {
|
| + test.assertEq(4, sendInfo.bytesSent);
|
| + test.assertEq(undefined, sendInfo.error);
|
| + disconnect();
|
| + }));
|
| + });
|
| + },
|
| +
|
| + // Test that a timed-out send returns a timeout error and that changing the
|
| + // send timeout during a send does not affect its timeout. This test uses an
|
| + // IoHandle that never completes sends.
|
| + function testSendTimeout() {
|
| + connect(function() {
|
| + sendData().then(test.callbackPass(function(sendInfo) {
|
| + test.assertEq(0, sendInfo.bytesSent);
|
| + test.assertEq('timeout', sendInfo.error);
|
| + test.assertEq(5, timeoutManager.currentTime);
|
| + disconnect();
|
| + }));
|
| + serial.update(connectionId, {sendTimeout: 10}, test.callbackPass(
|
| + timeoutManager.run.bind(timeoutManager, 1)));
|
| + }, {sendTimeout: 5});
|
| + },
|
| +
|
| + // Test that a timed-out send returns a timeout error and that disabling the
|
| + // send timeout during a send does not affect its timeout. This test uses an
|
| + // IoHandle that never completes sends.
|
| + function testDisableSendTimeout() {
|
| + connect(function() {
|
| + sendData().then(test.callbackPass(function(sendInfo) {
|
| + test.assertEq(0, sendInfo.bytesSent);
|
| + test.assertEq('timeout', sendInfo.error);
|
| + test.assertEq(6, timeoutManager.currentTime);
|
| + disconnect();
|
| + }));
|
| + serial.update(connectionId, {sendTimeout: 0}, test.callbackPass(
|
| + timeoutManager.run.bind(timeoutManager, 1)));
|
| + }, {sendTimeout: 6});
|
| + },
|
| +
|
| + // Test that data received while the connection is paused is queued and
|
| + // dispatched once the connection is unpaused.
|
| + function testPausedReceive() {
|
| + // Wait until the receive hook is installed, then start the test.
|
| + addReceiveHook(function() {
|
| + // Unpause the connection after the connection has queued the received
|
| + // data to ensure the queued data is dispatched when the connection is
|
| + // unpaused.
|
| + serial.setPaused(connectionId, false, test.callbackPass());
|
| + // Check that setPaused(false) is idempotent.
|
| + serial.setPaused(connectionId, false, test.callbackPass());
|
| + }).then(function() {
|
| + connect(function() {
|
| + // Check that setPaused(true) is idempotent.
|
| + serial.setPaused(connectionId, true, test.callbackPass());
|
| + serial.setPaused(connectionId, true, test.callbackPass());
|
| + });
|
| + });
|
| + test.listenOnce(serial.onReceive, function(result) {
|
| + checkReceivedData(result);
|
| + disconnect();
|
| + });
|
| + },
|
| +
|
| + // Test that a receive error received while the connection is paused is queued
|
| + // and dispatched once the connection is unpaused.
|
| + function testPausedReceiveError() {
|
| + addReceiveErrorHook(function() {
|
| + // Unpause the connection after the connection has queued the receive
|
| + // error to ensure the queued error is dispatched when the connection is
|
| + // unpaused.
|
| + serial.setPaused(connectionId, false, test.callbackPass());
|
| + }).then(test.callbackPass(function() {
|
| + connect(function() {
|
| + serial.setPaused(connectionId, true, test.callbackPass());
|
| + });
|
| + }));
|
| +
|
| + test.listenOnce(serial.onReceiveError, function(result) {
|
| + serial.getInfo(connectionId, test.callbackPass(function(connectionInfo) {
|
| + disconnect();
|
| + test.assertTrue(connectionInfo.paused);
|
| + }));
|
| + test.assertEq(connectionId, result.connectionId);
|
| + test.assertEq('device_lost', result.error);
|
| + });
|
| + serial.onReceive.addListener(function() {
|
| + test.fail('unexpected onReceive event');
|
| + });
|
| + },
|
| +
|
| + // Test that receive timeouts trigger after the timeout time elapses and that
|
| + // changing the receive timeout does not affect a wait in progress.
|
| + function testReceiveTimeout() {
|
| + connect(function() {
|
| + test.listenOnce(serial.onReceiveError, function(result) {
|
| + test.assertEq(connectionId, result.connectionId);
|
| + test.assertEq('timeout', result.error);
|
| + test.assertEq(20, timeoutManager.currentTime);
|
| + serial.getInfo(connectionId, test.callbackPass(
|
| + function(connectionInfo) {
|
| + test.assertFalse(connectionInfo.paused);
|
| + disconnect();
|
| + }));
|
| + });
|
| + // Changing the timeout does not take effect until the current timeout
|
| + // expires or a receive completes.
|
| + serial.update(connectionId, {receiveTimeout: 10}, test.callbackPass(
|
| + timeoutManager.run.bind(timeoutManager, 1)));
|
| + }, {receiveTimeout: 20});
|
| + },
|
| +
|
| + // Test that receive timeouts trigger after the timeout time elapses and that
|
| + // disabling the receive timeout does not affect a wait in progress.
|
| + function testDisableReceiveTimeout() {
|
| + connect(function() {
|
| + test.listenOnce(serial.onReceiveError, function(result) {
|
| + test.assertEq(connectionId, result.connectionId);
|
| + test.assertEq('timeout', result.error);
|
| + test.assertEq(30, timeoutManager.currentTime);
|
| + serial.getInfo(connectionId, test.callbackPass(
|
| + function(connectionInfo) {
|
| + disconnect();
|
| + test.assertFalse(connectionInfo.paused);
|
| + }));
|
| + });
|
| + // Disabling the timeout does not take effect until the current timeout
|
| + // expires or a receive completes.
|
| + serial.update(connectionId, {receiveTimeout: 0}, test.callbackPass(
|
| + timeoutManager.run.bind(timeoutManager, 1)));
|
| + }, {receiveTimeout: 30});
|
| + },
|
| +
|
| + // Test that a receive error from the service is correctly dispatched. This
|
| + // test uses an IoHandler that only reports 'disconnected' receive errors.
|
| + function testReceiveErrorDisconnected() {
|
| + runReceiveErrorTest('disconnected');
|
| + },
|
| +
|
| + // Test that a receive error from the service is correctly dispatched. This
|
| + // test uses an IoHandler that only reports 'device_lost' receive errors.
|
| + function testReceiveErrorDeviceLost() {
|
| + runReceiveErrorTest('device_lost');
|
| + },
|
| +
|
| + // Test that a receive from error the service is correctly dispatched. This
|
| + // test uses an IoHandler that only reports 'system_error' receive errors.
|
| + function testReceiveErrorSystemError() {
|
| + runReceiveErrorTest('system_error');
|
| + },
|
| +
|
| + // Test that a send error from the service is correctly returned as the send
|
| + // result. This test uses an IoHandler that only reports 'disconnected' send
|
| + // errors.
|
| + function testSendErrorDisconnected() {
|
| + runSendErrorTest('disconnected');
|
| + },
|
| +
|
| + // Test that a send error from the service is correctly returned as the send
|
| + // result. This test uses an IoHandler that only reports 'system_error' send
|
| + // errors.
|
| + function testSendErrorSystemError() {
|
| + runSendErrorTest('system_error');
|
| + },
|
| +
|
| + // Test that disconnect returns the correct error for a connection ID that
|
| + // does not exist.
|
| function testDisconnectUnknownConnectionId() {
|
| serial.disconnect(-1, test.callbackFail('Serial connection not found.'));
|
| },
|
|
|
| + // Test that getInfo returns the correct error for a connection ID that does
|
| + // not exist.
|
| function testGetInfoUnknownConnectionId() {
|
| serial.getInfo(-1, test.callbackFail('Serial connection not found.'));
|
| },
|
|
|
| + // Test that update returns the correct error for a connection ID that does
|
| + // not exist.
|
| function testUpdateUnknownConnectionId() {
|
| serial.update(-1, {}, test.callbackFail('Serial connection not found.'));
|
| },
|
|
|
| + // Test that setControlSignals returns the correct error for a connection ID
|
| + // that does not exist.
|
| function testSetControlSignalsUnknownConnectionId() {
|
| serial.setControlSignals(-1, {}, test.callbackFail(
|
| 'Serial connection not found.'));
|
| },
|
|
|
| + // Test that getControlSignals returns the correct error for a connection ID
|
| + // that does not exist.
|
| function testGetControlSignalsUnknownConnectionId() {
|
| serial.getControlSignals(-1, test.callbackFail(
|
| 'Serial connection not found.'));
|
| },
|
|
|
| + // Test that flush returns the correct error for a connection ID that does not
|
| + // exist.
|
| function testFlushUnknownConnectionId() {
|
| serial.flush(-1, test.callbackFail('Serial connection not found.'));
|
| },
|
|
|
| + // Test that setPaused returns the correct error for a connection ID that does
|
| + // not exist.
|
| function testSetPausedUnknownConnectionId() {
|
| serial.setPaused(
|
| -1, true, test.callbackFail('Serial connection not found.'));
|
| serial.setPaused(
|
| -1, false, test.callbackFail('Serial connection not found.'));
|
| },
|
| +
|
| + // Test that send returns the correct error for a connection ID that does not
|
| + // exist.
|
| + function testSendUnknownConnectionId() {
|
| + var buffer = new ArrayBuffer(1);
|
| + serial.send(-1, buffer, test.callbackFail('Serial connection not found.'));
|
| + },
|
| ], test.runTests, exports);
|
|
|