| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 'use strict'; | 
|  | 2 | 
|  | 3 if (self.importScripts) { | 
|  | 4   self.importScripts('../resources/rs-utils.js'); | 
|  | 5   self.importScripts('/resources/testharness.js'); | 
|  | 6 } | 
|  | 7 | 
|  | 8 test(function() { | 
|  | 9     var rs = new ReadableStream(); | 
|  | 10 | 
|  | 11     var result = rs.tee(); | 
|  | 12 | 
|  | 13     assert_true(Array.isArray(result), 'return value should be an array'); | 
|  | 14     assert_equals(result.length, 2, 'array should have length 2'); | 
|  | 15     assert_equals(result[0].constructor, ReadableStream, '0th element should be 
     a ReadableStream'); | 
|  | 16     assert_equals(result[1].constructor, ReadableStream, '1st element should be 
     a ReadableStream'); | 
|  | 17 }, 'ReadableStream teeing: rs.tee() returns an array of two ReadableStreams'); | 
|  | 18 | 
|  | 19 var test1 = async_test('ReadableStream teeing: should be able to read one branch
      to the end without affecting the other'); | 
|  | 20 test1.step(function() { | 
|  | 21     var readCalls = 0; | 
|  | 22     var rs = new ReadableStream({ | 
|  | 23         start: function(c) { | 
|  | 24             c.enqueue('a'); | 
|  | 25             c.enqueue('b'); | 
|  | 26             c.close(); | 
|  | 27         } | 
|  | 28     }); | 
|  | 29 | 
|  | 30     var branch = rs.tee(); | 
|  | 31     var branch1 = branch[0]; | 
|  | 32     var branch2 = branch[1]; | 
|  | 33     var reader1 = branch1.getReader(); | 
|  | 34     var reader2 = branch2.getReader(); | 
|  | 35 | 
|  | 36     reader1.closed.then(test1.step_func(function() { | 
|  | 37         assert_equals(readCalls, 4); | 
|  | 38         test1.done(); | 
|  | 39     })).catch(test1.step_func(function(e) { assert_unreached(e); })); | 
|  | 40     reader2.closed.then(test1.step_func(function() { assert_unreached('branch2 s
     hould not be closed'); })); | 
|  | 41 | 
|  | 42     reader1.read().then(test1.step_func(function(r) { | 
|  | 43         assert_object_equals(r, { value: 'a', done: false }, 'first chunk from b
     ranch1 should be correct'); | 
|  | 44         ++readCalls; | 
|  | 45     })); | 
|  | 46     reader1.read().then(test1.step_func(function(r) { | 
|  | 47         assert_object_equals(r, { value: 'b', done: false }, 'second chunk from 
     branch1 should be correct'); | 
|  | 48         ++readCalls; | 
|  | 49     })); | 
|  | 50     reader1.read().then(test1.step_func(function(r) { | 
|  | 51         assert_object_equals(r, { value: undefined, done: true }, 'third read() 
     from branch1 should be done'); | 
|  | 52         ++readCalls; | 
|  | 53     })); | 
|  | 54 | 
|  | 55     reader2.read().then(test1.step_func(function(r) { | 
|  | 56         assert_object_equals(r, { value: 'a', done: false }, 'first chunk from b
     ranch2 should be correct'); | 
|  | 57         ++readCalls; | 
|  | 58     })); | 
|  | 59 }); | 
|  | 60 | 
|  | 61 var test2 = async_test('ReadableStream teeing: values should be equal across eac
     h branch'); | 
|  | 62 test2.step(function() { | 
|  | 63     var theObject = { the: 'test object' }; | 
|  | 64     var rs = new ReadableStream({ | 
|  | 65         start: function(c) { | 
|  | 66             c.enqueue(theObject); | 
|  | 67         } | 
|  | 68     }); | 
|  | 69 | 
|  | 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(); | 
|  | 75 | 
|  | 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')
     ; | 
|  | 78         test2.done(); | 
|  | 79     })); | 
|  | 80 }); | 
|  | 81 | 
|  | 82 var test3 = async_test('ReadableStream teeing: errors in the source should propa
     gate to both branches'); | 
|  | 83 test3.step(function() { | 
|  | 84     var closedRejects = 0; | 
|  | 85     var readCalls = 0; | 
|  | 86     var readRejects = 0; | 
|  | 87     var theError = new Error('boo!'); | 
|  | 88     var rs = new ReadableStream({ | 
|  | 89         start: function(c) { | 
|  | 90             c.enqueue('a'); | 
|  | 91             c.enqueue('b'); | 
|  | 92         }, | 
|  | 93         pull: function() { | 
|  | 94             throw theError; | 
|  | 95         } | 
|  | 96     }); | 
|  | 97 | 
|  | 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(); | 
|  | 103 | 
|  | 104     reader1.label = 'reader1'; | 
|  | 105     reader2.label = 'reader2'; | 
|  | 106 | 
|  | 107     reader1.closed.catch(test3.step_func(function(e) { | 
|  | 108         ++closedRejects; | 
|  | 109         assert_equals(e, theError, 'branch1 closed promise should reject with th
     e error'); | 
|  | 110     })); | 
|  | 111     reader2.closed.catch(test3.step_func(function(e) { | 
|  | 112         ++closedRejects; | 
|  | 113         assert_equals(e, theError, 'branch2 closed promise should reject with th
     e error'); | 
|  | 114     })); | 
|  | 115 | 
|  | 116     reader1.read().then(test3.step_func(function(r) { | 
|  | 117         ++readCalls; | 
|  | 118         assert_object_equals(r, { value: 'a', done: false }, 'should be able to 
     read the first chunk in branch1'); | 
|  | 119     })); | 
|  | 120 | 
|  | 121     reader1.read().then(test3.step_func(function(r) { | 
|  | 122         ++readCalls; | 
|  | 123         assert_object_equals(r, { value: 'b', done: false }, 'should be able to 
     read the second chunk in branch1'); | 
|  | 124 | 
|  | 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) { | 
|  | 128                 ++readRejects; | 
|  | 129                 assert_equals(e, theError, 'branch2 read() promise should reject
      with the error'); | 
|  | 130             })); | 
|  | 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'); | 
|  | 139                 test3.done(); | 
|  | 140             }) | 
|  | 141         ); | 
|  | 142     })).catch(test3.step_func(function(e) { assert_unreached(e); })); | 
|  | 143 }); | 
|  | 144 | 
|  | 145 var test4 = async_test('ReadableStream teeing: canceling branch1 should not impa
     ct branch2'); | 
|  | 146 test4.step(function() { | 
|  | 147     var branch1Read = false; | 
|  | 148     var rs = new ReadableStream({ | 
|  | 149         start: function(c) { | 
|  | 150             c.enqueue('a'); | 
|  | 151             c.enqueue('b'); | 
|  | 152             c.close(); | 
|  | 153         } | 
|  | 154     }); | 
|  | 155 | 
|  | 156     var branch = rs.tee(); | 
|  | 157     var branch1 = branch[0]; | 
|  | 158     var branch2 = branch[1]; | 
|  | 159     branch1.cancel(); | 
|  | 160 | 
|  | 161     readableStreamToArray(branch1).then(test4.step_func(function(chunks) { | 
|  | 162         assert_array_equals(chunks, [], 'branch1 should have no chunks'); | 
|  | 163         branch1Read = true; | 
|  | 164     })); | 
|  | 165 | 
|  | 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); | 
|  | 169         test4.done(); | 
|  | 170     })); | 
|  | 171 }); | 
|  | 172 | 
|  | 173 var test5 = async_test('ReadableStream teeing: canceling branch2 should not impa
     ct branch1'); | 
|  | 174 test5.step(function() { | 
|  | 175     var branch2Read = false; | 
|  | 176     var rs = new ReadableStream({ | 
|  | 177         start: function(c) { | 
|  | 178             c.enqueue('a'); | 
|  | 179             c.enqueue('b'); | 
|  | 180             c.close(); | 
|  | 181         } | 
|  | 182     }); | 
|  | 183 | 
|  | 184     var branch = rs.tee(); | 
|  | 185     var branch1 = branch[0]; | 
|  | 186     var branch2 = branch[1]; | 
|  | 187     branch2.cancel(); | 
|  | 188 | 
|  | 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); | 
|  | 192         test5.done(); | 
|  | 193     })); | 
|  | 194     readableStreamToArray(branch2).then(test5.step_func(function(chunks) { | 
|  | 195         assert_array_equals(chunks, [], 'branch2 should have no chunks'); | 
|  | 196         branch2Read = true; | 
|  | 197     })); | 
|  | 198 }); | 
|  | 199 | 
|  | 200 var test6 = async_test('ReadableStream teeing: canceling both branches should ag
     gregate 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.'); | 
|  | 204 | 
|  | 205     var rs = new ReadableStream({ | 
|  | 206         cancel: function(reason) { | 
|  | 207             assert_array_equals(reason, [reason1, reason2], 'the cancel reason s
     hould be an array containing those from the branches'); | 
|  | 208             test6.done(); | 
|  | 209         } | 
|  | 210     }); | 
|  | 211 | 
|  | 212     var branch = rs.tee(); | 
|  | 213     var branch1 = branch[0]; | 
|  | 214     var branch2 = branch[1]; | 
|  | 215     branch1.cancel(reason1); | 
|  | 216     branch2.cancel(reason2); | 
|  | 217 }); | 
|  | 218 | 
|  | 219 var test7 = async_test('ReadableStream teeing: failing to cancel the original st
     ream 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({ | 
|  | 224         cancel: function() { | 
|  | 225             throw theError; | 
|  | 226         } | 
|  | 227     }); | 
|  | 228 | 
|  | 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 erro
     r'); | 
|  | 234         cancelRejected = true; | 
|  | 235     })); | 
|  | 236     branch2.cancel().catch(test7.step_func(function(e) { | 
|  | 237         assert_equals(e, theError, 'branch2.cancel() should reject with the erro
     r'); | 
|  | 238         assert_true(cancelRejected); | 
|  | 239         test7.done(); | 
|  | 240     })); | 
|  | 241 }); | 
|  | 242 | 
|  | 243 var test8 = async_test('ReadableStream teeing: closing the original should immed
     iately close the branches'); | 
|  | 244 test8.step(function() { | 
|  | 245     var reader1Closed = false; | 
|  | 246     var controller; | 
|  | 247     var rs = new ReadableStream({ | 
|  | 248         start: function(c) { | 
|  | 249             controller = c; | 
|  | 250         } | 
|  | 251     }); | 
|  | 252 | 
|  | 253     var branch = rs.tee(); | 
|  | 254     var branch1 = branch[0]; | 
|  | 255     var branch2 = branch[1]; | 
|  | 256     var reader1 = branch1.getReader(); | 
|  | 257     var reader2 = branch2.getReader(); | 
|  | 258 | 
|  | 259     reader1.closed.then(test8.step_func(function() { | 
|  | 260         reader1Closed = true; //branch1 should be closed | 
|  | 261     })).catch(test8.step_func(function(e) { assert_unreached(e); })); | 
|  | 262     reader2.closed.then(test8.step_func(function() { | 
|  | 263         assert_true(reader1Closed); | 
|  | 264         test8.done('branch2 should be closed'); | 
|  | 265     })).catch(test8.step_func(function(e) { assert_unreached(e); })); | 
|  | 266 | 
|  | 267     controller.close(); | 
|  | 268 }); | 
|  | 269 | 
|  | 270 var test9 = async_test('ReadableStream teeing: erroring the original should imme
     diately error the branches'); | 
|  | 271 test9.step(function() { | 
|  | 272     var reader1Rejected = false; | 
|  | 273     var controller; | 
|  | 274     var rs = new ReadableStream({ | 
|  | 275         start(c) { | 
|  | 276             controller = c; | 
|  | 277         } | 
|  | 278     }); | 
|  | 279 | 
|  | 280     var branch = rs.tee(); | 
|  | 281     var branch1 = branch[0]; | 
|  | 282     var branch2 = branch[1]; | 
|  | 283     var reader1 = branch1.getReader(); | 
|  | 284     var reader2 = branch2.getReader(); | 
|  | 285 | 
|  | 286     var theError = new Error('boo!'); | 
|  | 287 | 
|  | 288     reader1.closed.then( | 
|  | 289         test9.step_func(function() { assert_unreached('branch1 should not be clo
     sed'); }), | 
|  | 290         test9.step_func(function(e) { | 
|  | 291             assert_equals(e, theError, 'branch1 should be errored with the error
     '); | 
|  | 292             reader1Rejected = true; | 
|  | 293         }) | 
|  | 294     ); | 
|  | 295     reader2.closed.then( | 
|  | 296         test9.step_func(function() { assert_unreached('branch2 should not be clo
     sed'); }), | 
|  | 297         test9.step_func(function(e) { | 
|  | 298             assert_equals(e, theError, 'branch2 should be errored with the error
     '); | 
|  | 299             assert_true(reader1Rejected); | 
|  | 300             test9.done(); | 
|  | 301         }) | 
|  | 302     ); | 
|  | 303 | 
|  | 304     controller.error(theError); | 
|  | 305 }); | 
|  | 306 | 
|  | 307 done(); | 
| OLD | NEW | 
|---|