summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/streams/writable-streams/start.any.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/streams/writable-streams/start.any.js')
-rw-r--r--testing/web-platform/tests/streams/writable-streams/start.any.js163
1 files changed, 163 insertions, 0 deletions
diff --git a/testing/web-platform/tests/streams/writable-streams/start.any.js b/testing/web-platform/tests/streams/writable-streams/start.any.js
new file mode 100644
index 0000000000..82d869430d
--- /dev/null
+++ b/testing/web-platform/tests/streams/writable-streams/start.any.js
@@ -0,0 +1,163 @@
+// META: global=window,worker
+// META: script=../resources/test-utils.js
+// META: script=../resources/recording-streams.js
+'use strict';
+
+const error1 = { name: 'error1' };
+
+promise_test(() => {
+ let resolveStartPromise;
+ const ws = recordingWritableStream({
+ start() {
+ return new Promise(resolve => {
+ resolveStartPromise = resolve;
+ });
+ }
+ });
+
+ const writer = ws.getWriter();
+
+ assert_equals(writer.desiredSize, 1, 'desiredSize should be 1');
+ writer.write('a');
+ assert_equals(writer.desiredSize, 0, 'desiredSize should be 0 after writer.write()');
+
+ // Wait and verify that write isn't called.
+ return flushAsyncEvents()
+ .then(() => {
+ assert_array_equals(ws.events, [], 'write should not be called until start promise resolves');
+ resolveStartPromise();
+ return writer.ready;
+ })
+ .then(() => assert_array_equals(ws.events, ['write', 'a'],
+ 'write should not be called until start promise resolves'));
+}, 'underlying sink\'s write should not be called until start finishes');
+
+promise_test(() => {
+ let resolveStartPromise;
+ const ws = recordingWritableStream({
+ start() {
+ return new Promise(resolve => {
+ resolveStartPromise = resolve;
+ });
+ }
+ });
+
+ const writer = ws.getWriter();
+
+ writer.close();
+ assert_equals(writer.desiredSize, 1, 'desiredSize should be 1');
+
+ // Wait and verify that write isn't called.
+ return flushAsyncEvents().then(() => {
+ assert_array_equals(ws.events, [], 'close should not be called until start promise resolves');
+ resolveStartPromise();
+ return writer.closed;
+ });
+}, 'underlying sink\'s close should not be called until start finishes');
+
+test(() => {
+ const passedError = new Error('horrible things');
+
+ let writeCalled = false;
+ let closeCalled = false;
+ assert_throws_exactly(passedError, () => {
+ // recordingWritableStream cannot be used here because the exception in the
+ // constructor prevents assigning the object to a variable.
+ new WritableStream({
+ start() {
+ throw passedError;
+ },
+ write() {
+ writeCalled = true;
+ },
+ close() {
+ closeCalled = true;
+ }
+ });
+ }, 'constructor should throw passedError');
+ assert_false(writeCalled, 'write should not be called');
+ assert_false(closeCalled, 'close should not be called');
+}, 'underlying sink\'s write or close should not be called if start throws');
+
+promise_test(() => {
+ const ws = recordingWritableStream({
+ start() {
+ return Promise.reject();
+ }
+ });
+
+ // Wait and verify that write or close aren't called.
+ return flushAsyncEvents()
+ .then(() => assert_array_equals(ws.events, [], 'write and close should not be called'));
+}, 'underlying sink\'s write or close should not be invoked if the promise returned by start is rejected');
+
+promise_test(t => {
+ const ws = new WritableStream({
+ start() {
+ return {
+ then(onFulfilled, onRejected) { onRejected(error1); }
+ };
+ }
+ });
+ return promise_rejects_exactly(t, error1, ws.getWriter().closed, 'closed promise should be rejected');
+}, 'returning a thenable from start() should work');
+
+promise_test(t => {
+ const ws = recordingWritableStream({
+ start(controller) {
+ controller.error(error1);
+ }
+ });
+ return promise_rejects_exactly(t, error1, ws.getWriter().write('a'), 'write() should reject with the error')
+ .then(() => {
+ assert_array_equals(ws.events, [], 'sink write() should not have been called');
+ });
+}, 'controller.error() during start should cause writes to fail');
+
+promise_test(t => {
+ let controller;
+ let resolveStart;
+ const ws = recordingWritableStream({
+ start(c) {
+ controller = c;
+ return new Promise(resolve => {
+ resolveStart = resolve;
+ });
+ }
+ });
+ const writer = ws.getWriter();
+ const writePromise = writer.write('a');
+ const closePromise = writer.close();
+ controller.error(error1);
+ resolveStart();
+ return Promise.all([
+ promise_rejects_exactly(t, error1, writePromise, 'write() should fail'),
+ promise_rejects_exactly(t, error1, closePromise, 'close() should fail')
+ ]).then(() => {
+ assert_array_equals(ws.events, [], 'sink write() and close() should not have been called');
+ });
+}, 'controller.error() during async start should cause existing writes to fail');
+
+promise_test(t => {
+ const events = [];
+ const promises = [];
+ function catchAndRecord(promise, name) {
+ promises.push(promise.then(t.unreached_func(`promise ${name} should not resolve`),
+ () => {
+ events.push(name);
+ }));
+ }
+ const ws = new WritableStream({
+ start() {
+ return Promise.reject();
+ }
+ }, { highWaterMark: 0 });
+ const writer = ws.getWriter();
+ catchAndRecord(writer.ready, 'ready');
+ catchAndRecord(writer.closed, 'closed');
+ catchAndRecord(writer.write(), 'write');
+ return Promise.all(promises)
+ .then(() => {
+ assert_array_equals(events, ['ready', 'write', 'closed'], 'promises should reject in standard order');
+ });
+}, 'when start() rejects, writer promises should reject in standard order');