| // META: script=/resources/test-only-api.js |
| // META: script=/serial/resources/common.js |
| // META: script=resources/automation.js |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| |
| assert_equals(port.writable, null); |
| |
| await port.open({baudRate: 9600}); |
| const writable = port.writable; |
| assert_true(writable instanceof WritableStream); |
| |
| await port.close(); |
| assert_equals(port.writable, null); |
| |
| const writer = writable.getWriter(); |
| const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); |
| await promise_rejects_dom(t, 'InvalidStateError', writer.write(data)); |
| }, 'open() and close() set and unset SerialPort.writable'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| |
| await port.open({baudRate: 9600}); |
| assert_true(port.writable instanceof WritableStream); |
| |
| const writer = port.writable.getWriter(); |
| await promise_rejects_js(t, TypeError, port.close()); |
| |
| writer.releaseLock(); |
| await port.close(); |
| assert_equals(port.writable, null); |
| }, 'Port cannot be closed while writable is locked'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| |
| await port.open({baudRate: 9600}); |
| assert_true(port.writable instanceof WritableStream); |
| |
| const writer = port.writable.getWriter(); |
| const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); |
| let writePromise = writer.write(data); |
| writer.releaseLock(); |
| |
| await fakePort.readable(); |
| let {value, done} = await fakePort.read(); |
| await writePromise; |
| compareArrays(value, data); |
| |
| await port.close(); |
| assert_equals(port.writable, null); |
| }, 'Can write a small amount of data'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| // Select a buffer size smaller than the amount of data transferred. |
| await port.open({baudRate: 9600, bufferSize: 64}); |
| |
| const writer = port.writable.getWriter(); |
| const data = new Uint8Array(1024); // Much larger than bufferSize above. |
| for (let i = 0; i < data.byteLength; ++i) |
| data[i] = i & 0xff; |
| writer.write(data); |
| writer.releaseLock(); |
| |
| await fakePort.readable(); |
| const value = await fakePort.readWithLength(data.byteLength); |
| compareArrays(data, value); |
| |
| await port.close(); |
| }, 'Can write a large amount of data'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| await port.open({baudRate: 9600}); |
| |
| const writable = port.writable; |
| assert_true(writable instanceof WritableStream); |
| let writer = writable.getWriter(); |
| |
| await fakePort.readable(); |
| fakePort.simulateSystemErrorOnWrite(); |
| const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); |
| await promise_rejects_dom(t, 'UnknownError', writer.write(data)); |
| |
| assert_true(port.writable instanceof WritableStream); |
| assert_not_equals(port.writable, writable); |
| |
| writer = port.writable.getWriter(); |
| let writePromise = writer.write(data); |
| writer.releaseLock(); |
| await fakePort.readable(); |
| let {value, done} = await fakePort.read(); |
| await writePromise; |
| compareArrays(value, data); |
| |
| await port.close(); |
| assert_equals(port.writable, null); |
| }, 'System error closes writable and replaces it with a new stream'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| await port.open({baudRate: 9600}); |
| |
| assert_true(port.writable instanceof WritableStream); |
| const writer = port.writable.getWriter(); |
| |
| await fakePort.readable(); |
| fakePort.simulateDisconnectOnWrite(); |
| const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); |
| await promise_rejects_dom(t, 'NetworkError', writer.write(data)); |
| assert_equals(port.writable, null); |
| |
| await port.close(); |
| }, 'Disconnect error closes writable and sets it to null'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| |
| await port.open({baudRate: 9600, bufferSize: 64}); |
| const originalWritable = port.writable; |
| assert_true(originalWritable instanceof WritableStream); |
| |
| let writer = originalWritable.getWriter(); |
| let data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); |
| // The buffer size is large enough to allow this write to complete without |
| // the data being read from the fake port. |
| await writer.write(data); |
| await writer.abort(); |
| |
| assert_true(port.writable instanceof WritableStream); |
| assert_true(port.writable !== originalWritable); |
| writer = port.writable.getWriter(); |
| data = new Uint8Array([9, 10, 11, 12, 13, 14, 15, 16]); |
| const writePromise = writer.write(data); |
| writer.releaseLock(); |
| |
| await fakePort.readable(); |
| const {value, done} = await fakePort.read(); |
| await writePromise; |
| compareArrays(value, data); |
| |
| await port.close(); |
| assert_equals(port.writable, null); |
| }, 'abort() discards the write buffer'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| // Select a buffer size smaller than the amount of data transferred. |
| await port.open({baudRate: 9600, bufferSize: 64}); |
| |
| const writer = port.writable.getWriter(); |
| const data = new Uint8Array(1024); // Much larger than bufferSize above. |
| for (let i = 0; i < data.byteLength; ++i) |
| data[i] = i & 0xff; |
| const writePromise = |
| promise_rejects_exactly(t, 'Aborting.', writer.write(data)); |
| |
| await writer.abort('Aborting.'); |
| await writePromise; |
| await port.close(); |
| assert_equals(port.writable, null); |
| }, 'abort() does not wait for the write buffer to be cleared'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| // Select a buffer size smaller than the amount of data transferred. |
| await port.open({baudRate: 9600, bufferSize: 64}); |
| |
| const writer = port.writable.getWriter(); |
| const data = new Uint8Array(1024); // Much larger than bufferSize above. |
| for (let i = 0; i < data.byteLength; ++i) |
| data[i] = i & 0xff; |
| const closed = (async () => { |
| await promise_rejects_exactly(t, 'Aborting.', writer.write(data)); |
| writer.releaseLock(); |
| await port.close(); |
| assert_equals(port.writable, null); |
| })(); |
| |
| await writer.abort('Aborting.'); |
| await closed; |
| }, 'Can close while aborting'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| // Select a buffer size smaller than the amount of data transferred. |
| await port.open({baudRate: 9600, bufferSize: 64}); |
| |
| const writer = port.writable.getWriter(); |
| const data = new Uint8Array(1024); // Much larger than bufferSize above. |
| for (let i = 0; i < data.byteLength; ++i) |
| data[i] = i & 0xff; |
| writer.write(data); |
| |
| let readComplete = false; |
| let writePromise = writer.close().then(() => { |
| assert_true(readComplete); |
| }); |
| |
| await fakePort.readable(); |
| let readPromise = fakePort.readWithLength(data.byteLength).then(result => { |
| readComplete = true; |
| return result; |
| }); |
| const value = await readPromise; |
| compareArrays(data, value); |
| await writePromise; |
| |
| await port.close(); |
| }, 'close() waits for the write buffer to be cleared'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| |
| await port.open({baudRate: 9600}); |
| assert_true(port.writable instanceof WritableStream); |
| |
| const encoder = new TextEncoderStream(); |
| const streamClosed = encoder.readable.pipeTo(port.writable); |
| const writer = encoder.writable.getWriter(); |
| const writePromise = writer.write('Hello world!'); |
| |
| await fakePort.readable(); |
| const {value, done} = await fakePort.read(); |
| await writePromise; |
| assert_equals('Hello world!', new TextDecoder().decode(value)); |
| await writer.close(); |
| await streamClosed; |
| |
| await port.close(); |
| assert_equals(port.writable, null); |
| }, 'Can pipe a stream to writable'); |
| |
| serial_test(async (t, fake) => { |
| const {port, fakePort} = await getFakeSerialPort(fake); |
| |
| await port.open({baudRate: 9600}); |
| assert_true(port.writable instanceof WritableStream); |
| |
| const transform = new TransformStream(); |
| const readable = transform.readable.pipeThrough(new TextEncoderStream()) |
| .pipeThrough(new TransformStream()) |
| .pipeThrough(new TransformStream()) |
| .pipeThrough(new TransformStream()); |
| const streamClosed = readable.pipeTo(port.writable); |
| const writer = transform.writable.getWriter(); |
| const writePromise = writer.write('Hello world!'); |
| |
| await fakePort.readable(); |
| const {value, done} = await fakePort.read(); |
| await writePromise; |
| assert_equals('Hello world!', new TextDecoder().decode(value)); |
| await writer.close(); |
| await streamClosed; |
| |
| await port.close(); |
| assert_equals(port.writable, null); |
| }, 'Stream closure is observable through a long chain of transformers'); |