1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * Unit tests for the JS serial service client.
8 * These test that configuration and data are correctly transmitted between the
9 * client and the service. They are launched by
10 * extensions/renderer/api/serial/serial_api_unittest.cc.
13 var test
= require('test').binding
;
14 var serial
= require('serial').binding
;
15 var unittestBindings
= require('test_environment_specific_bindings');
16 var utils
= require('utils');
18 var timeoutManager
= new unittestBindings
.TimeoutManager();
19 timeoutManager
.installGlobals();
23 var connectionId
= null;
25 var OPTIONS_VALUES
= [
26 {}, // SetPortOptions is called once during connection.
35 {ctsFlowControl
: false},
36 {ctsFlowControl
: true},
44 // Create a serial connection. That serial connection will be used by the other
45 // helper functions below.
46 function connect(options
) {
47 options
= options
|| {
48 name
: 'test connection',
49 bufferSize
: BUFFER_SIZE
,
50 receiveTimeout
: 12345,
54 return utils
.promise(serial
.connect
, 'device', options
).then(function(info
) {
55 connectionId
= info
.connectionId
;
60 // Serialize and deserialize all serial connections, preserving onData and
61 // onError event listeners.
62 function serializeRoundTrip() {
63 return requireAsync('serial_service').then(function(serialService
) {
64 function serializeConnections(connections
) {
65 var serializedConnections
= [];
66 for (var connection
of connections
.values()) {
67 serializedConnections
.push(serializeConnection(connection
));
69 return Promise
.all(serializedConnections
);
72 function serializeConnection(connection
) {
73 var onData
= connection
.onData
;
74 var onError
= connection
.onError
;
75 return connection
.serialize().then(function(serialization
) {
77 serialization
: serialization
,
84 function deserializeConnections(serializedConnections
) {
85 $Array
.forEach(serializedConnections
, function(serializedConnection
) {
86 var connection
= serialService
.Connection
.deserialize(
87 serializedConnection
.serialization
);
88 connection
.onData
= serializedConnection
.onData
;
89 connection
.onError
= serializedConnection
.onError
;
90 connection
.resumeReceives();
94 return serialService
.getConnections()
95 .then(serializeConnections
)
96 .then(deserializeConnections
);
100 // Returns a promise that will resolve to the connection info for the
103 return utils
.promise(serial
.getInfo
, connectionId
);
106 // Returns a function that checks that the values of keys contained within
107 // |expectedInfo| match the values of the same keys contained within |info|.
108 function checkInfo(expectedInfo
) {
109 return function(info
) {
110 for (var key
in expectedInfo
) {
111 test
.assertEq(expectedInfo
[key
], info
[key
]);
116 // Returns a function that will update the options of the serial connection with
117 // those contained within |values|.
118 function update(values
) {
120 return utils
.promise(serial
.update
, connectionId
, values
);
124 // Checks that the previous operation succeeded.
125 function expectSuccess(success
) {
126 test
.assertTrue(success
);
129 // Returns a function that checks that the send result matches |bytesSent| and
130 // |error|. If no error is expected, |error| may be omitted.
131 function expectSendResult(bytesSent
, error
) {
132 return function(sendInfo
) {
133 test
.assertEq(bytesSent
, sendInfo
.bytesSent
);
134 test
.assertEq(error
, sendInfo
.error
);
138 // Returns a function that checks that the current time is |expectedTime|.
139 function expectCurrentTime(expectedTime
) {
141 test
.assertEq(expectedTime
, timeoutManager
.currentTime
);
145 // Returns a promise that will resolve to the device control signals for the
146 // serial connection.
147 function getControlSignals() {
148 return utils
.promise(serial
.getControlSignals
, connectionId
);
151 // Returns a function that will set the control signals for the serial
152 // connection to |signals|.
153 function setControlSignals(signals
) {
155 return utils
.promise(serial
.setControlSignals
, connectionId
, signals
);
159 // Returns a function that will set the paused state of the serial connection to
161 function setPaused(paused
) {
163 return utils
.promise(serial
.setPaused
, connectionId
, paused
);
167 // Sets a function to be called once when data is received. Returns a promise
168 // that will resolve once the hook is installed.
169 function addReceiveHook(callback
) {
170 return requireAsync('serial_service').then(function(serialService
) {
172 var dataReceived
= serialService
.Connection
.prototype.onDataReceived_
;
173 serialService
.Connection
.prototype.onDataReceived_ = function() {
174 var result
= $Function
.apply(dataReceived
, this, arguments
);
183 // Sets a function to be called once when a receive error is received. Returns a
184 // promise that will resolve once the hook is installed.
185 function addReceiveErrorHook(callback
) {
186 return requireAsync('serial_service').then(function(serialService
) {
188 var receiveError
= serialService
.Connection
.prototype.onReceiveError_
;
189 serialService
.Connection
.prototype.onReceiveError_ = function() {
190 var result
= $Function
.apply(receiveError
, this, arguments
);
199 function listenOnce(targetEvent
) {
200 return new Promise(function(resolve
, reject
) {
201 targetEvent
.addListener(function(result
) {
207 function disconnect() {
208 return utils
.promise(serial
.disconnect
, connectionId
).then(function(success
) {
209 test
.assertTrue(success
);
214 function checkClientConnectionInfo(connectionInfo
) {
215 test
.assertTrue(connectionInfo
.persistent
);
216 test
.assertEq('test connection', connectionInfo
.name
);
217 test
.assertEq(12345, connectionInfo
.receiveTimeout
);
218 test
.assertEq(6789, connectionInfo
.sendTimeout
);
219 test
.assertEq(BUFFER_SIZE
, connectionInfo
.bufferSize
);
220 test
.assertFalse(connectionInfo
.paused
);
223 function checkServiceConnectionInfo(connectionInfo
) {
224 test
.assertEq(9600, connectionInfo
.bitrate
);
225 test
.assertEq('eight', connectionInfo
.dataBits
);
226 test
.assertEq('no', connectionInfo
.parityBit
);
227 test
.assertEq('one', connectionInfo
.stopBits
);
228 test
.assertFalse(connectionInfo
.ctsFlowControl
);
231 function checkConnectionInfo(connectionInfo
) {
232 checkClientConnectionInfo(connectionInfo
);
233 checkServiceConnectionInfo(connectionInfo
);
234 test
.assertEq(12, $Object
.keys(connectionInfo
).length
);
237 function sendData() {
239 var buffer
= new ArrayBuffer(data
.length
);
240 var byteBuffer
= new Int8Array(buffer
);
241 for (var i
= 0; i
< data
.length
; i
++) {
242 byteBuffer
[i
] = data
.charCodeAt(i
);
244 return utils
.promise(serial
.send
, connectionId
, buffer
);
247 function checkReceivedData(result
) {
249 test
.assertEq(connectionId
, result
.connectionId
);
250 test
.assertEq(data
.length
, result
.data
.byteLength
);
251 var resultByteBuffer
= new Int8Array(result
.data
);
252 for (var i
= 0; i
< data
.length
; i
++) {
253 test
.assertEq(data
.charCodeAt(i
), resultByteBuffer
[i
]);
257 function checkReceiveError(expectedError
) {
258 return function(result
) {
259 test
.assertEq(connectionId
, result
.connectionId
);
260 test
.assertEq(expectedError
, result
.error
);
264 function runReceiveErrorTest(expectedError
) {
265 var errorReceived
= listenOnce(serial
.onReceiveError
);
269 .then(checkReceiveError(expectedError
)),
272 .then(checkInfo({paused
: true})),
275 .then(test
.succeed
, test
.fail
);
278 function runSendErrorTest(expectedError
) {
281 .then(expectSendResult(0, expectedError
))
283 .then(test
.succeed
, test
.fail
);
286 unittestBindings
.exportTests([
287 // Test that getDevices correctly transforms the data returned by the
288 // SerialDeviceEnumerator.
289 function testGetDevices() {
290 utils
.promise(serial
.getDevices
).then(function(devices
) {
291 test
.assertEq(3, devices
.length
);
292 test
.assertEq(4, $Object
.keys(devices
[0]).length
);
293 test
.assertEq('device', devices
[0].path
);
294 test
.assertEq(1234, devices
[0].vendorId
);
295 test
.assertEq(5678, devices
[0].productId
);
296 test
.assertEq('foo', devices
[0].displayName
);
297 test
.assertEq(1, $Object
.keys(devices
[1]).length
);
298 test
.assertEq('another_device', devices
[1].path
);
299 test
.assertEq(1, $Object
.keys(devices
[2]).length
);
300 test
.assertEq('', devices
[2].path
);
301 }).then(test
.succeed
, test
.fail
);
304 // Test that the correct error message is returned when an error occurs in
305 // connecting to the port. This test uses an IoHandler that fails to connect.
306 function testConnectFail() {
307 serial
.connect('device',
308 test
.callbackFail('Failed to connect to the port.'));
311 // Test that the correct error message is returned when an error occurs in
312 // calling getPortInfo after connecting to the port. This test uses an
313 // IoHandler that fails on calls to GetPortInfo.
314 function testGetInfoFailOnConnect() {
315 serial
.connect('device',
316 test
.callbackFail('Failed to connect to the port.'));
319 // Test that the correct error message is returned when an invalid bit-rate
320 // value is passed to connect.
321 function testConnectInvalidBitrate() {
322 serial
.connect('device', {bitrate
: -1}, test
.callbackFail(
323 'Failed to connect to the port.'));
326 // Test that a successful connect returns the expected connection info.
327 function testConnect() {
329 .then(checkConnectionInfo
)
331 .then(test
.succeed
, test
.fail
);
334 // Test that a connection created with no options has the correct default
336 function testConnectDefaultOptions() {
337 connect({}).then(function(connectionInfo
) {
338 test
.assertEq(9600, connectionInfo
.bitrate
);
339 test
.assertEq('eight', connectionInfo
.dataBits
);
340 test
.assertEq('no', connectionInfo
.parityBit
);
341 test
.assertEq('one', connectionInfo
.stopBits
);
342 test
.assertFalse(connectionInfo
.ctsFlowControl
);
343 test
.assertFalse(connectionInfo
.persistent
);
344 test
.assertEq('', connectionInfo
.name
);
345 test
.assertEq(0, connectionInfo
.receiveTimeout
);
346 test
.assertEq(0, connectionInfo
.sendTimeout
);
347 test
.assertEq(4096, connectionInfo
.bufferSize
);
350 .then(test
.succeed
, test
.fail
);
353 // Test that a getInfo call correctly converts the service-side info from the
354 // Mojo format and returns both it and the client-side configuration.
355 function testGetInfo() {
358 .then(checkConnectionInfo
)
360 .then(test
.succeed
, test
.fail
);
363 // Test that a getInfo call returns the correct info after serialization.
364 function testGetInfoAfterSerialization() {
366 .then(serializeRoundTrip
)
368 .then(checkConnectionInfo
)
370 .then(test
.succeed
, test
.fail
);
373 // Test that only client-side options are returned when the service fails a
374 // getInfo call. This test uses an IoHandler that fails GetPortInfo calls
375 // after the initial call during connect.
376 function testGetInfoFailToGetPortInfo() {
377 var info
= connect().then(getInfo
);
379 info
.then(function(connectionInfo
) {
380 test
.assertFalse('bitrate' in connectionInfo
);
381 test
.assertFalse('dataBits' in connectionInfo
);
382 test
.assertFalse('parityBit' in connectionInfo
);
383 test
.assertFalse('stopBit' in connectionInfo
);
384 test
.assertFalse('ctsFlowControl' in connectionInfo
);
386 info
.then(checkClientConnectionInfo
),
389 .then(test
.succeed
, test
.fail
);
392 // Test that getConnections returns an array containing the open connection.
393 function testGetConnections() {
394 connect().then(function() {
395 return utils
.promise(serial
.getConnections
);
396 }).then(function(connections
) {
397 test
.assertEq(1, connections
.length
);
398 checkConnectionInfo(connections
[0]);
401 .then(test
.succeed
, test
.fail
);
404 // Test that getControlSignals correctly converts the Mojo format result. This
405 // test uses an IoHandler that returns values matching the pattern being
407 function testGetControlSignals() {
408 function checkControlSignals(expectedBitfield
) {
409 return function(signals
) {
410 test
.assertEq(!!(expectedBitfield
& 1), signals
.dcd
);
411 test
.assertEq(!!(expectedBitfield
& 2), signals
.cts
);
412 test
.assertEq(!!(expectedBitfield
& 4), signals
.ri
);
413 test
.assertEq(!!(expectedBitfield
& 8), signals
.dsr
);
416 var promiseChain
= connect();
417 for (var i
= 0; i
< 16; i
++) {
418 promiseChain
= promiseChain
419 .then(getControlSignals
)
420 .then(checkControlSignals(i
));
424 .then(test
.succeed
, test
.fail
);
427 // Test that setControlSignals correctly converts to the Mojo format result.
428 // This test uses an IoHandler that returns values following the same table of
429 // values as |signalsValues|.
430 function testSetControlSignals() {
431 var signalsValues
= [
436 {dtr
: false, rts
: false},
437 {dtr
: true, rts
: false},
439 {dtr
: false, rts
: true},
440 {dtr
: true, rts
: true},
442 var promiseChain
= connect();
443 for (var i
= 0; i
< signalsValues
.length
; i
++) {
444 promiseChain
= promiseChain
.then(setControlSignals(signalsValues
[i
]));
448 .then(test
.succeed
, test
.fail
);
451 // Test that update correctly passes values to the service only for
452 // service-side options and that all update calls are reflected by the result
453 // of getInfo calls. This test uses an IoHandler that expects corresponding
454 // ConfigurePort calls.
455 function testUpdate() {
456 var promiseChain
= connect()
458 .then(checkInfo(OPTIONS_VALUES
[i
]));
459 for (var i
= 1; i
< OPTIONS_VALUES
.length
; i
++) {
460 promiseChain
= promiseChain
461 .then(update(OPTIONS_VALUES
[i
]))
464 .then(checkInfo(OPTIONS_VALUES
[i
]));
468 .then(test
.succeed
, test
.fail
);
471 // Test that options set by update persist after serialization.
472 function testUpdateAcrossSerialization() {
473 var promiseChain
= connect()
474 .then(serializeRoundTrip
)
476 .then(checkInfo(OPTIONS_VALUES
[i
]));
477 for (var i
= 1; i
< OPTIONS_VALUES
.length
; i
++) {
478 promiseChain
= promiseChain
479 .then(update(OPTIONS_VALUES
[i
]))
481 .then(serializeRoundTrip
)
483 .then(checkInfo(OPTIONS_VALUES
[i
]));
487 .then(test
.succeed
, test
.fail
);
490 // Test that passing an invalid bit-rate reslts in an error.
491 function testUpdateInvalidBitrate() {
493 .then(update({bitrate
: -1}))
494 .then(function(success
) {
495 test
.assertFalse(success
);
498 .then(test
.succeed
, test
.fail
);
501 // Test flush. This test uses an IoHandler that counts the number of flush
503 function testFlush() {
504 connect().then(function() {
505 return utils
.promise(serial
.flush
, connectionId
);
509 .then(test
.succeed
, test
.fail
);
512 // Test that setPaused values are reflected by the results returned by getInfo
514 function testSetPaused() {
516 .then(setPaused(true))
518 .then(checkInfo({paused
: true}))
519 .then(setPaused(false))
521 .then(checkInfo({paused
: false}))
523 .then(test
.succeed
, test
.fail
);
526 // Test that a send and a receive correctly echoes data. This uses an
527 // IoHandler that echoes data sent to it.
528 function testEcho() {
532 .then(expectSendResult(4)),
533 listenOnce(serial
.onReceive
)
534 .then(checkReceivedData
),
537 .then(test
.succeed
, test
.fail
);
540 // Test that a send while another send is in progress returns a pending error.
541 function testSendDuringExistingSend() {
542 var connected
= connect();
546 .then(expectSendResult(4)),
549 .then(expectSendResult(0, 'pending')),
552 .then(test
.succeed
, test
.fail
);
555 // Test that a second send after the first finishes is successful. This uses
556 // an IoHandler that echoes data sent to it.
557 function testSendAfterSuccessfulSend() {
560 .then(expectSendResult(4))
562 .then(expectSendResult(4))
564 .then(test
.succeed
, test
.fail
);
567 // Test that a second send after the first fails is successful. This uses an
568 // IoHandler that returns system_error for only the first send.
569 function testSendPartialSuccessWithError() {
572 .then(expectSendResult(2, 'system_error'))
574 .then(expectSendResult(4))
576 .then(test
.succeed
, test
.fail
);
579 // Test that a send and a receive correctly echoes data after serialization.
580 function testEchoAfterSerialization() {
583 .then(serializeRoundTrip
)
585 .then(expectSendResult(4)),
586 listenOnce(serial
.onReceive
).then(checkReceivedData
)
589 .then(test
.succeed
, test
.fail
);
592 // Test that a timed-out send returns a timeout error and that changing the
593 // send timeout during a send does not affect its timeout. This test uses an
594 // IoHandle that never completes sends.
595 function testSendTimeout() {
596 var connected
= connect({sendTimeout
: 5});
597 var sent
= connected
.then(sendData
);
599 sent
.then(expectSendResult(0, 'timeout')),
600 sent
.then(expectCurrentTime(5)),
601 connected
.then(update({sendTimeout
: 10}))
603 .then(timeoutManager
.run
.bind(timeoutManager
, 1)),
606 .then(test
.succeed
, test
.fail
);
609 // Test that send timeouts still function correctly after a serialization
611 function testSendTimeoutAfterSerialization() {
612 var connected
= connect({sendTimeout
: 5}).then(serializeRoundTrip
);
613 var sent
= connected
.then(sendData
);
615 sent
.then(expectSendResult(0, 'timeout')),
616 sent
.then(expectCurrentTime(5)),
617 connected
.then(update({sendTimeout
: 10}))
619 .then(timeoutManager
.run
.bind(timeoutManager
, 1)),
622 .then(test
.succeed
, test
.fail
);
625 // Test that a timed-out send returns a timeout error and that disabling the
626 // send timeout during a send does not affect its timeout. This test uses an
627 // IoHandle that never completes sends.
628 function testDisableSendTimeout() {
629 var connected
= connect({sendTimeout
: 5});
630 var sent
= connected
.then(sendData
);
632 sent
.then(expectSendResult(0, 'timeout')),
633 sent
.then(expectCurrentTime(5)),
634 connected
.then(update({sendTimeout
: 0}))
636 .then(timeoutManager
.run
.bind(timeoutManager
, 1)),
639 .then(test
.succeed
, test
.fail
);
642 // Test that data received while the connection is paused is queued and
643 // dispatched once the connection is unpaused.
644 function testPausedReceive() {
646 // Wait until the receive hook is installed, then start the test.
647 addReceiveHook(function() {
648 // Unpause the connection after the connection has queued the received
649 // data to ensure the queued data is dispatched when the connection is
652 utils
.promise(serial
.setPaused
, connectionId
, false),
653 // Check that setPaused(false) is idempotent.
654 utils
.promise(serial
.setPaused
, connectionId
, false),
659 // Check that setPaused(true) is idempotent.
661 utils
.promise(serial
.setPaused
, connectionId
, true),
662 utils
.promise(serial
.setPaused
, connectionId
, true),
665 listenOnce(serial
.onReceive
).then(checkReceivedData
),
668 .then(test
.succeed
, test
.fail
);
671 // Test that a receive error received while the connection is paused is queued
672 // and dispatched once the connection is unpaused.
673 function testPausedReceiveError() {
675 // Wait until the receive hook is installed, then start the test.
676 addReceiveErrorHook(function() {
677 // Unpause the connection after the connection has queued the received
678 // data to ensure the queued data is dispatched when the connection is
680 utils
.promise(serial
.setPaused
, connectionId
, false).catch(test
.fail
);
683 .then(setPaused(true)),
684 listenOnce(serial
.onReceiveError
)
685 .then(checkReceiveError('device_lost')),
688 .then(test
.succeed
, test
.fail
);
689 serial
.onReceive
.addListener(function() {
690 test
.fail('unexpected onReceive event');
694 // Test that receive timeouts trigger after the timeout time elapses and that
695 // changing the receive timeout does not affect a wait in progress.
696 function testReceiveTimeout() {
697 var errorReceived
= listenOnce(serial
.onReceiveError
);
699 errorReceived
.then(checkReceiveError('timeout')),
700 errorReceived
.then(expectCurrentTime(20)),
703 .then(checkInfo({paused
: false})),
704 connect({receiveTimeout
: 20})
705 // Changing the timeout does not take effect until the current
706 // timeout expires or a receive completes.
707 .then(update({receiveTimeout
: 10}))
709 .then(timeoutManager
.run
.bind(timeoutManager
, 1)),
712 .then(test
.succeed
, test
.fail
);
715 // Test that receive timeouts still function correctly after a serialization
717 function testReceiveTimeoutAfterSerialization() {
718 var errorReceived
= listenOnce(serial
.onReceiveError
);
720 errorReceived
.then(checkReceiveError('timeout')),
721 errorReceived
.then(expectCurrentTime(20)),
724 .then(checkInfo({paused
: false})),
725 connect({receiveTimeout
: 20})
726 .then(serializeRoundTrip
)
727 .then(timeoutManager
.run
.bind(timeoutManager
, 1)),
730 .then(test
.succeed
, test
.fail
);
733 // Test that receive timeouts trigger after the timeout time elapses and that
734 // disabling the receive timeout does not affect a wait in progress.
735 function testDisableReceiveTimeout() {
736 var errorReceived
= listenOnce(serial
.onReceiveError
);
738 errorReceived
.then(checkReceiveError('timeout')),
739 errorReceived
.then(expectCurrentTime(20)),
742 .then(checkInfo({paused
: false})),
743 connect({receiveTimeout
: 20})
744 // Disabling the timeout does not take effect until the current
745 // timeout expires or a receive completes.
746 .then(update({receiveTimeout
: 0}))
748 .then(timeoutManager
.run
.bind(timeoutManager
, 1)),
751 .then(test
.succeed
, test
.fail
);
754 // Test that a receive error from the service is correctly dispatched. This
755 // test uses an IoHandler that only reports 'disconnected' receive errors.
756 function testReceiveErrorDisconnected() {
757 runReceiveErrorTest('disconnected');
760 // Test that a receive error from the service is correctly dispatched. This
761 // test uses an IoHandler that only reports 'device_lost' receive errors.
762 function testReceiveErrorDeviceLost() {
763 runReceiveErrorTest('device_lost');
766 // Test that a receive from error the service is correctly dispatched. This
767 // test uses an IoHandler that only reports 'system_error' receive errors.
768 function testReceiveErrorSystemError() {
769 runReceiveErrorTest('system_error');
772 // Test that a send error from the service is correctly returned as the send
773 // result. This test uses an IoHandler that only reports 'disconnected' send
775 function testSendErrorDisconnected() {
776 runSendErrorTest('disconnected');
779 // Test that a send error from the service is correctly returned as the send
780 // result. This test uses an IoHandler that only reports 'system_error' send
782 function testSendErrorSystemError() {
783 runSendErrorTest('system_error');
786 // Test that disconnect returns the correct error for a connection ID that
788 function testDisconnectUnknownConnectionId() {
789 serial
.disconnect(-1, test
.callbackFail('Serial connection not found.'));
792 // Test that getInfo returns the correct error for a connection ID that does
794 function testGetInfoUnknownConnectionId() {
795 serial
.getInfo(-1, test
.callbackFail('Serial connection not found.'));
798 // Test that update returns the correct error for a connection ID that does
800 function testUpdateUnknownConnectionId() {
801 serial
.update(-1, {}, test
.callbackFail('Serial connection not found.'));
804 // Test that setControlSignals returns the correct error for a connection ID
805 // that does not exist.
806 function testSetControlSignalsUnknownConnectionId() {
807 serial
.setControlSignals(-1, {}, test
.callbackFail(
808 'Serial connection not found.'));
811 // Test that getControlSignals returns the correct error for a connection ID
812 // that does not exist.
813 function testGetControlSignalsUnknownConnectionId() {
814 serial
.getControlSignals(-1, test
.callbackFail(
815 'Serial connection not found.'));
818 // Test that flush returns the correct error for a connection ID that does not
820 function testFlushUnknownConnectionId() {
821 serial
.flush(-1, test
.callbackFail('Serial connection not found.'));
824 // Test that setPaused returns the correct error for a connection ID that does
826 function testSetPausedUnknownConnectionId() {
828 -1, true, test
.callbackFail('Serial connection not found.'));
830 -1, false, test
.callbackFail('Serial connection not found.'));
833 // Test that send returns the correct error for a connection ID that does not
835 function testSendUnknownConnectionId() {
836 var buffer
= new ArrayBuffer(1);
837 serial
.send(-1, buffer
, test
.callbackFail('Serial connection not found.'));
840 function testSendAndStash() {
842 .then(setPaused(true))
844 .then(expectSendResult(4))
845 .then(test
.succeed
, test
.fail
);
848 function testRestoreAndReceive() {
851 utils
.promise(serial
.setPaused
, connectionId
, false),
852 listenOnce(serial
.onReceive
).then(checkReceivedData
),
855 .then(test
.succeed
, test
.fail
);
858 function testRestoreAndReceiveErrorSetUp() {
859 connect().then(test
.succeed
, test
.fail
);
862 function testRestoreAndReceiveError() {
865 utils
.promise(serial
.setPaused
, connectionId
, false),
866 listenOnce(serial
.onReceiveError
)
867 .then(checkReceiveError('device_lost')),
870 .then(test
.succeed
, test
.fail
);
873 function testStashNoConnections() {
874 connect({persistent
: false}).then(test
.succeed
, test
.fail
);
877 function testRestoreNoConnections() {
879 .then(function(connectionInfo
) {
880 test
.assertEq(0, connectionInfo
.connectionId
);
881 return connectionInfo
;
883 .then(checkConnectionInfo
)
885 .then(test
.succeed
, test
.fail
);
888 ], test
.runTests
, exports
);