146 lines
4.5 KiB
JavaScript
146 lines
4.5 KiB
JavaScript
// META: global=window,worker,shadowrealm
|
|
// META: script=../resources/test-utils.js
|
|
'use strict';
|
|
|
|
promise_test(() => {
|
|
let flushCalled = false;
|
|
const ts = new TransformStream({
|
|
transform() { },
|
|
flush() {
|
|
flushCalled = true;
|
|
}
|
|
});
|
|
|
|
return ts.writable.getWriter().close().then(() => {
|
|
return assert_true(flushCalled, 'closing the writable triggers the transform flush immediately');
|
|
});
|
|
}, 'TransformStream flush is called immediately when the writable is closed, if no writes are queued');
|
|
|
|
promise_test(() => {
|
|
let flushCalled = false;
|
|
let resolveTransform;
|
|
const ts = new TransformStream({
|
|
transform() {
|
|
return new Promise(resolve => {
|
|
resolveTransform = resolve;
|
|
});
|
|
},
|
|
flush() {
|
|
flushCalled = true;
|
|
return new Promise(() => {}); // never resolves
|
|
}
|
|
}, undefined, { highWaterMark: 1 });
|
|
|
|
const writer = ts.writable.getWriter();
|
|
writer.write('a');
|
|
writer.close();
|
|
assert_false(flushCalled, 'closing the writable does not immediately call flush if writes are not finished');
|
|
|
|
let rsClosed = false;
|
|
ts.readable.getReader().closed.then(() => {
|
|
rsClosed = true;
|
|
});
|
|
|
|
return delay(0).then(() => {
|
|
assert_false(flushCalled, 'closing the writable does not asynchronously call flush if writes are not finished');
|
|
resolveTransform();
|
|
return delay(0);
|
|
}).then(() => {
|
|
assert_true(flushCalled, 'flush is eventually called');
|
|
assert_false(rsClosed, 'if flushPromise does not resolve, the readable does not become closed');
|
|
});
|
|
}, 'TransformStream flush is called after all queued writes finish, once the writable is closed');
|
|
|
|
promise_test(() => {
|
|
let c;
|
|
const ts = new TransformStream({
|
|
start(controller) {
|
|
c = controller;
|
|
},
|
|
transform() {
|
|
},
|
|
flush() {
|
|
c.enqueue('x');
|
|
c.enqueue('y');
|
|
}
|
|
});
|
|
|
|
const reader = ts.readable.getReader();
|
|
|
|
const writer = ts.writable.getWriter();
|
|
writer.write('a');
|
|
writer.close();
|
|
return reader.read().then(result1 => {
|
|
assert_equals(result1.value, 'x', 'the first chunk read is the first one enqueued in flush');
|
|
assert_equals(result1.done, false, 'the first chunk read is the first one enqueued in flush');
|
|
|
|
return reader.read().then(result2 => {
|
|
assert_equals(result2.value, 'y', 'the second chunk read is the second one enqueued in flush');
|
|
assert_equals(result2.done, false, 'the second chunk read is the second one enqueued in flush');
|
|
});
|
|
});
|
|
}, 'TransformStream flush gets a chance to enqueue more into the readable');
|
|
|
|
promise_test(() => {
|
|
let c;
|
|
const ts = new TransformStream({
|
|
start(controller) {
|
|
c = controller;
|
|
},
|
|
transform() {
|
|
},
|
|
flush() {
|
|
c.enqueue('x');
|
|
c.enqueue('y');
|
|
return delay(0);
|
|
}
|
|
});
|
|
|
|
const reader = ts.readable.getReader();
|
|
|
|
const writer = ts.writable.getWriter();
|
|
writer.write('a');
|
|
writer.close();
|
|
|
|
return Promise.all([
|
|
reader.read().then(result1 => {
|
|
assert_equals(result1.value, 'x', 'the first chunk read is the first one enqueued in flush');
|
|
assert_equals(result1.done, false, 'the first chunk read is the first one enqueued in flush');
|
|
|
|
return reader.read().then(result2 => {
|
|
assert_equals(result2.value, 'y', 'the second chunk read is the second one enqueued in flush');
|
|
assert_equals(result2.done, false, 'the second chunk read is the second one enqueued in flush');
|
|
});
|
|
}),
|
|
reader.closed.then(() => {
|
|
assert_true(true, 'readable reader becomes closed');
|
|
})
|
|
]);
|
|
}, 'TransformStream flush gets a chance to enqueue more into the readable, and can then async close');
|
|
|
|
const error1 = new Error('error1');
|
|
error1.name = 'error1';
|
|
|
|
promise_test(t => {
|
|
const ts = new TransformStream({
|
|
flush(controller) {
|
|
controller.error(error1);
|
|
}
|
|
});
|
|
return promise_rejects_exactly(t, error1, ts.writable.getWriter().close(), 'close() should reject');
|
|
}, 'error() during flush should cause writer.close() to reject');
|
|
|
|
promise_test(async t => {
|
|
let flushed = false;
|
|
const ts = new TransformStream({
|
|
flush() {
|
|
flushed = true;
|
|
},
|
|
cancel: t.unreached_func('cancel should not be called')
|
|
});
|
|
const closePromise = ts.writable.close();
|
|
await delay(0);
|
|
const cancelPromise = ts.readable.cancel(error1);
|
|
await Promise.all([closePromise, cancelPromise]);
|
|
assert_equals(flushed, true, 'transformer.flush() should be called');
|
|
}, 'closing the writable side should call transformer.flush() and a parallel readable.cancel() should not reject');
|