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 |