diff --git a/reference-implementation/to-upstream-wpts/transform-streams/errors.js b/reference-implementation/to-upstream-wpts/transform-streams/errors.js index 5df3b2de2..bbbd8b8a8 100644 --- a/reference-implementation/to-upstream-wpts/transform-streams/errors.js +++ b/reference-implementation/to-upstream-wpts/transform-streams/errors.js @@ -206,7 +206,8 @@ promise_test(t => { abortPromise, cancelPromise, promise_rejects(t, new TypeError(), writer.closed, 'writer.closed should reject with a TypeError')]); -}, 'abort should set the close reason for the writable when it happens first during start'); +}, '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; @@ -230,6 +231,55 @@ promise_test(t => { cancelPromise, promise_rejects(t, new TypeError(), writer.closed, 'writer.closed should reject with a TypeError')]); }); -}, 'abort should set the close reason for the writable when it happens first during underlying sink write'); +}, 'abort should set the close reason for the writable when it happens before cancel during underlying sink write, ' + + 'but cancel should still succeed'); + +test(() => { + new TransformStream({ + start(controller) { + controller.error(thrownError); + assert_throws(new TypeError(), () => controller.error(), 'error() should throw'); + } + }); +}, 'controller.error() should throw the second time it is called'); + +promise_test(() => { + let controller; + const ts = new TransformStream({ + start(c) { + controller = c; + } + }); + const cancelPromise = ts.readable.cancel(); + assert_throws(new TypeError(), () => controller.error(), 'error() should throw'); + return cancelPromise; +}, 'controller.error() should throw after readable.cancel() but the cancel should still succeed'); + +promise_test(() => { + let controller; + const ts = new TransformStream({ + start(c) { + controller = c; + } + }); + return ts.writable.abort().then(() => { + assert_throws(new TypeError(), () => controller.error(), 'error() should throw'); + }); +}, 'controller.error() should throw after writable.abort() has completed'); + +promise_test(t => { + let controller; + const ts = new TransformStream({ + start(c) { + controller = c; + }, + transform() { + throw thrownError; + } + }, undefined, { highWaterMark: Infinity }); + return promise_rejects(t, thrownError, ts.writable.getWriter().write(), 'write() should reject').then(() => { + assert_throws(new TypeError(), () => controller.error(), 'error() should throw'); + }); +}, 'controller.error() should throw after a transformer method has thrown an exception'); done(); diff --git a/reference-implementation/to-upstream-wpts/transform-streams/general.js b/reference-implementation/to-upstream-wpts/transform-streams/general.js index fd472c6a5..cee5e9705 100644 --- a/reference-implementation/to-upstream-wpts/transform-streams/general.js +++ b/reference-implementation/to-upstream-wpts/transform-streams/general.js @@ -367,6 +367,48 @@ promise_test(() => { writer.close(); return Promise.all([writer.closed, ts.readable.getReader().closed]); -}, 'closing the writable should closes the readable when there are no queued chunks, even with backpressure'); +}, 'closing the writable should close the readable when there are no queued chunks, even with backpressure'); + +test(() => { + new TransformStream({ + start(controller) { + controller.close(); + assert_throws(new TypeError(), () => controller.enqueue(), 'enqueue should throw'); + } + }); +}, 'enqueue() should throw after controller.close()'); + +promise_test(() => { + let controller; + const ts = new TransformStream({ + start(c) { + controller = c; + } + }); + const cancelPromise = ts.readable.cancel(); + assert_throws(new TypeError(), () => controller.enqueue(), 'enqueue should throw'); + return cancelPromise; +}, 'enqueue() should throw after readable.cancel()'); + +test(() => { + new TransformStream({ + start(controller) { + controller.close(); + assert_throws(new TypeError(), () => controller.close(), 'close should throw'); + } + }); +}, 'controller.close() should throw the second time it is called'); + +promise_test(() => { + let controller; + const ts = new TransformStream({ + start(c) { + controller = c; + } + }); + const cancelPromise = ts.readable.cancel(); + assert_throws(new TypeError(), () => controller.close(), 'close should throw'); + return cancelPromise; +}, 'close() should throw after readable.cancel()'); done();