| 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(() => { | |
| 9 | |
| 10 const rs = new ReadableStream(); | |
| 11 const 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 | |
| 18 }, 'ReadableStream teeing: rs.tee() returns an array of two ReadableStreams'); | |
| 19 | |
| 20 promise_test(t => { | |
| 21 | |
| 22 const rs = new ReadableStream({ | |
| 23 start(c) { | |
| 24 c.enqueue('a'); | |
| 25 c.enqueue('b'); | |
| 26 c.close(); | |
| 27 } | |
| 28 }); | |
| 29 | |
| 30 const branch = rs.tee(); | |
| 31 const branch1 = branch[0]; | |
| 32 const branch2 = branch[1]; | |
| 33 const reader1 = branch1.getReader(); | |
| 34 const reader2 = branch2.getReader(); | |
| 35 | |
| 36 reader2.closed.then(t.unreached_func('branch2 should not be closed')); | |
| 37 | |
| 38 return Promise.all([ | |
| 39 reader1.closed, | |
| 40 reader1.read().then(r => { | |
| 41 assert_object_equals(r, { value: 'a', done: false }, 'first chunk from bra
nch1 should be correct'); | |
| 42 }), | |
| 43 reader1.read().then(r => { | |
| 44 assert_object_equals(r, { value: 'b', done: false }, 'second chunk from br
anch1 should be correct'); | |
| 45 }), | |
| 46 reader1.read().then(r => { | |
| 47 assert_object_equals(r, { value: undefined, done: true }, 'third read() fr
om branch1 should be done'); | |
| 48 }), | |
| 49 reader2.read().then(r => { | |
| 50 assert_object_equals(r, { value: 'a', done: false }, 'first chunk from bra
nch2 should be correct'); | |
| 51 }) | |
| 52 ]); | |
| 53 | |
| 54 }, 'ReadableStream teeing: should be able to read one branch to the end without
affecting the other'); | |
| 55 | |
| 56 promise_test(() => { | |
| 57 | |
| 58 const theObject = { the: 'test object' }; | |
| 59 const rs = new ReadableStream({ | |
| 60 start(c) { | |
| 61 c.enqueue(theObject); | |
| 62 } | |
| 63 }); | |
| 64 | |
| 65 const branch = rs.tee(); | |
| 66 const branch1 = branch[0]; | |
| 67 const branch2 = branch[1]; | |
| 68 const reader1 = branch1.getReader(); | |
| 69 const reader2 = branch2.getReader(); | |
| 70 | |
| 71 return Promise.all([reader1.read(), reader2.read()]).then(values => { | |
| 72 assert_object_equals(values[0], values[1], 'the values should be equal'); | |
| 73 }); | |
| 74 | |
| 75 }, 'ReadableStream teeing: values should be equal across each branch'); | |
| 76 | |
| 77 promise_test(t => { | |
| 78 | |
| 79 const theError = { name: 'boo!' }; | |
| 80 const rs = new ReadableStream({ | |
| 81 start(c) { | |
| 82 c.enqueue('a'); | |
| 83 c.enqueue('b'); | |
| 84 }, | |
| 85 pull() { | |
| 86 throw theError; | |
| 87 } | |
| 88 }); | |
| 89 | |
| 90 const branches = rs.tee(); | |
| 91 const reader1 = branches[0].getReader(); | |
| 92 const reader2 = branches[1].getReader(); | |
| 93 | |
| 94 reader1.label = 'reader1'; | |
| 95 reader2.label = 'reader2'; | |
| 96 | |
| 97 return Promise.all([ | |
| 98 promise_rejects(t, theError, reader1.closed), | |
| 99 promise_rejects(t, theError, reader2.closed), | |
| 100 reader1.read().then(r => { | |
| 101 assert_object_equals(r, { value: 'a', done: false }, 'should be able to re
ad the first chunk in branch1'); | |
| 102 }), | |
| 103 reader1.read().then(r => { | |
| 104 assert_object_equals(r, { value: 'b', done: false }, 'should be able to re
ad the second chunk in branch1'); | |
| 105 | |
| 106 return promise_rejects(t, theError, reader2.read()); | |
| 107 }) | |
| 108 .then(() => promise_rejects(t, theError, reader1.read())) | |
| 109 ]); | |
| 110 | |
| 111 }, 'ReadableStream teeing: errors in the source should propagate to both branche
s'); | |
| 112 | |
| 113 promise_test(() => { | |
| 114 | |
| 115 const rs = new ReadableStream({ | |
| 116 start(c) { | |
| 117 c.enqueue('a'); | |
| 118 c.enqueue('b'); | |
| 119 c.close(); | |
| 120 } | |
| 121 }); | |
| 122 | |
| 123 const branches = rs.tee(); | |
| 124 const branch1 = branches[0]; | |
| 125 const branch2 = branches[1]; | |
| 126 branch1.cancel(); | |
| 127 | |
| 128 return Promise.all([ | |
| 129 readableStreamToArray(branch1).then(chunks => { | |
| 130 assert_array_equals(chunks, [], 'branch1 should have no chunks'); | |
| 131 }), | |
| 132 readableStreamToArray(branch2).then(chunks => { | |
| 133 assert_array_equals(chunks, ['a', 'b'], 'branch2 should have two chunks'); | |
| 134 }) | |
| 135 ]); | |
| 136 | |
| 137 }, 'ReadableStream teeing: canceling branch1 should not impact branch2'); | |
| 138 | |
| 139 promise_test(() => { | |
| 140 | |
| 141 const rs = new ReadableStream({ | |
| 142 start(c) { | |
| 143 c.enqueue('a'); | |
| 144 c.enqueue('b'); | |
| 145 c.close(); | |
| 146 } | |
| 147 }); | |
| 148 | |
| 149 const branches = rs.tee(); | |
| 150 const branch1 = branches[0]; | |
| 151 const branch2 = branches[1]; | |
| 152 branch2.cancel(); | |
| 153 | |
| 154 return Promise.all([ | |
| 155 readableStreamToArray(branch1).then(chunks => { | |
| 156 assert_array_equals(chunks, ['a', 'b'], 'branch1 should have two chunks'); | |
| 157 }), | |
| 158 readableStreamToArray(branch2).then(chunks => { | |
| 159 assert_array_equals(chunks, [], 'branch2 should have no chunks'); | |
| 160 }) | |
| 161 ]); | |
| 162 | |
| 163 }, 'ReadableStream teeing: canceling branch2 should not impact branch2'); | |
| 164 | |
| 165 promise_test(() => { | |
| 166 | |
| 167 const reason1 = new Error('We\'re wanted men.'); | |
| 168 const reason2 = new Error('I have the death sentence on twelve systems.'); | |
| 169 | |
| 170 let resolve; | |
| 171 const promise = new Promise(r => resolve = r); | |
| 172 const rs = new ReadableStream({ | |
| 173 cancel(reason) { | |
| 174 assert_array_equals(reason, [reason1, reason2], | |
| 175 'the cancel reason should be an array containing those
from the branches'); | |
| 176 resolve(); | |
| 177 } | |
| 178 }); | |
| 179 | |
| 180 const branch = rs.tee(); | |
| 181 const branch1 = branch[0]; | |
| 182 const branch2 = branch[1]; | |
| 183 branch1.cancel(reason1); | |
| 184 branch2.cancel(reason2); | |
| 185 | |
| 186 return promise; | |
| 187 | |
| 188 }, 'ReadableStream teeing: canceling both branches should aggregate the cancel r
easons into an array'); | |
| 189 | |
| 190 promise_test(t => { | |
| 191 | |
| 192 const theError = { name: 'I\'ll be careful.' }; | |
| 193 const rs = new ReadableStream({ | |
| 194 cancel() { | |
| 195 throw theError; | |
| 196 } | |
| 197 }); | |
| 198 | |
| 199 const branch = rs.tee(); | |
| 200 const branch1 = branch[0]; | |
| 201 const branch2 = branch[1]; | |
| 202 | |
| 203 return Promise.all([ | |
| 204 promise_rejects(t, theError, branch1.cancel()), | |
| 205 promise_rejects(t, theError, branch2.cancel()) | |
| 206 ]); | |
| 207 | |
| 208 }, 'ReadableStream teeing: failing to cancel the original stream should cause ca
ncel() to reject on branches'); | |
| 209 | |
| 210 promise_test(() => { | |
| 211 | |
| 212 let controller; | |
| 213 const rs = new ReadableStream({ | |
| 214 start(c) { | |
| 215 controller = c; | |
| 216 } | |
| 217 }); | |
| 218 | |
| 219 const branches = rs.tee(); | |
| 220 const reader1 = branches[0].getReader(); | |
| 221 const reader2 = branches[1].getReader(); | |
| 222 | |
| 223 const promise = Promise.all([reader1.closed, reader2.closed]); | |
| 224 | |
| 225 controller.close(); | |
| 226 return promise; | |
| 227 | |
| 228 }, 'ReadableStream teeing: closing the original should immediately close the bra
nches'); | |
| 229 | |
| 230 promise_test(t => { | |
| 231 | |
| 232 let controller; | |
| 233 const rs = new ReadableStream({ | |
| 234 start(c) { | |
| 235 controller = c; | |
| 236 } | |
| 237 }); | |
| 238 | |
| 239 const branches = rs.tee(); | |
| 240 const reader1 = branches[0].getReader(); | |
| 241 const reader2 = branches[1].getReader(); | |
| 242 | |
| 243 const theError = { name: 'boo!' }; | |
| 244 const promise = Promise.all([ | |
| 245 promise_rejects(t, theError, reader1.closed), | |
| 246 promise_rejects(t, theError, reader2.closed) | |
| 247 ]); | |
| 248 | |
| 249 controller.error(theError); | |
| 250 return promise; | |
| 251 | |
| 252 }, 'ReadableStream teeing: erroring the original should immediately error the br
anches'); | |
| 253 | |
| 254 done(); | |
| OLD | NEW |