| <!DOCTYPE html> |
| <script src='../resources/testharness.js'></script> |
| <script src='../resources/testharnessreport.js'></script> |
| <script src='reference-implementation/resources/streams-utils.js'></script> |
| <script> |
| // This is updated till https://github.com/whatwg/streams/commit/4ba861e6f60c248060811830e11271c84b439cc3 |
| |
| // This test is alone here for timing reasons though it should be at streams/reference-implementation/pipe-to.html. |
| var test24 = async_test('Piping to a writable stream that does not consume the writes fast enough exerts backpressure on the source'); |
| test24.step(function() { |
| const timeoutMultiplier = 15; |
| var desiredSizes = []; |
| var rs = new ReadableStream({ |
| start: function(c) { |
| setTimeout(test24.step_func(function() { enqueue('a'); }), 100 * timeoutMultiplier); |
| setTimeout(test24.step_func(function() { enqueue('b'); }), 200 * timeoutMultiplier); |
| setTimeout(test24.step_func(function() { enqueue('c'); }), 300 * timeoutMultiplier); |
| setTimeout(test24.step_func(function() { enqueue('d'); }), 400 * timeoutMultiplier); |
| setTimeout(test24.step_func(function() { c.close(); }), 500 * timeoutMultiplier); |
| |
| function enqueue(chunk) { |
| c.enqueue(chunk); |
| desiredSizes.push(c.desiredSize); |
| } |
| } |
| }); |
| |
| var chunksGivenToWrite = []; |
| var chunksFinishedWriting = []; |
| var startPromise = Promise.resolve(); |
| var ws = new WritableStream({ |
| start: function() { |
| return startPromise; |
| }, |
| write: function(chunk) { |
| chunksGivenToWrite.push(chunk); |
| return new Promise(test24.step_func(function(resolve) { |
| setTimeout(test24.step_func(function() { |
| chunksFinishedWriting.push(chunk); |
| resolve(); |
| }), 350 * timeoutMultiplier); |
| })); |
| } |
| }); |
| |
| startPromise.then(test24.step_func(function() { |
| rs.pipeTo(ws).then(test24.step_func(function() { |
| assert_array_equals(desiredSizes, [1, 1, 0, -1], 'backpressure was correctly exerted at the source'); |
| assert_array_equals(chunksFinishedWriting, ['a', 'b', 'c', 'd'], 'all chunks were written'); |
| test24.done(); |
| })); |
| |
| assert_equals(ws.state, 'writable', 'at t = 0 ms, ws should be writable'); |
| |
| setTimeout(test24.step_func(function() { |
| assert_equals(ws.state, 'waiting', 'at t = 125 ms, ws should be waiting'); |
| assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 125 ms, ws.write should have been called with one chunk'); |
| assert_array_equals(chunksFinishedWriting, [], 'at t = 125 ms, no chunks should have finished writing'); |
| |
| // When 'a' (the very first chunk) was enqueued, it was immediately used to fulfill the outstanding read request |
| // promise, leaving room in the queue |
| assert_array_equals(desiredSizes, [1], 'at t = 125 ms, the one enqueued chunk in rs did not cause backpressure'); |
| }), 125 * timeoutMultiplier); |
| |
| setTimeout(test24.step_func(function() { |
| assert_equals(ws.state, 'waiting', 'at t = 225 ms, ws should be waiting'); |
| assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 225 ms, ws.write should have been called with one chunk'); |
| assert_array_equals(chunksFinishedWriting, [], 'at t = 225 ms, no chunks should have finished writing'); |
| |
| // When 'b' was enqueued at 200 ms, the queue was also empty, since immediately after enqueuing 'a' at |
| // t = 100 ms, it was dequeued in order to fulfill the read() call that was made at time t = 0. |
| assert_array_equals(desiredSizes, [1, 1], 'at t = 225 ms, the two enqueued chunks in rs did not cause backpressure'); |
| }), 225 * timeoutMultiplier); |
| |
| setTimeout(test24.step_func(function() { |
| assert_equals(ws.state, 'waiting', 'at t = 325 ms, ws should be waiting'); |
| assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 325 ms, ws.write should have been called with one chunk'); |
| assert_array_equals(chunksFinishedWriting, [], 'at t = 325 ms, no chunks should have finished writing'); |
| |
| // When 'c' was enqueued at 300 ms, the queue was again empty, since at time t = 200 ms when 'b' was enqueued, |
| // it was immediately dequeued in order to fulfill the second read() call that was made at time t = 0. |
| // However, this time there was no pending read request to whisk it away, so after the enqueue desired size is 0. |
| assert_array_equals(desiredSizes, [1, 1, 0], 'at t = 325 ms, the three enqueued chunks in rs did not cause backpressure'); |
| }), 325 * timeoutMultiplier); |
| |
| setTimeout(test24.step_func(function() { |
| assert_equals(ws.state, 'waiting', 'at t = 425 ms, ws should be waiting'); |
| assert_array_equals(chunksGivenToWrite, ['a'], 'at t = 425 ms, ws.write should have been called with one chunk'); |
| assert_array_equals(chunksFinishedWriting, [], 'at t = 425 ms, no chunks should have finished writing'); |
| |
| // When 'd' was enqueued at 400 ms, the queue was *not* empty. 'c' was still in it, since the write() of 'b' will |
| // not finish until t = 100 ms + 350 ms = 450 ms. Thus backpressure should have been exerted. |
| assert_array_equals(desiredSizes, [1, 1, 0, -1], 'at t = 425 ms, the fourth enqueued chunks in rs did cause backpressure'); |
| }), 425 * timeoutMultiplier); |
| |
| setTimeout(test24.step_func(function() { |
| assert_equals(ws.state, 'waiting', 'at t = 475 ms, ws should be waiting'); |
| assert_array_equals(chunksGivenToWrite, ['a', 'b'], 'at t = 475 ms, ws.write should have been called with two chunks'); |
| assert_array_equals(chunksFinishedWriting, ['a'], 'at t = 475 ms, one chunk should have finished writing'); |
| }), 475 * timeoutMultiplier); |
| })); |
| }); |
| </script> |