205 lines
7.6 KiB
JavaScript
205 lines
7.6 KiB
JavaScript
// META: global=window,worker,shadowrealm
|
|
// META: script=../resources/test-utils.js
|
|
'use strict';
|
|
|
|
const thrownError = new Error('bad things are happening!');
|
|
thrownError.name = 'error1';
|
|
|
|
const originalReason = new Error('original reason');
|
|
originalReason.name = 'error2';
|
|
|
|
promise_test(async t => {
|
|
let cancelled = undefined;
|
|
const ts = new TransformStream({
|
|
cancel(reason) {
|
|
cancelled = reason;
|
|
}
|
|
});
|
|
const res = await ts.readable.cancel(thrownError);
|
|
assert_equals(res, undefined, 'readable.cancel() should return undefined');
|
|
assert_equals(cancelled, thrownError, 'transformer.cancel() should be called with the passed reason');
|
|
}, 'cancelling the readable side should call transformer.cancel()');
|
|
|
|
promise_test(async t => {
|
|
const ts = new TransformStream({
|
|
cancel(reason) {
|
|
assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason');
|
|
throw thrownError;
|
|
}
|
|
});
|
|
const writer = ts.writable.getWriter();
|
|
const cancelPromise = ts.readable.cancel(originalReason);
|
|
await promise_rejects_exactly(t, thrownError, cancelPromise, 'readable.cancel() should reject with thrownError');
|
|
await promise_rejects_exactly(t, thrownError, writer.closed, 'writer.closed should reject with thrownError');
|
|
}, 'cancelling the readable side should reject if transformer.cancel() throws');
|
|
|
|
promise_test(async t => {
|
|
let aborted = undefined;
|
|
const ts = new TransformStream({
|
|
cancel(reason) {
|
|
aborted = reason;
|
|
},
|
|
flush: t.unreached_func('flush should not be called')
|
|
});
|
|
const res = await ts.writable.abort(thrownError);
|
|
assert_equals(res, undefined, 'writable.abort() should return undefined');
|
|
assert_equals(aborted, thrownError, 'transformer.abort() should be called with the passed reason');
|
|
}, 'aborting the writable side should call transformer.abort()');
|
|
|
|
promise_test(async t => {
|
|
const ts = new TransformStream({
|
|
cancel(reason) {
|
|
assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason');
|
|
throw thrownError;
|
|
},
|
|
flush: t.unreached_func('flush should not be called')
|
|
});
|
|
const reader = ts.readable.getReader();
|
|
const abortPromise = ts.writable.abort(originalReason);
|
|
await promise_rejects_exactly(t, thrownError, abortPromise, 'writable.abort() should reject with thrownError');
|
|
await promise_rejects_exactly(t, thrownError, reader.closed, 'reader.closed should reject with thrownError');
|
|
}, 'aborting the writable side should reject if transformer.cancel() throws');
|
|
|
|
promise_test(async t => {
|
|
const ts = new TransformStream({
|
|
async cancel(reason) {
|
|
assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason');
|
|
throw thrownError;
|
|
},
|
|
flush: t.unreached_func('flush should not be called')
|
|
});
|
|
const cancelPromise = ts.readable.cancel(originalReason);
|
|
const closePromise = ts.writable.close();
|
|
await Promise.all([
|
|
promise_rejects_exactly(t, thrownError, cancelPromise, 'cancelPromise should reject with thrownError'),
|
|
promise_rejects_exactly(t, thrownError, closePromise, 'closePromise should reject with thrownError'),
|
|
]);
|
|
}, 'closing the writable side should reject if a parallel transformer.cancel() throws');
|
|
|
|
promise_test(async t => {
|
|
let controller;
|
|
const ts = new TransformStream({
|
|
start(c) {
|
|
controller = c;
|
|
},
|
|
async cancel(reason) {
|
|
assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason');
|
|
controller.error(thrownError);
|
|
},
|
|
flush: t.unreached_func('flush should not be called')
|
|
});
|
|
const cancelPromise = ts.readable.cancel(originalReason);
|
|
const closePromise = ts.writable.close();
|
|
await Promise.all([
|
|
promise_rejects_exactly(t, thrownError, cancelPromise, 'cancelPromise should reject with thrownError'),
|
|
promise_rejects_exactly(t, thrownError, closePromise, 'closePromise should reject with thrownError'),
|
|
]);
|
|
}, 'readable.cancel() and a parallel writable.close() should reject if a transformer.cancel() calls controller.error()');
|
|
|
|
promise_test(async t => {
|
|
let controller;
|
|
const ts = new TransformStream({
|
|
start(c) {
|
|
controller = c;
|
|
},
|
|
async cancel(reason) {
|
|
assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason');
|
|
controller.error(thrownError);
|
|
},
|
|
flush: t.unreached_func('flush should not be called')
|
|
});
|
|
const cancelPromise = ts.writable.abort(originalReason);
|
|
await promise_rejects_exactly(t, thrownError, cancelPromise, 'cancelPromise should reject with thrownError');
|
|
const closePromise = ts.readable.cancel(1);
|
|
await promise_rejects_exactly(t, thrownError, closePromise, 'closePromise should reject with thrownError');
|
|
}, 'writable.abort() and readable.cancel() should reject if a transformer.cancel() calls controller.error()');
|
|
|
|
promise_test(async t => {
|
|
const cancelReason = new Error('cancel reason');
|
|
let controller;
|
|
let cancelPromise;
|
|
let flushCalled = false;
|
|
const ts = new TransformStream({
|
|
start(c) {
|
|
controller = c;
|
|
},
|
|
flush() {
|
|
flushCalled = true;
|
|
cancelPromise = ts.readable.cancel(cancelReason);
|
|
},
|
|
cancel: t.unreached_func('cancel should not be called')
|
|
});
|
|
await flushAsyncEvents(); // ensure stream is started
|
|
await ts.writable.close();
|
|
assert_true(flushCalled, 'flush() was called');
|
|
await cancelPromise;
|
|
}, 'readable.cancel() should not call cancel() when flush() is already called from writable.close()');
|
|
|
|
promise_test(async t => {
|
|
const cancelReason = new Error('cancel reason');
|
|
const abortReason = new Error('abort reason');
|
|
let cancelCalls = 0;
|
|
let controller;
|
|
let cancelPromise;
|
|
const ts = new TransformStream({
|
|
start(c) {
|
|
controller = c;
|
|
},
|
|
cancel() {
|
|
if (++cancelCalls === 1) {
|
|
cancelPromise = ts.readable.cancel(cancelReason);
|
|
}
|
|
},
|
|
flush: t.unreached_func('flush should not be called')
|
|
});
|
|
await flushAsyncEvents(); // ensure stream is started
|
|
await ts.writable.abort(abortReason);
|
|
assert_equals(cancelCalls, 1);
|
|
await cancelPromise;
|
|
assert_equals(cancelCalls, 1);
|
|
}, 'readable.cancel() should not call cancel() again when already called from writable.abort()');
|
|
|
|
promise_test(async t => {
|
|
const cancelReason = new Error('cancel reason');
|
|
let controller;
|
|
let closePromise;
|
|
let cancelCalled = false;
|
|
const ts = new TransformStream({
|
|
start(c) {
|
|
controller = c;
|
|
},
|
|
cancel() {
|
|
cancelCalled = true;
|
|
closePromise = ts.writable.close();
|
|
},
|
|
flush: t.unreached_func('flush should not be called')
|
|
});
|
|
await flushAsyncEvents(); // ensure stream is started
|
|
await ts.readable.cancel(cancelReason);
|
|
assert_true(cancelCalled, 'cancel() was called');
|
|
await closePromise;
|
|
}, 'writable.close() should not call flush() when cancel() is already called from readable.cancel()');
|
|
|
|
promise_test(async t => {
|
|
const cancelReason = new Error('cancel reason');
|
|
const abortReason = new Error('abort reason');
|
|
let cancelCalls = 0;
|
|
let controller;
|
|
let abortPromise;
|
|
const ts = new TransformStream({
|
|
start(c) {
|
|
controller = c;
|
|
},
|
|
cancel() {
|
|
if (++cancelCalls === 1) {
|
|
abortPromise = ts.writable.abort(abortReason);
|
|
}
|
|
},
|
|
flush: t.unreached_func('flush should not be called')
|
|
});
|
|
await flushAsyncEvents(); // ensure stream is started
|
|
await promise_rejects_exactly(t, abortReason, ts.readable.cancel(cancelReason));
|
|
assert_equals(cancelCalls, 1);
|
|
await promise_rejects_exactly(t, abortReason, abortPromise);
|
|
assert_equals(cancelCalls, 1);
|
|
}, 'writable.abort() should not call cancel() again when already called from readable.cancel()');
|