2 <script src='../../resources/testharness.js'></script>
3 <script src='../../resources/testharnessreport.js'></script>
4 <script src='resources/streams-utils.js'></script>
7 var rs = new ReadableStream();
11 assert_true(Array.isArray(result), 'return value should be an array');
12 assert_equals(result.length, 2, 'array should have length 2');
13 assert_equals(result[0].constructor, ReadableStream, '0th element should be a ReadableStream');
14 assert_equals(result[1].constructor, ReadableStream, '1st element should be a ReadableStream');
15 }, 'ReadableStream teeing: rs.tee() returns an array of two ReadableStreams');
17 var test1 = async_test('ReadableStream teeing: should be able to read one branch to the end without affecting the other');
18 test1.step(function() {
19 var closedCalled = false;
21 const rs = new ReadableStream({
29 var branch = rs.tee();
30 var branch1 = branch[0];
31 var branch2 = branch[1];
32 var reader1 = branch1.getReader();
33 var reader2 = branch2.getReader();
35 reader1.closed.then(test1.step_func(function() {
37 })).catch(test1.step_func(function(e) { assert_unreached(e); }));
38 reader2.closed.then(test1.step_func(function() { assert_unreached('branch2 should not be closed'); }));
40 reader1.read().then(test1.step_func(function(r) {
41 assert_object_equals(r, { value: 'a', done: false }, 'first chunk from branch1 should be correct');
44 reader1.read().then(test1.step_func(function(r) {
45 assert_object_equals(r, { value: 'b', done: false }, 'second chunk from branch1 should be correct');
48 reader1.read().then(test1.step_func(function(r) {
49 assert_object_equals(r, { value: undefined, done: true }, 'third read() from branch1 should be done');
50 assert_true(closedCalled);
51 assert_equals(++readCalls, 4);
55 reader2.read().then(test1.step_func(function(r) {
56 assert_object_equals(r, { value: 'a', done: false }, 'first chunk from branch2 should be correct');
61 var test2 = async_test('ReadableStream teeing: values should be equal across each branch');
62 test2.step(function() {
63 var theObject = { the: 'test object' };
64 var rs = new ReadableStream({
70 var branch = rs.tee();
71 var branch1 = branch[0];
72 var branch2 = branch[1];
73 var reader1 = branch1.getReader();
74 var reader2 = branch2.getReader();
76 Promise.all([reader1.read(), reader2.read()]).then(test2.step_func(function(values) {
77 assert_object_equals(values[0], values[1], 'the values should be equal');
82 var test3 = async_test('ReadableStream teeing: errors in the source should propagate to both branches');
83 test3.step(function() {
84 var closedRejects = 0;
87 var theError = new Error('boo!');
88 var rs = new ReadableStream({
98 var branch = rs.tee();
99 var branch1 = branch[0];
100 var branch2 = branch[1];
101 var reader1 = branch1.getReader();
102 var reader2 = branch2.getReader();
104 reader1.label = 'reader1';
105 reader2.label = 'reader2';
107 reader1.closed.catch(test3.step_func(function(e) {
109 assert_equals(e, theError, 'branch1 closed promise should reject with the error');
111 reader2.closed.catch(test3.step_func(function(e) {
113 assert_equals(e, theError, 'branch2 closed promise should reject with the error');
116 reader1.read().then(test3.step_func(function(r) {
118 assert_object_equals(r, { value: 'a', done: false }, 'should be able to read the first chunk in branch1');
121 reader1.read().then(test3.step_func(function(r) {
123 assert_object_equals(r, { value: 'b', done: false }, 'should be able to read the second chunk in branch1');
125 return reader2.read().then(
126 test3.step_func(function() { assert_unreached('once the root stream has errored, you should not be able to read from branch2'); }),
127 test3.step_func(function(e) {
129 assert_equals(e, theError, 'branch2 read() promise should reject with the error');
131 })).then(test3.step_func(function() {
132 return reader1.read().then(
133 test3.step_func(function() { assert_unreached('once the root stream has errored, you should not be able to read from branch1 either'); }),
134 test3.step_func(function(e) {
135 assert_equals(closedRejects, 2);
136 assert_equals(readCalls, 2);
137 assert_equals(++readRejects, 2);
138 assert_equals(e, theError, 'branch1 read() promise should reject with the error');
142 })).catch(test3.step_func(function(e) { assert_unreached(e); }));
145 var test4 = async_test('ReadableStream teeing: canceling branch1 should not impact branch2');
146 test4.step(function() {
147 var branch1Read = false;
148 var rs = new ReadableStream({
156 var branch = rs.tee();
157 var branch1 = branch[0];
158 var branch2 = branch[1];
161 readableStreamToArray(branch1).then(test4.step_func(function(chunks) {
162 assert_array_equals(chunks, [], 'branch1 should have no chunks');
166 readableStreamToArray(branch2).then(test4.step_func(function(chunks) {
167 assert_array_equals(chunks, ['a', 'b'], 'branch2 should have two chunks');
168 assert_true(branch1Read);
173 var test5 = async_test('ReadableStream teeing: canceling branch2 should not impact branch1');
174 test5.step(function() {
175 var branch2Read = false;
176 var rs = new ReadableStream({
184 var branch = rs.tee();
185 var branch1 = branch[0];
186 var branch2 = branch[1];
189 readableStreamToArray(branch1).then(test5.step_func(function(chunks) {
190 assert_array_equals(chunks, ['a', 'b'], 'branch1 should have two chunks');
191 assert_true(branch2Read);
194 readableStreamToArray(branch2).then(test5.step_func(function(chunks) {
195 assert_array_equals(chunks, [], 'branch2 should have no chunks');
200 var test6 = async_test('ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array');
201 test6.step(function() {
202 var reason1 = new Error('We\'re wanted men.');
203 var reason2 = new Error('I have the death sentence on twelve systems.');
205 var rs = new ReadableStream({
206 cancel: test6.step_func(function(reason) {
207 assert_array_equals(reason, [reason1, reason2], 'the cancel reason should be an array containing those from the branches');
212 var branch = rs.tee();
213 var branch1 = branch[0];
214 var branch2 = branch[1];
215 branch1.cancel(reason1);
216 branch2.cancel(reason2);
219 var test7 = async_test('ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches');
220 test7.step(function() {
221 var cancelRejected = false;
222 var theError = new Error('I\'ll be careful.');
223 var rs = new ReadableStream({
229 var branch = rs.tee();
230 var branch1 = branch[0];
231 var branch2 = branch[1];
232 branch1.cancel().catch(test7.step_func(function(e) {
233 assert_equals(e, theError, 'branch1.cancel() should reject with the error');
234 cancelRejected = true;
237 branch2.cancel().catch(test7.step_func(function(e) {
238 assert_equals(e, theError, 'branch2.cancel() should reject with the error');
239 assert_true(cancelRejected);
244 var test8 = async_test('ReadableStream teeing: closing the original should immediately close the branches');
245 test8.step(function() {
246 var reader1Closed = false;
248 var rs = new ReadableStream({
254 var branch = rs.tee();
255 var branch1 = branch[0];
256 var branch2 = branch[1];
257 var reader1 = branch1.getReader();
258 var reader2 = branch2.getReader();
260 reader1.closed.then(test8.step_func(function() {
261 reader1Closed = true; //branch1 should be closed
262 })).catch(test8.step_func(function(e) { assert_unreached(e); }));
263 reader2.closed.then(test8.step_func(function() {
264 assert_true(reader1Closed);
265 test8.done('branch2 should be closed');
266 })).catch(test8.step_func(function(e) { assert_unreached(e); }));
271 var test9 = async_test('ReadableStream teeing: erroring the original should immediately error the branches');
272 test9.step(function() {
273 var reader1Rejected = false;
275 var rs = new ReadableStream({
281 var branch = rs.tee();
282 var branch1 = branch[0];
283 var branch2 = branch[1];
284 var reader1 = branch1.getReader();
285 var reader2 = branch2.getReader();
287 var theError = new Error('boo!');
290 test9.step_func(function() { assert_unreached('branch1 should not be closed'); }),
291 test9.step_func(function(e) {
292 assert_equals(e, theError, 'branch1 should be errored with the error');
293 reader1Rejected = true;
297 test9.step_func(function() { assert_unreached('branch2 should not be closed'); }),
298 test9.step_func(function(e) {
299 assert_equals(e, theError, 'branch2 should be errored with the error');
300 assert_true(reader1Rejected);
305 controller.error(theError);