| OLD | NEW |
| (Empty) |
| 1 'use strict'; | |
| 2 | |
| 3 if (self.importScripts) { | |
| 4 self.importScripts('../resources/test-utils.js'); | |
| 5 self.importScripts('../resources/rs-utils.js'); | |
| 6 self.importScripts('/resources/testharness.js'); | |
| 7 } | |
| 8 | |
| 9 promise_test(() => { | |
| 10 | |
| 11 const randomSource = new RandomPushSource(); | |
| 12 | |
| 13 let cancellationFinished = false; | |
| 14 const rs = new ReadableStream({ | |
| 15 start(c) { | |
| 16 randomSource.ondata = c.enqueue.bind(c); | |
| 17 randomSource.onend = c.close.bind(c); | |
| 18 randomSource.onerror = c.error.bind(c); | |
| 19 }, | |
| 20 | |
| 21 pull() { | |
| 22 randomSource.readStart(); | |
| 23 }, | |
| 24 | |
| 25 cancel() { | |
| 26 randomSource.readStop(); | |
| 27 | |
| 28 return new Promise(resolve => { | |
| 29 setTimeout(() => { | |
| 30 cancellationFinished = true; | |
| 31 resolve(); | |
| 32 }, 1); | |
| 33 }); | |
| 34 } | |
| 35 }); | |
| 36 | |
| 37 const reader = rs.getReader(); | |
| 38 | |
| 39 // We call delay multiple times to avoid cancelling too early for the | |
| 40 // source to enqueue at least one chunk. | |
| 41 const cancel = delay(5).then(() => delay(5)).then(() => delay(5)).then(() => { | |
| 42 let cancelPromise = reader.cancel(); | |
| 43 assert_false(cancellationFinished, 'cancellation in source should happen lat
er'); | |
| 44 return cancelPromise; | |
| 45 }) | |
| 46 | |
| 47 return readableStreamToArray(rs, reader).then(chunks => { | |
| 48 assert_greater_than(chunks.length, 0, 'at least one chunk should be read'); | |
| 49 for (let i = 0; i < chunks.length; i++) { | |
| 50 assert_equals(chunks[i].length, 128, 'chunk ' + i + ' should have 128 byte
s'); | |
| 51 } | |
| 52 return cancel; | |
| 53 }).then(() => { | |
| 54 assert_true(cancellationFinished, 'it returns a promise that is fulfilled wh
en the cancellation finishes'); | |
| 55 }); | |
| 56 | |
| 57 }, 'ReadableStream cancellation: integration test on an infinite stream derived
from a random push source'); | |
| 58 | |
| 59 test(() => { | |
| 60 | |
| 61 let recordedReason; | |
| 62 const rs = new ReadableStream({ | |
| 63 cancel(reason) { | |
| 64 recordedReason = reason; | |
| 65 } | |
| 66 }); | |
| 67 | |
| 68 const passedReason = new Error('Sorry, it just wasn\'t meant to be.'); | |
| 69 rs.cancel(passedReason); | |
| 70 | |
| 71 assert_equals(recordedReason, passedReason, | |
| 72 'the error passed to the underlying source\'s cancel method should equal the
one passed to the stream\'s cancel'); | |
| 73 | |
| 74 }, 'ReadableStream cancellation: cancel(reason) should pass through the given re
ason to the underlying source'); | |
| 75 | |
| 76 promise_test(() => { | |
| 77 | |
| 78 const rs = new ReadableStream({ | |
| 79 start(c) { | |
| 80 c.enqueue('a'); | |
| 81 c.close(); | |
| 82 }, | |
| 83 cancel() { | |
| 84 assert_unreached('underlying source cancel() should not have been called')
; | |
| 85 } | |
| 86 }); | |
| 87 | |
| 88 const reader = rs.getReader(); | |
| 89 | |
| 90 return rs.cancel().then(() => { | |
| 91 assert_unreached('cancel() should be rejected'); | |
| 92 }, e => { | |
| 93 assert_equals(e.name, 'TypeError', 'cancel() should be rejected with a TypeE
rror'); | |
| 94 }).then(() => { | |
| 95 return reader.read(); | |
| 96 }).then(result => { | |
| 97 assert_object_equals(result, { value: 'a', done: false }, 'read() should sti
ll work after the attempted cancel'); | |
| 98 return reader.closed; | |
| 99 }); | |
| 100 | |
| 101 }, 'ReadableStream cancellation: cancel() on a locked stream should fail and not
call the underlying source cancel'); | |
| 102 | |
| 103 promise_test(() => { | |
| 104 | |
| 105 let cancelReceived = false; | |
| 106 const cancelReason = new Error('I am tired of this stream, I prefer to cancel
it'); | |
| 107 const rs = new ReadableStream({ | |
| 108 cancel(reason) { | |
| 109 cancelReceived = true; | |
| 110 assert_equals(reason, cancelReason, 'cancellation reason given to the unde
rlying source should be equal to the one passed'); | |
| 111 } | |
| 112 }); | |
| 113 | |
| 114 return rs.cancel(cancelReason).then(() => { | |
| 115 assert_true(cancelReceived); | |
| 116 }); | |
| 117 | |
| 118 }, 'ReadableStream cancellation: should fulfill promise when cancel callback wen
t fine'); | |
| 119 | |
| 120 promise_test(() => { | |
| 121 | |
| 122 const rs = new ReadableStream({ | |
| 123 cancel() { | |
| 124 return 'Hello'; | |
| 125 } | |
| 126 }); | |
| 127 | |
| 128 return rs.cancel().then(v => { | |
| 129 assert_equals(v, undefined, 'cancel() return value should be fulfilled with
undefined'); | |
| 130 }); | |
| 131 | |
| 132 }, 'ReadableStream cancellation: returning a value from the underlying source\'s
cancel should not affect the fulfillment value of the promise returned by the s
tream\'s cancel'); | |
| 133 | |
| 134 promise_test(() => { | |
| 135 | |
| 136 const thrownError = new Error('test'); | |
| 137 let cancelCalled = false; | |
| 138 | |
| 139 const rs = new ReadableStream({ | |
| 140 cancel() { | |
| 141 cancelCalled = true; | |
| 142 throw thrownError; | |
| 143 } | |
| 144 }); | |
| 145 | |
| 146 return rs.cancel('test').then(() => { | |
| 147 assert_unreached('cancel should reject'); | |
| 148 }, e => { | |
| 149 assert_true(cancelCalled); | |
| 150 assert_equals(e, thrownError); | |
| 151 }); | |
| 152 | |
| 153 }, 'ReadableStream cancellation: should reject promise when cancel callback rais
es an exception'); | |
| 154 | |
| 155 promise_test(() => { | |
| 156 | |
| 157 const cancelReason = new Error('test'); | |
| 158 | |
| 159 const rs = new ReadableStream({ | |
| 160 cancel(error) { | |
| 161 assert_equals(error, cancelReason); | |
| 162 return delay(1); | |
| 163 } | |
| 164 }); | |
| 165 | |
| 166 return rs.cancel(cancelReason); | |
| 167 | |
| 168 }, 'ReadableStream cancellation: if the underlying source\'s cancel method retur
ns a promise, the promise returned by the stream\'s cancel should fulfill when t
hat one does (1)'); | |
| 169 | |
| 170 promise_test(() => { | |
| 171 | |
| 172 let resolveSourceCancelPromise; | |
| 173 let sourceCancelPromiseHasFulfilled = false; | |
| 174 | |
| 175 const rs = new ReadableStream({ | |
| 176 cancel() { | |
| 177 const sourceCancelPromise = new Promise(resolve => resolveSourceCancelProm
ise = resolve); | |
| 178 | |
| 179 sourceCancelPromise.then(() => { | |
| 180 sourceCancelPromiseHasFulfilled = true; | |
| 181 }); | |
| 182 | |
| 183 return sourceCancelPromise; | |
| 184 } | |
| 185 }); | |
| 186 | |
| 187 setTimeout(() => resolveSourceCancelPromise('Hello'), 1); | |
| 188 | |
| 189 return rs.cancel().then(value => { | |
| 190 assert_true(sourceCancelPromiseHasFulfilled, 'cancel() return value should b
e fulfilled only after the promise returned by the underlying source\'s cancel')
; | |
| 191 assert_equals(value, undefined, 'cancel() return value should be fulfilled w
ith undefined'); | |
| 192 }); | |
| 193 | |
| 194 }, 'ReadableStream cancellation: if the underlying source\'s cancel method retur
ns a promise, the promise returned by the stream\'s cancel should fulfill when t
hat one does (2)'); | |
| 195 | |
| 196 promise_test(() => { | |
| 197 | |
| 198 let rejectSourceCancelPromise; | |
| 199 let sourceCancelPromiseHasRejected = false; | |
| 200 | |
| 201 const rs = new ReadableStream({ | |
| 202 cancel() { | |
| 203 const sourceCancelPromise = new Promise((resolve, reject) => rejectSourceC
ancelPromise = reject); | |
| 204 | |
| 205 sourceCancelPromise.catch(() => { | |
| 206 sourceCancelPromiseHasRejected = true; | |
| 207 }); | |
| 208 | |
| 209 return sourceCancelPromise; | |
| 210 } | |
| 211 }); | |
| 212 | |
| 213 const errorInCancel = new Error('Sorry, it just wasn\'t meant to be.'); | |
| 214 | |
| 215 setTimeout(() => rejectSourceCancelPromise(errorInCancel), 1); | |
| 216 | |
| 217 return rs.cancel().then(() => { | |
| 218 assert_unreached('cancel() return value should be rejected'); | |
| 219 }, r => { | |
| 220 assert_true(sourceCancelPromiseHasRejected, 'cancel() return value should be
rejected only after the promise returned by the underlying source\'s cancel'); | |
| 221 assert_equals(r, errorInCancel, 'cancel() return value should be rejected wi
th the underlying source\'s rejection reason'); | |
| 222 }); | |
| 223 | |
| 224 }, 'ReadableStream cancellation: if the underlying source\'s cancel method retur
ns a promise, the promise returned by the stream\'s cancel should reject when th
at one does'); | |
| 225 | |
| 226 promise_test(() => { | |
| 227 | |
| 228 const rs = new ReadableStream({ | |
| 229 start() { | |
| 230 return new Promise(() => {}); | |
| 231 }, | |
| 232 pull() { | |
| 233 assert_unreached('pull should not have been called'); | |
| 234 } | |
| 235 }); | |
| 236 | |
| 237 return Promise.all([rs.cancel(), rs.getReader().closed]); | |
| 238 | |
| 239 }, 'ReadableStream cancellation: cancelling before start finishes should prevent
pull() from being called'); | |
| 240 | |
| 241 done(); | |
| OLD | NEW |