| <!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> |