blob: 0120b81b6054ac906ceb4f2441b776e439480c60 [file] [log] [blame]
<!DOCTYPE html>
<script src='../../resources/testharness.js'></script>
<script src='../../resources/testharnessreport.js'></script>
<script src='resources/streams-utils.js'></script>
<script>
// This is updated till https://github.com/whatwg/streams/commit/4ba861e6f60c248060811830e11271c84b439cc3
var test1 = async_test('Aborting a WritableStream immediately prevents future writes');
test1.step(function() {
var chunks = [];
var ws = new WritableStream({
write: function(chunk) {
chunks.push(chunk);
}
});
setTimeout(test1.step_func(function() {
ws.abort();
ws.write(1);
ws.write(2);
assert_array_equals(chunks, [], 'no chunks are written');
test1.done();
}), 0);
});
var test2 = async_test('Aborting a WritableStream prevents further writes after any that are in progress');
test2.step(function() {
var chunks = [];
var ws = new WritableStream({
write: function(chunk) {
chunks.push(chunk);
return new Promise(test2.step_func(function(resolve) { setTimeout(test2.step_func(function() { resolve(); }), 200); }));
}
});
setTimeout(test2.step_func(function() {
ws.write(1);
ws.write(2);
ws.write(3);
ws.abort();
ws.write(4);
ws.write(5);
setTimeout(test2.step_func(function () {
assert_array_equals(chunks, [1], 'only the single in-progress chunk gets written');
test2.done();
}), 500);
}), 0);
});
var test3 = async_test('Fulfillment value of ws.abort() call must be undefined even if the underlying sink returns a non-undefined value');
test3.step(function() {
var ws = new WritableStream({
abort: function() {
return 'Hello';
}
});
var abortPromise = ws.abort('a');
abortPromise.then(test3.step_func(function(value) {
assert_equals(value, undefined, 'fulfillment value must be undefined');
test3.done();
})).catch(test3.step_func(function() { assert_unreached('abortPromise is rejected'); }));
});
var test4 = async_test('WritableStream if sink\'s abort throws, the promise returned by ws.abort() rejects');
test4.step(function() {
var errorInSinkAbort = new Error('Sorry, it just wasn\'t meant to be.');
var ws = new WritableStream({
abort: function() {
throw errorInSinkAbort;
}
});
var abortPromise = ws.abort(undefined);
abortPromise.then(
test4.step_func(function() { assert_unreached('abortPromise is fulfilled unexpectedly'); }),
test4.step_func(function(r) {
assert_equals(r, errorInSinkAbort, 'rejection reason of abortPromise must be errorInSinkAbort');
test4.done();
})
);
});
test(function() {
var recordedReason;
var ws = new WritableStream({
abort: function(reason) {
recordedReason = reason;
}
});
var passedReason = new Error('Sorry, it just wasn\'t meant to be.');
ws.abort(passedReason);
assert_equals(recordedReason, passedReason);
}, 'Aborting a WritableStream passes through the given reason');
var test5 = async_test('Aborting a WritableStream puts it in an errored state, with stored error equal to the abort reason');
test5.step(function() {
var events = 0;
var recordedReason;
var ws = new WritableStream();
var passedReason = new Error('Sorry, it just wasn\'t meant to be.');
ws.abort(passedReason);
assert_equals(ws.state, 'errored', 'state should be errored');
ws.write().then(
test5.step_func(function() { assert_unreached('writing should not succeed'); }),
test5.step_func(function(r) {
assert_equals(r, passedReason, 'writing should reject with the given reason');
assert_equals(++events, 1);
})
);
ws.close().then(
test5.step_func(function() { assert_unreached('closing should not succeed'); }),
test5.step_func(function(r) {
assert_equals(r, passedReason, 'closing should reject with the given reason');
assert_equals(++events, 2);
})
);
ws.abort().then(
test5.step_func(function() { assert_unreached('aborting a second time should not succeed'); }),
test5.step_func(function(r) {
assert_equals(r, passedReason, 'aborting a second time should reject with the given reason');
assert_equals(++events, 3);
})
);
ws.closed.then(
test5.step_func(function() { assert_unreached('closed promise should not be fulfilled'); }),
test5.step_func(function(r) {
assert_equals(r, passedReason, 'closed promise should be rejected with the given reason');
assert_equals(++events, 4);
test5.done();
})
);
});
var test6 = async_test('Aborting a WritableStream causes any outstanding ready promises to be fulfilled immediately');
test6.step(function() {
var writeCalled = false;
var recordedReason;
var ws = new WritableStream({
write: function(chunk) {
writeCalled = true;
return new Promise(test6.step_func(function() { })); // forever-pending, so normally .ready would not fulfill.
}
});
ws.write('a');
assert_equals(ws.state, 'waiting', 'state should be waiting');
ws.ready.then(test6.step_func(function() {
assert_equals(ws.state, 'errored', 'state should now be errored');
assert_false(writeCalled);
test6.done();
}));
var passedReason = new Error('Sorry, it just wasn\'t meant to be.');
ws.abort(passedReason);
});
var test7 = async_test('Aborting a WritableStream causes any outstanding write() promises to be rejected with the abort reason');
test7.step(function() {
var ws = new WritableStream();
ws.write('a').then(
test7.step_func(function() { assert_unreached('writing should not succeed'); }),
test7.step_func(function(r) {
assert_equals(r, passedReason, 'writing should reject with the given reason');
test7.done();
})
);
var passedReason = new Error('Sorry, it just wasn\'t meant to be.');
ws.abort(passedReason);
});
var test8 = async_test('Closing but then immediately aborting a WritableStream causes the stream to error');
test8.step(function() {
var ws = new WritableStream();
ws.close();
var passedReason = new Error('Sorry, it just wasn\'t meant to be.');
ws.abort(passedReason);
assert_equals(ws.state, 'errored');
ws.closed.then(
test8.step_func(function() { assert_unreached('the stream should not close successfully'); }),
test8.step_func(function(r) {
assert_equals(r, passedReason, 'the stream should be errored with the given reason');
test8.done();
})
);
});
var test9 = async_test('Closing a WritableStream and aborting it while it closes causes the stream to error');
test9.step(function() {
var ws = new WritableStream({
close: function() {
return new Promise(test9.step_func(function() { })); // forever-pending
}
});
ws.close();
var passedReason = new Error('Sorry, it just wasn\'t meant to be.');
setTimeout(test9.step_func(function() {
assert_equals(ws.state, 'closing');
ws.abort(passedReason);
assert_equals(ws.state, 'errored');
}), 200);
ws.closed.then(
test9.step_func(function() { assert_unreached('the stream should not close successfully'); }),
test9.step_func(function(r) {
assert_equals(r, passedReason, 'the stream should be errored with the given reason');
test9.done();
})
);
});
var test10 = async_test('Aborting a WritableStream after it is closed is a no-op');
test10.step(function() {
var ws = new WritableStream();
ws.close();
setTimeout(test10.step_func(function() {
assert_equals(ws.state, 'closed');
ws.abort().then(
test10.step_func(function(v) {
assert_equals(v, undefined, 'abort promise should fulfill with undefined');
test10.done();
}),
test10.step_func(assert_unreached)
);
assert_equals(ws.state, 'closed', 'state stays closed');
}), 0);
});
var test11 = async_test('WritableStream should call underlying sink\'s close if no abort is supplied');
test11.step(function() {
var ws = new WritableStream({
close: function() {
assert_equals(arguments.length, 0, 'close() was called (with no arguments)');
test11.done();
}
});
ws.abort();
});
</script>