Bug 1444940 [wpt PR 9926] - Streams: Modify tests to expect abort reason passthrough, a=testonly
authorAdam Rice <ricea@chromium.org>
Mon, 26 Mar 2018 15:37:06 +0000
changeset 411279 7ec8a0f2b4173c7bbd730cbfed9dae6ae1c8eed6
parent 411278 1e929cbff5520a393a1c61525e11eb5623525d12
child 411280 c9bb88bd5251e143900648b23e96416686744f31
push id33749
push usercsabou@mozilla.com
push dateMon, 02 Apr 2018 10:18:51 +0000
treeherdermozilla-central@c44f60c43432 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1444940
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1444940 [wpt PR 9926] - Streams: Modify tests to expect abort reason passthrough, a=testonly Automatic update from web-platform-testsStreams: Modify tests to expect abort reason passthrough (#9926) This tests the changes in https://github.com/whatwg/streams/pull/903. Replace expectations that a TypeError will be stored after abort() is called with with expectations that the reason passed to abort() will be stored instead. Also add a test of the stored error on the readable side of a TransformStream after abort() has been called on the writable size. This was not explicitly tested. Also fix a bug in the general.js test: it didn't wrap a call to assert_unreached properly, so a failure would have shown up as an unhandled rejection rather than being reported properly. wpt-commits: 81468a0b88d771af9dfa0feb5de99367e32d4b6e wpt-pr: 9926 wpt-commits: 81468a0b88d771af9dfa0feb5de99367e32d4b6e wpt-pr: 9926
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/streams/piping/error-propagation-backward.js
testing/web-platform/tests/streams/piping/multiple-propagation.js
testing/web-platform/tests/streams/transform-streams/errors.js
testing/web-platform/tests/streams/transform-streams/reentrant-strategies.js
testing/web-platform/tests/streams/writable-streams/aborting.js
testing/web-platform/tests/streams/writable-streams/bad-underlying-sinks.js
testing/web-platform/tests/streams/writable-streams/close.js
testing/web-platform/tests/streams/writable-streams/general.js
testing/web-platform/tests/streams/writable-streams/reentrant-strategy.js
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -593306,17 +593306,17 @@
    "2f7ad2bf616e612f8cae9c61264d1ea012be2561",
    "testharness"
   ],
   "streams/piping/error-propagation-backward.html": [
    "3fa70d5f0b864846b699ffd94b10a19a331fa65c",
    "testharness"
   ],
   "streams/piping/error-propagation-backward.js": [
-   "e7f1bdd524056017264ba1f0d2f569c5a5bbece5",
+   "a9ed4065bf5512937a60f85e18ee0b4312994506",
    "support"
   ],
   "streams/piping/error-propagation-backward.serviceworker.https.html": [
    "3502f6514992dab5662a5088c518d3a775863770",
    "testharness"
   ],
   "streams/piping/error-propagation-backward.sharedworker.html": [
    "464dbfc87804e207057de70b2dcbb0aacf03b92e",
@@ -593386,17 +593386,17 @@
    "ef3d8a0ab031c3e25c6fcd083e7361a449ed671d",
    "testharness"
   ],
   "streams/piping/multiple-propagation.html": [
    "a0c329fc93126deca9a1fa354ae536fdbe20d5a7",
    "testharness"
   ],
   "streams/piping/multiple-propagation.js": [
-   "8d00cd13d84d421a297bff499511d96f7b72c98c",
+   "a4f9df6a5da581c14aae0d489bc73972873f2b7d",
    "support"
   ],
   "streams/piping/multiple-propagation.serviceworker.https.html": [
    "b1ec8a36de6b683fcfc9b3af35f7544d4806bdb6",
    "testharness"
   ],
   "streams/piping/multiple-propagation.sharedworker.html": [
    "a2aaf43f0d2eb831bd9f8e379fbf0076eee76633",
@@ -593842,17 +593842,17 @@
    "ea56c89e303ed85d5f6acd423600b1d4ad73ac13",
    "testharness"
   ],
   "streams/transform-streams/errors.html": [
    "bb42fe4b43455e530f8fbb02d86f69fecdd994ef",
    "testharness"
   ],
   "streams/transform-streams/errors.js": [
-   "5dcd3245e4518ff59d1297e900118cf04c6cd2d8",
+   "607bf12f225025a006e3b898776553fa23d38597",
    "support"
   ],
   "streams/transform-streams/errors.serviceworker.https.html": [
    "85dc0c4639761359a19c1eed51692688c0a5fb7c",
    "testharness"
   ],
   "streams/transform-streams/errors.sharedworker.html": [
    "479366dd2a194281aba6138aa10fd2bc788ea44c",
@@ -593962,17 +593962,17 @@
    "6f9350ce1caf4fa9e6239693ec91b2249c2adab5",
    "testharness"
   ],
   "streams/transform-streams/reentrant-strategies.html": [
    "3ccd828e098956d0697c1f0e8809aa67d7945f2b",
    "testharness"
   ],
   "streams/transform-streams/reentrant-strategies.js": [
-   "caf6c2d53b211fdfd001858a8656dc0f0f92ce74",
+   "1ddadc53f6b69bda7cf015ca44e6c78f74f11111",
    "support"
   ],
   "streams/transform-streams/reentrant-strategies.serviceworker.https.html": [
    "f3000f522b6e1b7f1db839b85ff71aed36c29b8d",
    "testharness"
   ],
   "streams/transform-streams/reentrant-strategies.sharedworker.html": [
    "cdbd3f2cfc307cf007eabfb324dc107d5baa86a0",
@@ -594022,17 +594022,17 @@
    "89cfc3ba5cfbb426b6ac60c32aa5cfe9dd0ad8b4",
    "testharness"
   ],
   "streams/writable-streams/aborting.html": [
    "9cacb1967fee9eab8619b949101e28ffde922ed9",
    "testharness"
   ],
   "streams/writable-streams/aborting.js": [
-   "d5c1da21925490cb9ea134eac5435a03e84fe4f7",
+   "f10c4d9ffb59d4480fd069a9ea70ec41f5b71754",
    "support"
   ],
   "streams/writable-streams/aborting.serviceworker.https.html": [
    "b69530ebf51ccaf781ff78172be2f4607ee22c86",
    "testharness"
   ],
   "streams/writable-streams/aborting.sharedworker.html": [
    "9e792fad19cd10a96440478cb7e0486f41b70bf4",
@@ -594062,17 +594062,17 @@
    "1b17838179df4a18b4a2d06a1d977cbb26d3b4b9",
    "testharness"
   ],
   "streams/writable-streams/bad-underlying-sinks.html": [
    "416a7768757c202cae70acf4ac22073f9d066336",
    "testharness"
   ],
   "streams/writable-streams/bad-underlying-sinks.js": [
-   "f09d495d577ff9904adbcfc4746acfd5f70860ff",
+   "9a9f0b9eb7a93e9809c549e983c4052648157592",
    "support"
   ],
   "streams/writable-streams/bad-underlying-sinks.serviceworker.https.html": [
    "fbddba953d4b50ed43b1e03cab6eb8931db71ffe",
    "testharness"
   ],
   "streams/writable-streams/bad-underlying-sinks.sharedworker.html": [
    "b20a95798586eb4c1d9ba9d2413038fa37316c5e",
@@ -594122,17 +594122,17 @@
    "cccf37e3bcc4be858fb41be465c38e7785db4508",
    "testharness"
   ],
   "streams/writable-streams/close.html": [
    "70e009ba3ef83ab35b0f64ded234ecbe0409a1fe",
    "testharness"
   ],
   "streams/writable-streams/close.js": [
-   "a0f0183652427bdcd049eac90eb52d1ba5e09110",
+   "45a448b31a40388f277ecf064339f6858f032cc1",
    "support"
   ],
   "streams/writable-streams/close.serviceworker.https.html": [
    "5461a766e8047c6d50b7943d99f8ebb4c140a547",
    "testharness"
   ],
   "streams/writable-streams/close.sharedworker.html": [
    "b2aeb127d5ae7087b42e3fc08faaa113c84e6fd8",
@@ -594222,17 +594222,17 @@
    "8583d80450b090c16ed0795170340d040449bbc1",
    "testharness"
   ],
   "streams/writable-streams/general.html": [
    "e48bbd4dc77262037901c0f0da486ca53a84c939",
    "testharness"
   ],
   "streams/writable-streams/general.js": [
-   "4f07b059c3b2d90ca0c08ffe014e3e77ade70be0",
+   "af1848e49d119ba4e57b8354052e161ac8e80632",
    "support"
   ],
   "streams/writable-streams/general.serviceworker.https.html": [
    "1792d6c45a5687777291a4dab031a954aa053752",
    "testharness"
   ],
   "streams/writable-streams/general.sharedworker.html": [
    "44f9ceaa3bfc9d8b92885997d322486bd0f237a6",
@@ -594262,17 +594262,17 @@
    "5d9e5a6b69fbe79183ac6e0d2c8559f13be6e386",
    "testharness"
   ],
   "streams/writable-streams/reentrant-strategy.html": [
    "c05bf8306c3fe8e97b936a26c6de1649e9d0d243",
    "testharness"
   ],
   "streams/writable-streams/reentrant-strategy.js": [
-   "e0fea3678e9441483cda043bff02595836a20de4",
+   "87a02a0d0b66c3fe571ca106379da254a4e2869f",
    "support"
   ],
   "streams/writable-streams/reentrant-strategy.serviceworker.https.html": [
    "663075ee687ea54010f76d0e37191e46f37b9a49",
    "testharness"
   ],
   "streams/writable-streams/reentrant-strategy.sharedworker.html": [
    "5dabe1367481c57c58fe208ba66d8c13d4e2b796",
--- a/testing/web-platform/tests/streams/piping/error-propagation-backward.js
+++ b/testing/web-platform/tests/streams/piping/error-propagation-backward.js
@@ -543,17 +543,17 @@ promise_test(() => {
 
   const ws = recordingWritableStream();
 
   ws.abort(error1);
 
   return rs.pipeTo(ws).then(
     () => assert_unreached('the promise must not fulfill'),
     err => {
-      assert_equals(err.name, 'TypeError', 'the promise must reject with a TypeError (_not_ with error1)');
+      assert_equals(err, error1, 'the promise must reject with error1');
 
       assert_array_equals(rs.eventsWithoutPulls, ['cancel', err]);
       assert_array_equals(ws.events, ['abort', error1]);
     }
   );
 
 }, 'Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled ' +
    'cancel promise');
@@ -570,17 +570,17 @@ promise_test(t => {
 
   ws.abort(error1);
 
   return promise_rejects(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error')
     .then(() => {
       return ws.getWriter().closed.then(
         () => assert_unreached('the promise must not fulfill'),
         err => {
-          assert_equals(err.name, 'TypeError', 'the promise must reject with a TypeError (_not_ with error1)');
+          assert_equals(err, error1, 'the promise must reject with error1');
 
           assert_array_equals(rs.eventsWithoutPulls, ['cancel', err]);
           assert_array_equals(ws.events, ['abort', error1]);
         }
       );
     });
 
 }, 'Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected ' +
@@ -589,17 +589,17 @@ promise_test(t => {
 promise_test(t => {
 
   const rs = recordingReadableStream();
 
   const ws = recordingWritableStream();
 
   ws.abort(error1);
 
-  return promise_rejects(t, new TypeError(), rs.pipeTo(ws, { preventCancel: true })).then(() => {
+  return promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: true })).then(() => {
     assert_array_equals(rs.eventsWithoutPulls, []);
     assert_array_equals(ws.events, ['abort', error1]);
   });
 
 }, 'Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true');
 
 promise_test(t => {
 
--- a/testing/web-platform/tests/streams/piping/multiple-propagation.js
+++ b/testing/web-platform/tests/streams/piping/multiple-propagation.js
@@ -75,20 +75,20 @@ promise_test(t => {
   writer.releaseLock();
 
   return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the readable stream\'s error').then(() => {
     assert_array_equals(rs.events, []);
     assert_array_equals(ws.events, ['abort', error1]);
 
     return Promise.all([
       promise_rejects(t, error1, rs.getReader().closed, 'the readable stream must be errored with error1'),
-      promise_rejects(t, new TypeError(), ws.getWriter().closed,
-        'closed must reject with a TypeError indicating the writable stream was aborted'),
-      promise_rejects(t, new TypeError(), closePromise,
-        'close() must reject with a TypeError indicating the writable stream was aborted'),
+      promise_rejects(t, error1, ws.getWriter().closed,
+        'closed must reject with error1'),
+      promise_rejects(t, error1, closePromise,
+        'close() must reject with error1')
     ]);
   });
 
 }, 'Piping from an errored readable stream to a closing writable stream');
 
 promise_test(t => {
   const rs = recordingReadableStream({
     start(c) {
--- a/testing/web-platform/tests/streams/transform-streams/errors.js
+++ b/testing/web-platform/tests/streams/transform-streams/errors.js
@@ -200,17 +200,17 @@ promise_test(t => {
   const writer = ts.writable.getWriter();
   // The microtask following transformer.start() hasn't completed yet, so the abort is queued and not notified to the
   // TransformStream yet.
   const abortPromise = writer.abort(thrownError);
   const cancelPromise = ts.readable.cancel(new Error('cancel reason'));
   return Promise.all([
     abortPromise,
     cancelPromise,
-    promise_rejects(t, new TypeError(), writer.closed, 'writer.closed should reject with a TypeError')]);
+    promise_rejects(t, thrownError, writer.closed, 'writer.closed should reject with thrownError')]);
 }, 'abort should set the close reason for the writable when it happens before cancel during start, but cancel should ' +
              'still succeed');
 
 promise_test(t => {
   let resolveTransform;
   const transformPromise = new Promise(resolve => {
     resolveTransform = resolve;
   });
@@ -224,17 +224,17 @@ promise_test(t => {
     const writePromise = writer.write();
     const abortPromise = writer.abort(thrownError);
     const cancelPromise = ts.readable.cancel(new Error('cancel reason'));
     resolveTransform();
     return Promise.all([
       writePromise,
       abortPromise,
       cancelPromise,
-      promise_rejects(t, new TypeError(), writer.closed, 'writer.closed should reject with a TypeError')]);
+      promise_rejects(t, thrownError, writer.closed, 'writer.closed should reject with thrownError')]);
   });
 }, 'abort should set the close reason for the writable when it happens before cancel during underlying sink write, ' +
              'but cancel should still succeed');
 
 const ignoredError = new Error('ignoredError');
 ignoredError.name = 'ignoredError';
 
 promise_test(t => {
@@ -264,19 +264,19 @@ promise_test(t => {
 
 promise_test(t => {
   let controller;
   const ts = new TransformStream({
     start(c) {
       controller = c;
     }
   });
-  return ts.writable.abort().then(() => {
+  return ts.writable.abort(thrownError).then(() => {
     controller.error(ignoredError);
-    return promise_rejects(t, new TypeError(), ts.writable.getWriter().closed, 'closed should reject with a TypeError');
+    return promise_rejects(t, thrownError, ts.writable.getWriter().closed, 'closed should reject with thrownError');
   });
 }, 'controller.error() should do nothing after writable.abort() has completed');
 
 promise_test(t => {
   let controller;
   const ts = new TransformStream({
     start(c) {
       controller = c;
@@ -320,20 +320,27 @@ promise_test(t => {
 
 promise_test(t => {
   const ts = new TransformStream({}, undefined, { highWaterMark: 0 });
   return delay(0).then(() => {
     const writer = ts.writable.getWriter();
     // write should start synchronously
     const writePromise = writer.write(0);
     // The underlying sink's abort() is not called until the write() completes.
-    const abortPromise = writer.abort();
+    const abortPromise = writer.abort(thrownError);
     // Perform a read to relieve backpressure and permit the write() to complete.
     const readPromise = ts.readable.getReader().read();
     return Promise.all([
-      promise_rejects(t, new TypeError(), readPromise, 'read() should reject'),
-      promise_rejects(t, new TypeError(), writePromise, 'write() should reject'),
+      promise_rejects(t, thrownError, readPromise, 'read() should reject'),
+      promise_rejects(t, thrownError, writePromise, 'write() should reject'),
       abortPromise
     ]);
   });
 }, 'a write() that was waiting for backpressure should reject if the writable is aborted');
 
+promise_test(t => {
+  const ts = new TransformStream();
+  ts.writable.abort(thrownError);
+  const reader = ts.readable.getReader();
+  return promise_rejects(t, thrownError, reader.read(), 'read() should reject with thrownError');
+}, 'the readable should be errored with the reason passed to the writable abort() method');
+
 done();
--- a/testing/web-platform/tests/streams/transform-streams/reentrant-strategies.js
+++ b/testing/web-platform/tests/streams/transform-streams/reentrant-strategies.js
@@ -312,13 +312,13 @@ promise_test(t => {
     },
     highWaterMark: 1
   });
   const reader = ts.readable.getReader();
   // Wait for the promise returned by start() to be resolved so that the call to abort() will result in a synchronous
   // call to TransformStreamDefaultSink.
   return delay(0).then(() => {
     controller.enqueue('a');
-    return Promise.all([promise_rejects(t, new TypeError(), reader.read(), 'read() should reject'), abortPromise]);
+    return Promise.all([promise_rejects(t, error1, reader.read(), 'read() should reject'), abortPromise]);
   });
 }, 'writer.abort() inside size() should work');
 
 done();
--- a/testing/web-platform/tests/streams/writable-streams/aborting.js
+++ b/testing/web-platform/tests/streams/writable-streams/aborting.js
@@ -22,34 +22,34 @@ promise_test(t => {
 
   const readyPromise = writer.ready;
 
   writer.abort(error1);
 
   assert_equals(writer.ready, readyPromise, 'the ready promise property should not change');
 
   return Promise.all([
-    promise_rejects(t, new TypeError(), readyPromise, 'the ready promise should reject with a TypeError'),
-    promise_rejects(t, new TypeError(), writePromise, 'the write() promise should reject with a TypeError')
+    promise_rejects(t, error1, readyPromise, 'the ready promise should reject with error1'),
+    promise_rejects(t, error1, writePromise, 'the write() promise should reject with error1')
   ]);
 }, 'Aborting a WritableStream before it starts should cause the writer\'s unsettled ready promise to reject');
 
 promise_test(t => {
   const ws = new WritableStream();
 
   const writer = ws.getWriter();
   writer.write('a');
 
   const readyPromise = writer.ready;
 
   return readyPromise.then(() => {
     writer.abort(error1);
 
     assert_not_equals(writer.ready, readyPromise, 'the ready promise property should change');
-    return promise_rejects(t, new TypeError(), writer.ready, 'the ready promise should reject with a TypeError');
+    return promise_rejects(t, error1, writer.ready, 'the ready promise should reject with error1');
   });
 }, 'Aborting a WritableStream should cause the writer\'s fulfilled ready promise to reset to a rejected one');
 
 promise_test(t => {
   const ws = new WritableStream();
   const writer = ws.getWriter();
 
   writer.releaseLock();
@@ -59,53 +59,53 @@ promise_test(t => {
 
 promise_test(t => {
   const ws = recordingWritableStream();
 
   return delay(0)
     .then(() => {
       const writer = ws.getWriter();
 
-      const abortPromise = writer.abort();
+      const abortPromise = writer.abort(error1);
 
       return Promise.all([
-        promise_rejects(t, new TypeError(), writer.write(1), 'write(1) must reject with a TypeError'),
-        promise_rejects(t, new TypeError(), writer.write(2), 'write(2) must reject with a TypeError'),
+        promise_rejects(t, error1, writer.write(1), 'write(1) must reject with error1'),
+        promise_rejects(t, error1, writer.write(2), 'write(2) must reject with error1'),
         abortPromise
       ]);
     })
     .then(() => {
-      assert_array_equals(ws.events, ['abort', undefined]);
+      assert_array_equals(ws.events, ['abort', error1]);
     });
 }, 'Aborting a WritableStream immediately prevents future writes');
 
 promise_test(t => {
   const ws = recordingWritableStream();
   const results = [];
 
   return delay(0)
     .then(() => {
       const writer = ws.getWriter();
 
       results.push(
         writer.write(1),
-        promise_rejects(t, new TypeError(), writer.write(2), 'write(2) must reject with a TypeError'),
-        promise_rejects(t, new TypeError(), writer.write(3), 'write(3) must reject with a TypeError')
+        promise_rejects(t, error1, writer.write(2), 'write(2) must reject with error1'),
+        promise_rejects(t, error1, writer.write(3), 'write(3) must reject with error1')
       );
 
-      const abortPromise = writer.abort();
+      const abortPromise = writer.abort(error1);
 
       results.push(
-        promise_rejects(t, new TypeError(), writer.write(4), 'write(4) must reject with a TypeError'),
-        promise_rejects(t, new TypeError(), writer.write(5), 'write(5) must reject with a TypeError')
+        promise_rejects(t, error1, writer.write(4), 'write(4) must reject with error1'),
+        promise_rejects(t, error1, writer.write(5), 'write(5) must reject with error1')
       );
 
       return abortPromise;
     }).then(() => {
-      assert_array_equals(ws.events, ['write', 1, 'abort', undefined]);
+      assert_array_equals(ws.events, ['write', 1, 'abort', error1]);
 
       return Promise.all(results);
     });
 }, 'Aborting a WritableStream prevents further writes after any that are in progress');
 
 promise_test(() => {
   const ws = new WritableStream({
     abort() {
@@ -204,47 +204,47 @@ promise_test(t => {
     events.push('ready');
   });
   writer.closed.catch(() => {
     events.push('closed');
   });
 
   return Promise.all([
     abortPromise,
-    promise_rejects(t, new TypeError(), writer.write(), 'writing should reject with a TypeError'),
-    promise_rejects(t, new TypeError(), writer.close(), 'closing should reject with a TypeError'),
-    promise_rejects(t, new TypeError(), writer.ready, 'ready should reject with a TypeError'),
-    promise_rejects(t, new TypeError(), writer.closed, 'closed should reject with a TypeError')
+    promise_rejects(t, error1, writer.write(), 'writing should reject with error1'),
+    promise_rejects(t, error1, writer.close(), 'closing should reject with error1'),
+    promise_rejects(t, error1, writer.ready, 'ready should reject with error1'),
+    promise_rejects(t, error1, writer.closed, 'closed should reject with error1')
   ]).then(() => {
     assert_array_equals(['ready', 'closed'], events, 'ready should reject before closed');
   });
-}, 'Aborting a WritableStream puts it in an errored state, with a TypeError as the stored error');
+}, 'Aborting a WritableStream puts it in an errored state with the error passed to abort()');
 
 promise_test(t => {
   const ws = new WritableStream();
   const writer = ws.getWriter();
 
-  const writePromise = promise_rejects(t, new TypeError(), writer.write('a'),
-    'writing should reject with a TypeError');
+  const writePromise = promise_rejects(t, error1, writer.write('a'),
+    'writing should reject with error1');
 
   writer.abort(error1);
 
   return writePromise;
-}, 'Aborting a WritableStream causes any outstanding write() promises to be rejected with a TypeError');
+}, 'Aborting a WritableStream causes any outstanding write() promises to be rejected with the reason supplied');
 
 promise_test(t => {
   const ws = recordingWritableStream();
   const writer = ws.getWriter();
 
   const closePromise = writer.close();
   const abortPromise = writer.abort(error1);
 
   return Promise.all([
-    promise_rejects(t, new TypeError(), writer.closed, 'closed should reject with a TypeError'),
-    promise_rejects(t, new TypeError(), closePromise, 'close() should reject with a TypeError'),
+    promise_rejects(t, error1, writer.closed, 'closed should reject with error1'),
+    promise_rejects(t, error1, closePromise, 'close() should reject with error1'),
     abortPromise
   ]).then(() => {
     assert_array_equals(ws.events, ['abort', error1]);
   });
 }, 'Closing but then immediately aborting a WritableStream causes the stream to error');
 
 promise_test(() => {
   let resolveClose;
@@ -288,19 +288,19 @@ promise_test(t => {
   const ws = new WritableStream({
     close() {
       closeCalled = true;
     }
   });
 
   const writer = ws.getWriter();
 
-  writer.abort();
+  writer.abort(error1);
 
-  return promise_rejects(t, new TypeError(), writer.closed, 'closed should reject with a TypeError').then(() => {
+  return promise_rejects(t, error1, writer.closed, 'closed should reject with error1').then(() => {
     assert_false(closeCalled, 'close must not have been called');
   });
 }, 'WritableStream should NOT call underlying sink\'s close if no abort is supplied (historical)');
 
 promise_test(() => {
   let thenCalled = false;
   const ws = new WritableStream({
     abort() {
@@ -324,17 +324,17 @@ promise_test(t => {
   });
   const writer = ws.getWriter();
   return writer.ready.then(() => {
     const writePromise = writer.write('a');
     writer.abort(error1);
     let closedRejected = false;
     return Promise.all([
       writePromise.then(() => assert_false(closedRejected, '.closed should not resolve before write()')),
-      promise_rejects(t, new TypeError(), writer.closed, '.closed should reject').then(() => {
+      promise_rejects(t, error1, writer.closed, '.closed should reject').then(() => {
         closedRejected = true;
       })
     ]);
   });
 }, '.closed should not resolve before fulfilled write()');
 
 promise_test(t => {
   const ws = new WritableStream({
@@ -345,17 +345,17 @@ promise_test(t => {
   const writer = ws.getWriter();
   return writer.ready.then(() => {
     const writePromise = writer.write('a');
     const abortPromise = writer.abort(error2);
     let closedRejected = false;
     return Promise.all([
       promise_rejects(t, error1, writePromise, 'write() should reject')
           .then(() => assert_false(closedRejected, '.closed should not resolve before write()')),
-      promise_rejects(t, new TypeError(), writer.closed, '.closed should reject')
+      promise_rejects(t, error2, writer.closed, '.closed should reject')
           .then(() => {
             closedRejected = true;
           }),
       abortPromise
     ]);
   });
 }, '.closed should not resolve before rejected write(); write() error should not overwrite abort() error');
 
@@ -365,19 +365,19 @@ promise_test(t => {
       return flushAsyncEvents();
     }
   }, new CountQueuingStrategy(4));
   const writer = ws.getWriter();
   return writer.ready.then(() => {
     const settlementOrder = [];
     return Promise.all([
       writer.write('1').then(() => settlementOrder.push(1)),
-      promise_rejects(t, new TypeError(), writer.write('2'), 'first queued write should be rejected')
+      promise_rejects(t, error1, writer.write('2'), 'first queued write should be rejected')
           .then(() => settlementOrder.push(2)),
-      promise_rejects(t, new TypeError(), writer.write('3'), 'second queued write should be rejected')
+      promise_rejects(t, error1, writer.write('3'), 'second queued write should be rejected')
           .then(() => settlementOrder.push(3)),
       writer.abort(error1)
     ]).then(() => assert_array_equals([1, 2, 3], settlementOrder, 'writes should be satisfied in order'));
   });
 }, 'writes should be satisfied in order when aborting');
 
 promise_test(t => {
   const ws = new WritableStream({
@@ -386,41 +386,41 @@ promise_test(t => {
     }
   }, new CountQueuingStrategy(4));
   const writer = ws.getWriter();
   return writer.ready.then(() => {
     const settlementOrder = [];
     return Promise.all([
       promise_rejects(t, error1, writer.write('1'), 'in-flight write should be rejected')
           .then(() => settlementOrder.push(1)),
-      promise_rejects(t, new TypeError(), writer.write('2'), 'first queued write should be rejected')
+      promise_rejects(t, error2, writer.write('2'), 'first queued write should be rejected')
           .then(() => settlementOrder.push(2)),
-      promise_rejects(t, new TypeError(), writer.write('3'), 'second queued write should be rejected')
+      promise_rejects(t, error2, writer.write('3'), 'second queued write should be rejected')
           .then(() => settlementOrder.push(3)),
       writer.abort(error2)
     ]).then(() => assert_array_equals([1, 2, 3], settlementOrder, 'writes should be satisfied in order'));
   });
 }, 'writes should be satisfied in order after rejected write when aborting');
 
 promise_test(t => {
   const ws = new WritableStream({
     write() {
       return Promise.reject(error1);
     }
   });
   const writer = ws.getWriter();
   return writer.ready.then(() => {
     return Promise.all([
       promise_rejects(t, error1, writer.write('a'), 'writer.write() should reject with error from underlying write()'),
-      promise_rejects(t, new TypeError(), writer.close(),
+      promise_rejects(t, error2, writer.close(),
                       'writer.close() should reject with error from underlying write()'),
-      writer.abort()
+      writer.abort(error2)
     ]);
   });
-}, 'close() should reject with TypeError when abort() is first error');
+}, 'close() should reject with abort reason why abort() is first error');
 
 promise_test(() => {
   let resolveWrite;
   const ws = recordingWritableStream({
     write() {
       return new Promise(resolve => {
         resolveWrite = resolve;
       });
@@ -505,46 +505,46 @@ promise_test(t => {
       });
     }
   });
 
   const writer = ws.getWriter();
   return writer.ready.then(() => {
     writer.write('a');
     const closePromise = writer.close();
-    const abortPromise = writer.abort('b');
+    const abortPromise = writer.abort(error1);
 
     return flushAsyncEvents().then(() => {
       assert_array_equals(ws.events, ['write', 'a'], 'abort should not be called while write is in-flight');
       resolveWrite();
       return abortPromise.then(() => {
-        assert_array_equals(ws.events, ['write', 'a', 'abort', 'b'], 'abort should be called after write completes');
-        return promise_rejects(t, new TypeError(), closePromise, 'promise returned by close() should be rejected');
+        assert_array_equals(ws.events, ['write', 'a', 'abort', error1], 'abort should be called after write completes');
+        return promise_rejects(t, error1, closePromise, 'promise returned by close() should be rejected');
       });
     });
   });
 }, 'an abort() that happens during a write() should trigger the underlying abort() even with a close() queued');
 
 promise_test(t => {
   const ws = new WritableStream({
     write() {
       return new Promise(() => {});
     }
   });
 
   const writer = ws.getWriter();
   return writer.ready.then(() => {
     writer.write('a');
-    writer.abort();
+    writer.abort(error1);
     writer.releaseLock();
     const writer2 = ws.getWriter();
-    return promise_rejects(t, new TypeError(), writer2.ready,
-                           'ready of the second writer should be rejected with a TypeError');
+    return promise_rejects(t, error1, writer2.ready,
+                           'ready of the second writer should be rejected with error1');
   });
-}, 'if a writer is created for a stream with a pending abort, its ready should be rejected with a TypeError');
+}, 'if a writer is created for a stream with a pending abort, its ready should be rejected with the abort error');
 
 promise_test(() => {
   const ws = new WritableStream();
   const writer = ws.getWriter();
   return writer.ready.then(() => {
     const closePromise = writer.close();
     const abortPromise = writer.abort();
     const events = [];
@@ -602,43 +602,43 @@ promise_test(t => {
     abortPromise = writer.abort(error1);
     abortPromise.then(() => {
       events.push('abortPromise');
     });
 
     const writePromise2 = writer.write('a');
 
     return Promise.all([
-      promise_rejects(t, new TypeError(), writePromise2, 'writePromise2 must reject with an error indicating abort'),
-      promise_rejects(t, new TypeError(), writer.ready, 'writer.ready must reject with an error indicating abort'),
+      promise_rejects(t, error1, writePromise2, 'writePromise2 must reject with the error from abort'),
+      promise_rejects(t, error1, writer.ready, 'writer.ready must reject with the error from abort'),
       flushAsyncEvents()
     ]);
   }).then(() => {
     assert_array_equals(events, [], 'writePromise, abortPromise and writer.closed must not be rejected yet');
 
     rejectWrite(error2);
 
     return Promise.all([
       promise_rejects(t, error2, writePromise,
                       'writePromise must reject with the error returned from the sink\'s write method'),
       abortPromise,
-      promise_rejects(t, new TypeError(), writer.closed,
-                      'writer.closed must reject with an error indicating abort'),
+      promise_rejects(t, error1, writer.closed,
+                      'writer.closed must reject with the error from abort'),
       flushAsyncEvents()
     ]);
   }).then(() => {
     assert_array_equals(events, ['writePromise', 'abortPromise', 'closed'],
                         'writePromise, abortPromise and writer.closed must settle');
 
     const writePromise3 = writer.write('a');
 
     return Promise.all([
-      promise_rejects(t, new TypeError(), writePromise3,
-                      'writePromise3 must reject with an error indicating abort'),
-      promise_rejects(t, new TypeError(), writer.ready,
+      promise_rejects(t, error1, writePromise3,
+                      'writePromise3 must reject with the error from abort'),
+      promise_rejects(t, error1, writer.ready,
                       'writer.ready must be still rejected with the error indicating abort')
     ]);
   }).then(() => {
     writer.releaseLock();
 
     return Promise.all([
       promise_rejects(t, new TypeError(), writer.ready,
                       'writer.ready must be rejected with an error indicating release'),
@@ -681,61 +681,61 @@ promise_test(t => {
     abortPromise = writer.abort(error1);
     abortPromise.then(() => {
       events.push('abortPromise');
     });
 
     const writePromise2 = writer.write('a');
 
     return Promise.all([
-      promise_rejects(t, new TypeError(), writePromise2, 'writePromise2 must reject with an error indicating abort'),
-      promise_rejects(t, new TypeError(), writer.ready, 'writer.ready must reject with an error indicating abort'),
+      promise_rejects(t, error1, writePromise2, 'writePromise2 must reject with the error from abort'),
+      promise_rejects(t, error1, writer.ready, 'writer.ready must reject with the error from abort'),
       flushAsyncEvents()
     ]);
   }).then(() => {
     assert_array_equals(events, [], 'writePromise, abortPromise and writer.closed must not be fulfilled/rejected yet');
 
     // This error is too late to change anything. abort() has already changed the stream state to 'erroring'.
     controller.error(error2);
 
     const writePromise3 = writer.write('a');
 
     return Promise.all([
-      promise_rejects(t, new TypeError(), writePromise3,
-                      'writePromise3 must reject with an error indicating abort'),
-      promise_rejects(t, new TypeError(), writer.ready,
+      promise_rejects(t, error1, writePromise3,
+                      'writePromise3 must reject with the error from abort'),
+      promise_rejects(t, error1, writer.ready,
                       'writer.ready must be still rejected with the error indicating abort'),
       flushAsyncEvents()
     ]);
   }).then(() => {
     assert_array_equals(
         events, [],
         'writePromise, abortPromise and writer.closed must not be fulfilled/rejected yet even after ' +
             'controller.error() call');
 
     resolveWrite();
 
     return Promise.all([
       writePromise,
       abortPromise,
-      promise_rejects(t, new TypeError(), writer.closed,
-                      'writer.closed must reject with an error indicating abort'),
+      promise_rejects(t, error1, writer.closed,
+                      'writer.closed must reject with the error from abort'),
       flushAsyncEvents()
     ]);
   }).then(() => {
     assert_array_equals(events, ['writePromise', 'abortPromise', 'closed'],
                         'writePromise, abortPromise and writer.closed must settle');
 
     const writePromise4 = writer.write('a');
 
     return Promise.all([
       writePromise,
-      promise_rejects(t, new TypeError(), writePromise4,
-                      'writePromise4 must reject with an error indicating abort'),
-      promise_rejects(t, new TypeError(), writer.ready,
+      promise_rejects(t, error1, writePromise4,
+                      'writePromise4 must reject with the error from abort'),
+      promise_rejects(t, error1, writer.ready,
                       'writer.ready must be still rejected with the error indicating abort')
     ]);
   }).then(() => {
     writer.releaseLock();
 
     return Promise.all([
       promise_rejects(t, new TypeError(), writer.ready,
                       'writer.ready must be rejected with an error indicating release'),
@@ -780,28 +780,28 @@ promise_test(t => {
     abortPromise = writer.abort(error1);
     abortPromise.then(() => {
       events.push('abortPromise');
     });
 
     return Promise.all([
       promise_rejects(t, new TypeError(), writer.close(),
         'writer.close() must reject with an error indicating already closing'),
-      promise_rejects(t, new TypeError(), writer.ready, 'writer.ready must reject with an error indicating abort'),
+      promise_rejects(t, error1, writer.ready, 'writer.ready must reject with the error from abort'),
       flushAsyncEvents()
     ]);
   }).then(() => {
     assert_array_equals(events, [], 'closePromise, abortPromise and writer.closed must not be fulfilled/rejected yet');
 
     controller.error(error2);
 
     return Promise.all([
       promise_rejects(t, new TypeError(), writer.close(),
         'writer.close() must reject with an error indicating already closing'),
-      promise_rejects(t, new TypeError(), writer.ready,
+      promise_rejects(t, error1, writer.ready,
                       'writer.ready must be still rejected with the error indicating abort'),
       flushAsyncEvents()
     ]);
   }).then(() => {
     assert_array_equals(
         events, [],
         'closePromise, abortPromise and writer.closed must not be fulfilled/rejected yet even after ' +
             'controller.error() call');
@@ -816,17 +816,17 @@ promise_test(t => {
     ]);
   }).then(() => {
     assert_array_equals(events, ['closePromise', 'abortPromise', 'closed'],
                         'closedPromise, abortPromise and writer.closed must fulfill');
 
     return Promise.all([
       promise_rejects(t, new TypeError(), writer.close(),
         'writer.close() must reject with an error indicating already closing'),
-      promise_rejects(t, new TypeError(), writer.ready,
+      promise_rejects(t, error1, writer.ready,
                       'writer.ready must be still rejected with the error indicating abort')
     ]);
   }).then(() => {
     writer.releaseLock();
 
     return Promise.all([
       promise_rejects(t, new TypeError(), writer.close(),
         'writer.close() must reject with an error indicating release'),
@@ -1120,45 +1120,45 @@ promise_test(() => {
   return ws.abort('done').then(() =>
       assert_array_equals(ws.events, ['abort', 'done'], 'abort() should still be called if start() rejects'));
 }, 'stream abort() promise should still resolve if sink start() rejects');
 
 promise_test(t => {
   const ws = new WritableStream();
   const writer = ws.getWriter();
   const writerReady1 = writer.ready;
-  writer.abort('a');
+  writer.abort(error1);
   const writerReady2 = writer.ready;
   assert_not_equals(writerReady1, writerReady2, 'abort() should replace the ready promise with a rejected one');
   return Promise.all([writerReady1,
-                      promise_rejects(t, new TypeError(), writerReady2, 'writerReady2 should reject')]);
+                      promise_rejects(t, error1, writerReady2, 'writerReady2 should reject')]);
 }, 'writer abort() during sink start() should replace the writer.ready promise synchronously');
 
 promise_test(t => {
   const events = [];
   const ws = recordingWritableStream();
   const writer = ws.getWriter();
   const writePromise1 = writer.write(1);
-  const abortPromise = writer.abort('a');
+  const abortPromise = writer.abort(error1);
   const writePromise2 = writer.write(2);
   const closePromise = writer.close();
   writePromise1.catch(() => events.push('write1'));
   abortPromise.then(() => events.push('abort'));
   writePromise2.catch(() => events.push('write2'));
   closePromise.catch(() => events.push('close'));
   return Promise.all([
-    promise_rejects(t, new TypeError(), writePromise1, 'first write() should reject'),
+    promise_rejects(t, error1, writePromise1, 'first write() should reject'),
     abortPromise,
-    promise_rejects(t, new TypeError(), writePromise2, 'second write() should reject'),
-    promise_rejects(t, new TypeError(), closePromise, 'close() should reject')
+    promise_rejects(t, error1, writePromise2, 'second write() should reject'),
+    promise_rejects(t, error1, closePromise, 'close() should reject')
   ])
   .then(() => {
     assert_array_equals(events, ['write2', 'write1', 'abort', 'close'],
                         'promises should resolve in the standard order');
-    assert_array_equals(ws.events, ['abort', 'a'], 'underlying sink write() should not be called');
+    assert_array_equals(ws.events, ['abort', error1], 'underlying sink write() should not be called');
   });
 }, 'promises returned from other writer methods should be rejected when writer abort() happens during sink start()');
 
 promise_test(t => {
   let writeReject;
   let controller;
   const ws = new WritableStream({
     write(chunk, c) {
@@ -1219,17 +1219,17 @@ promise_test(t => {
   const writer = ws.getWriter();
   return writer.ready.then(() => {
     const writePromise = writer.write('1');
     const abortPromise = writer.abort(error2);
     rejectWrite(error1);
     return Promise.all([
       promise_rejects(t, error1, writePromise, 'write should reject'),
       abortPromise,
-      promise_rejects(t, new TypeError(), writer.closed, 'closed should reject with TypeError')
+      promise_rejects(t, error2, writer.closed, 'closed should reject with error2')
     ]);
   }).then(() => {
     assert_array_equals(ws.events, ['write', '1', 'abort', error2], 'abort sink method should be called');
   });
 }, 'a rejecting sink.write() should not prevent sink.abort() from being called');
 
 promise_test(() => {
   const ws = recordingWritableStream({
@@ -1238,27 +1238,27 @@ promise_test(() => {
     }
   });
   return ws.abort(error2)
       .then(() => {
         assert_array_equals(ws.events, ['abort', error2]);
       });
 }, 'when start errors after stream abort(), underlying sink abort() should be called anyway');
 
-promise_test(t => {
+promise_test(() => {
   const ws = new WritableStream();
   const abortPromise1 = ws.abort();
   const abortPromise2 = ws.abort();
   assert_equals(abortPromise1, abortPromise2, 'the promises must be the same');
 
   return abortPromise1.then(
       v => assert_equals(v, undefined, 'abort() should fulfill with undefined'));
 }, 'when calling abort() twice on the same stream, both should give the same promise that fulfills with undefined');
 
-promise_test(t => {
+promise_test(() => {
   const ws = new WritableStream();
   const abortPromise1 = ws.abort();
 
   return abortPromise1.then(v1 => {
     assert_equals(v1, undefined, 'first abort() should fulfill with undefined');
 
     const abortPromise2 = ws.abort();
     assert_not_equals(abortPromise2, abortPromise1, 'because we waited, the second promise should be a new promise');
--- a/testing/web-platform/tests/streams/writable-streams/bad-underlying-sinks.js
+++ b/testing/web-platform/tests/streams/writable-streams/bad-underlying-sinks.js
@@ -184,12 +184,12 @@ promise_test(t => {
     abort() {
       throw error1;
     }
   });
 
   const writer = ws.getWriter();
 
   return promise_rejects(t, error1, writer.abort(abortReason), 'abort should reject with the thrown error')
-  .then(() => promise_rejects(t, new TypeError(), writer.closed, 'closed should reject with a TypeError'));
+  .then(() => promise_rejects(t, abortReason, writer.closed, 'closed should reject with abortReason'));
 }, 'abort: throwing method should cause abort() and closed to reject');
 
 done();
--- a/testing/web-platform/tests/streams/writable-streams/close.js
+++ b/testing/web-platform/tests/streams/writable-streams/close.js
@@ -356,18 +356,18 @@ promise_test(t => {
     closePromise.catch(() => events.push('closePromise'));
     abortPromise.catch(() => events.push('abortPromise'));
     writer.closed.catch(() => events.push('closed'));
     return Promise.all([
       promise_rejects(t, error1, closePromise,
                       'closePromise must reject with the error returned from the sink\'s close method'),
       promise_rejects(t, error1, abortPromise,
                       'abortPromise must reject with the error returned from the sink\'s close method'),
-      promise_rejects(t, new TypeError(), writer.closed,
-                      'writer.closed must reject with a TypeError indicating the stream was aborted')
+      promise_rejects(t, error2, writer.closed,
+                      'writer.closed must reject with error2')
     ]).then(() => {
       assert_array_equals(events, ['closePromise', 'abortPromise', 'closed'],
                           'promises must fulfill/reject in the expected order');
     });
   });
 }, 'promises must fulfill/reject in the expected order on aborted and errored closure');
 
 promise_test(t => {
--- a/testing/web-platform/tests/streams/writable-streams/general.js
+++ b/testing/web-platform/tests/streams/writable-streams/general.js
@@ -160,49 +160,52 @@ promise_test(() => {
       .then(() => promises.close)
       .then(thisValue => assert_equals(thisValue, theSink, 'close should be called as a method'))
       .then(() => promises.abort)
       .then(thisValue => assert_equals(thisValue, theSink, 'abort should be called as a method'));
 }, 'WritableStream should call underlying sink methods as methods');
 
 promise_test(t => {
   function functionWithOverloads() {}
-  functionWithOverloads.apply = () => assert_unreached('apply() should not be called');
-  functionWithOverloads.call = () => assert_unreached('call() should not be called');
+  functionWithOverloads.apply = t.unreached_func('apply() should not be called');
+  functionWithOverloads.call = t.unreached_func('call() should not be called');
   const underlyingSink = {
     start: functionWithOverloads,
     write: functionWithOverloads,
     close: functionWithOverloads,
     abort: functionWithOverloads
   };
   // Test start(), write(), close().
   const ws1 = new WritableStream(underlyingSink);
   const writer1 = ws1.getWriter();
   writer1.write('a');
   writer1.close();
 
   // Test abort().
+  const abortError = new Error();
+  abortError.name = 'abort error';
+
   const ws2 = new WritableStream(underlyingSink);
   const writer2 = ws2.getWriter();
-  writer2.abort();
+  writer2.abort(abortError);
 
   // Test abort() with a close underlying sink method present. (Historical; see
   // https://github.com/whatwg/streams/issues/620#issuecomment-263483953 for what used to be
   // tested here. But more coverage can't hurt.)
   const ws3 = new WritableStream({
     start: functionWithOverloads,
     write: functionWithOverloads,
     close: functionWithOverloads
   });
   const writer3 = ws3.getWriter();
-  writer3.abort();
+  writer3.abort(abortError);
 
   return writer1.closed
-      .then(() => promise_rejects(t, new TypeError(), writer2.closed, 'writer2.closed should be rejected'))
-      .then(() => promise_rejects(t, new TypeError(), writer3.closed, 'writer3.closed should be rejected'));
+      .then(() => promise_rejects(t, abortError, writer2.closed, 'writer2.closed should be rejected'))
+      .then(() => promise_rejects(t, abortError, writer3.closed, 'writer3.closed should be rejected'));
 }, 'methods should not not have .apply() or .call() called');
 
 promise_test(() => {
   const strategy = {
     size() {
       if (this !== undefined) {
         throw new Error('size called as a method');
       }
--- a/testing/web-platform/tests/streams/writable-streams/reentrant-strategy.js
+++ b/testing/web-platform/tests/streams/writable-streams/reentrant-strategy.js
@@ -109,26 +109,26 @@ promise_test(t => {
         assert_array_equals(ws.events, ['close'], 'sink.write() should not be called');
       });
 }, 'close() should work when called from within strategy.size()');
 
 promise_test(t => {
   let writer;
   const strategy = {
     size() {
-      writer.abort('nice');
+      writer.abort(error1);
       return 1;
     }
   };
 
   const ws = recordingWritableStream({}, strategy);
   writer = ws.getWriter();
-  return promise_rejects(t, new TypeError(), writer.write('a'), 'write() promise should reject')
+  return promise_rejects(t, error1, writer.write('a'), 'write() promise should reject')
       .then(() => {
-        assert_array_equals(ws.events, ['abort', 'nice'], 'sink.write() should not be called');
+        assert_array_equals(ws.events, ['abort', error1], 'sink.write() should not be called');
       });
 }, 'abort() should work when called from within strategy.size()');
 
 promise_test(t => {
   let writer;
   const strategy = {
     size() {
       writer.releaseLock();