| OLD | NEW |
| (Empty) |
| 1 'use strict'; | |
| 2 | |
| 3 // These tests can be run against any readable stream produced by the web platfo
rm that meets the given descriptions. | |
| 4 // For readable stream tests, the factory should return the stream. For reader t
ests, the factory should return a | |
| 5 // { stream, reader } object. (You can use this to vary the time at which you ac
quire a reader.) | |
| 6 | |
| 7 self.templatedRSEmpty = (label, factory) => { | |
| 8 test(() => {}, 'Running templatedRSEmpty with ' + label); | |
| 9 | |
| 10 test(() => { | |
| 11 | |
| 12 const rs = factory(); | |
| 13 | |
| 14 assert_equals(typeof rs.locked, 'boolean', 'has a boolean locked getter'); | |
| 15 assert_equals(typeof rs.cancel, 'function', 'has a cancel method'); | |
| 16 assert_equals(typeof rs.getReader, 'function', 'has a getReader method'); | |
| 17 assert_equals(typeof rs.tee, 'function', 'has a tee method'); | |
| 18 | |
| 19 }, 'instances have the correct methods and properties'); | |
| 20 | |
| 21 test(() => { | |
| 22 const rs = factory(); | |
| 23 | |
| 24 assert_throws(new RangeError(), () => rs.getReader({ mode: '' }), 'empty str
ing mode should throw'); | |
| 25 assert_throws(new RangeError(), () => rs.getReader({ mode: null }), 'null mo
de should throw'); | |
| 26 assert_throws(new RangeError(), () => rs.getReader({ mode: 'asdf' }), 'asdf
mode should throw'); | |
| 27 assert_throws(new TypeError(), () => rs.getReader(null), 'null should throw'
); | |
| 28 | |
| 29 }, 'calling getReader with invalid arguments should throw appropriate errors')
; | |
| 30 }; | |
| 31 | |
| 32 self.templatedRSClosed = (label, factory) => { | |
| 33 test(() => {}, 'Running templatedRSClosed with ' + label); | |
| 34 | |
| 35 promise_test(() => { | |
| 36 | |
| 37 const rs = factory(); | |
| 38 const cancelPromise1 = rs.cancel(); | |
| 39 const cancelPromise2 = rs.cancel(); | |
| 40 | |
| 41 assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should ret
urn distinct promises'); | |
| 42 | |
| 43 return Promise.all([ | |
| 44 cancelPromise1.then(v => assert_equals(v, undefined, 'first cancel() call
should fulfill with undefined')), | |
| 45 cancelPromise2.then(v => assert_equals(v, undefined, 'second cancel() call
should fulfill with undefined')) | |
| 46 ]); | |
| 47 | |
| 48 }, 'cancel() should return a distinct fulfilled promise each time'); | |
| 49 | |
| 50 test(() => { | |
| 51 | |
| 52 const rs = factory(); | |
| 53 assert_false(rs.locked, 'locked getter should return false'); | |
| 54 | |
| 55 }, 'locked should be false'); | |
| 56 | |
| 57 test(() => { | |
| 58 | |
| 59 const rs = factory(); | |
| 60 rs.getReader(); // getReader() should not throw. | |
| 61 | |
| 62 }, 'getReader() should be OK'); | |
| 63 | |
| 64 test(() => { | |
| 65 | |
| 66 const rs = factory(); | |
| 67 | |
| 68 const reader = rs.getReader(); | |
| 69 reader.releaseLock(); | |
| 70 | |
| 71 const reader2 = rs.getReader(); // Getting a second reader should not throw. | |
| 72 reader2.releaseLock(); | |
| 73 | |
| 74 rs.getReader(); // Getting a third reader should not throw. | |
| 75 | |
| 76 }, 'should be able to acquire multiple readers if they are released in success
ion'); | |
| 77 | |
| 78 test(() => { | |
| 79 | |
| 80 const rs = factory(); | |
| 81 | |
| 82 rs.getReader(); | |
| 83 | |
| 84 assert_throws(new TypeError(), () => rs.getReader(), 'getting a second reade
r should throw'); | |
| 85 assert_throws(new TypeError(), () => rs.getReader(), 'getting a third reader
should throw'); | |
| 86 | |
| 87 }, 'should not be able to acquire a second reader if we don\'t release the fir
st one'); | |
| 88 }; | |
| 89 | |
| 90 self.templatedRSErrored = (label, factory, error) => { | |
| 91 test(() => {}, 'Running templatedRSErrored with ' + label); | |
| 92 | |
| 93 promise_test(t => { | |
| 94 | |
| 95 const rs = factory(); | |
| 96 const reader = rs.getReader(); | |
| 97 | |
| 98 return Promise.all([ | |
| 99 promise_rejects(t, error, reader.closed), | |
| 100 promise_rejects(t, error, reader.read()) | |
| 101 ]); | |
| 102 | |
| 103 }, 'getReader() should return a reader that acts errored'); | |
| 104 | |
| 105 promise_test(t => { | |
| 106 | |
| 107 const rs = factory(); | |
| 108 const reader = rs.getReader(); | |
| 109 | |
| 110 return Promise.all([ | |
| 111 promise_rejects(t, error, reader.read()), | |
| 112 promise_rejects(t, error, reader.read()), | |
| 113 promise_rejects(t, error, reader.closed) | |
| 114 ]); | |
| 115 | |
| 116 }, 'read() twice should give the error each time'); | |
| 117 | |
| 118 test(() => { | |
| 119 const rs = factory(); | |
| 120 | |
| 121 assert_false(rs.locked, 'locked getter should return false'); | |
| 122 }, 'locked should be false'); | |
| 123 }; | |
| 124 | |
| 125 self.templatedRSErroredSyncOnly = (label, factory, error) => { | |
| 126 test(() => {}, 'Running templatedRSErroredSyncOnly with ' + label); | |
| 127 | |
| 128 promise_test(t => { | |
| 129 | |
| 130 const rs = factory(); | |
| 131 rs.getReader().releaseLock(); | |
| 132 const reader = rs.getReader(); // Calling getReader() twice does not throw (
the stream is not locked). | |
| 133 | |
| 134 return promise_rejects(t, error, reader.closed); | |
| 135 | |
| 136 }, 'should be able to obtain a second reader, with the correct closed promise'
); | |
| 137 | |
| 138 test(() => { | |
| 139 | |
| 140 const rs = factory(); | |
| 141 rs.getReader(); | |
| 142 | |
| 143 assert_throws(new TypeError(), () => rs.getReader(), 'getting a second reade
r should throw a TypeError'); | |
| 144 assert_throws(new TypeError(), () => rs.getReader(), 'getting a third reader
should throw a TypeError'); | |
| 145 | |
| 146 }, 'should not be able to obtain additional readers if we don\'t release the f
irst lock'); | |
| 147 | |
| 148 promise_test(t => { | |
| 149 | |
| 150 const rs = factory(); | |
| 151 const cancelPromise1 = rs.cancel(); | |
| 152 const cancelPromise2 = rs.cancel(); | |
| 153 | |
| 154 assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should ret
urn distinct promises'); | |
| 155 | |
| 156 return Promise.all([ | |
| 157 promise_rejects(t, error, cancelPromise1), | |
| 158 promise_rejects(t, error, cancelPromise2) | |
| 159 ]); | |
| 160 | |
| 161 }, 'cancel() should return a distinct rejected promise each time'); | |
| 162 | |
| 163 promise_test(t => { | |
| 164 | |
| 165 const rs = factory(); | |
| 166 const reader = rs.getReader(); | |
| 167 const cancelPromise1 = reader.cancel(); | |
| 168 const cancelPromise2 = reader.cancel(); | |
| 169 | |
| 170 assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should ret
urn distinct promises'); | |
| 171 | |
| 172 return Promise.all([ | |
| 173 promise_rejects(t, error, cancelPromise1), | |
| 174 promise_rejects(t, error, cancelPromise2) | |
| 175 ]); | |
| 176 | |
| 177 }, 'reader cancel() should return a distinct rejected promise each time'); | |
| 178 }; | |
| 179 | |
| 180 self.templatedRSEmptyReader = (label, factory) => { | |
| 181 test(() => {}, 'Running templatedRSEmptyReader with ' + label); | |
| 182 | |
| 183 test(() => { | |
| 184 | |
| 185 const reader = factory().reader; | |
| 186 | |
| 187 assert_true('closed' in reader, 'has a closed property'); | |
| 188 assert_equals(typeof reader.closed.then, 'function', 'closed property is the
nable'); | |
| 189 | |
| 190 assert_equals(typeof reader.cancel, 'function', 'has a cancel method'); | |
| 191 assert_equals(typeof reader.read, 'function', 'has a read method'); | |
| 192 assert_equals(typeof reader.releaseLock, 'function', 'has a releaseLock meth
od'); | |
| 193 | |
| 194 }, 'instances have the correct methods and properties'); | |
| 195 | |
| 196 test(() => { | |
| 197 | |
| 198 const stream = factory().stream; | |
| 199 | |
| 200 assert_true(stream.locked, 'locked getter should return true'); | |
| 201 | |
| 202 }, 'locked should be true'); | |
| 203 | |
| 204 promise_test(t => { | |
| 205 | |
| 206 const reader = factory().reader; | |
| 207 | |
| 208 reader.read().then( | |
| 209 t.unreached_func('read() should not fulfill'), | |
| 210 t.unreached_func('read() should not reject') | |
| 211 ); | |
| 212 | |
| 213 return delay(500); | |
| 214 | |
| 215 }, 'read() should never settle'); | |
| 216 | |
| 217 promise_test(t => { | |
| 218 | |
| 219 const reader = factory().reader; | |
| 220 | |
| 221 reader.read().then( | |
| 222 t.unreached_func('read() should not fulfill'), | |
| 223 t.unreached_func('read() should not reject') | |
| 224 ); | |
| 225 | |
| 226 reader.read().then( | |
| 227 t.unreached_func('read() should not fulfill'), | |
| 228 t.unreached_func('read() should not reject') | |
| 229 ); | |
| 230 | |
| 231 return delay(500); | |
| 232 | |
| 233 }, 'two read()s should both never settle'); | |
| 234 | |
| 235 test(() => { | |
| 236 | |
| 237 const reader = factory().reader; | |
| 238 assert_not_equals(reader.read(), reader.read(), 'the promises returned shoul
d be distinct'); | |
| 239 | |
| 240 }, 'read() should return distinct promises each time'); | |
| 241 | |
| 242 test(() => { | |
| 243 | |
| 244 const stream = factory().stream; | |
| 245 assert_throws(new TypeError(), () => stream.getReader(), 'stream.getReader()
should throw a TypeError'); | |
| 246 | |
| 247 }, 'getReader() again on the stream should fail'); | |
| 248 | |
| 249 promise_test(t => { | |
| 250 | |
| 251 const streamAndReader = factory(); | |
| 252 const stream = streamAndReader.stream; | |
| 253 const reader = streamAndReader.reader; | |
| 254 | |
| 255 reader.read().then( | |
| 256 t.unreached_func('first read() should not fulfill'), | |
| 257 t.unreached_func('first read() should not reject') | |
| 258 ); | |
| 259 | |
| 260 reader.read().then( | |
| 261 t.unreached_func('second read() should not fulfill'), | |
| 262 t.unreached_func('second read() should not reject') | |
| 263 ); | |
| 264 | |
| 265 reader.closed.then( | |
| 266 t.unreached_func('closed should not fulfill'), | |
| 267 t.unreached_func('closed should not reject') | |
| 268 ); | |
| 269 | |
| 270 assert_throws(new TypeError(), () => reader.releaseLock(), 'releaseLock shou
ld throw a TypeError'); | |
| 271 | |
| 272 assert_true(stream.locked, 'the stream should still be locked'); | |
| 273 | |
| 274 return delay(500); | |
| 275 | |
| 276 }, 'releasing the lock with pending read requests should throw but the read re
quests should stay pending'); | |
| 277 | |
| 278 promise_test(t => { | |
| 279 | |
| 280 const reader = factory().reader; | |
| 281 reader.releaseLock(); | |
| 282 | |
| 283 return Promise.all([ | |
| 284 promise_rejects(t, new TypeError(), reader.read()), | |
| 285 promise_rejects(t, new TypeError(), reader.read()) | |
| 286 ]); | |
| 287 | |
| 288 }, 'releasing the lock should cause further read() calls to reject with a Type
Error'); | |
| 289 | |
| 290 promise_test(t => { | |
| 291 | |
| 292 const reader = factory().reader; | |
| 293 | |
| 294 const closedBefore = reader.closed; | |
| 295 reader.releaseLock(); | |
| 296 const closedAfter = reader.closed; | |
| 297 | |
| 298 assert_equals(closedBefore, closedAfter, 'the closed promise should not chan
ge identity'); | |
| 299 | |
| 300 return promise_rejects(t, new TypeError(), closedBefore); | |
| 301 | |
| 302 }, 'releasing the lock should cause closed calls to reject with a TypeError'); | |
| 303 | |
| 304 test(() => { | |
| 305 | |
| 306 const streamAndReader = factory(); | |
| 307 const stream = streamAndReader.stream; | |
| 308 const reader = streamAndReader.reader; | |
| 309 | |
| 310 reader.releaseLock(); | |
| 311 assert_false(stream.locked, 'locked getter should return false'); | |
| 312 | |
| 313 }, 'releasing the lock should cause locked to become false'); | |
| 314 | |
| 315 promise_test(() => { | |
| 316 | |
| 317 const reader = factory().reader; | |
| 318 reader.cancel(); | |
| 319 | |
| 320 return reader.read().then(r => { | |
| 321 assert_object_equals(r, { value: undefined, done: true }, 'read()ing from
the reader should give a done result'); | |
| 322 }); | |
| 323 | |
| 324 }, 'canceling via the reader should cause the reader to act closed'); | |
| 325 | |
| 326 promise_test(t => { | |
| 327 | |
| 328 const stream = factory().stream; | |
| 329 return promise_rejects(t, new TypeError(), stream.cancel()); | |
| 330 | |
| 331 }, 'canceling via the stream should fail'); | |
| 332 }; | |
| 333 | |
| 334 self.templatedRSClosedReader = (label, factory) => { | |
| 335 test(() => {}, 'Running templatedRSClosedReader with ' + label); | |
| 336 | |
| 337 promise_test(() => { | |
| 338 | |
| 339 const reader = factory().reader; | |
| 340 | |
| 341 return reader.read().then(v => { | |
| 342 assert_object_equals(v, { value: undefined, done: true }, 'read() should f
ulfill correctly'); | |
| 343 }); | |
| 344 | |
| 345 }, 'read() should fulfill with { value: undefined, done: true }'); | |
| 346 | |
| 347 promise_test(() => { | |
| 348 | |
| 349 const reader = factory().reader; | |
| 350 | |
| 351 return Promise.all([ | |
| 352 reader.read().then(v => { | |
| 353 assert_object_equals(v, { value: undefined, done: true }, 'read() should
fulfill correctly'); | |
| 354 }), | |
| 355 reader.read().then(v => { | |
| 356 assert_object_equals(v, { value: undefined, done: true }, 'read() should
fulfill correctly'); | |
| 357 }) | |
| 358 ]); | |
| 359 | |
| 360 }, 'read() multiple times should fulfill with { value: undefined, done: true }
'); | |
| 361 | |
| 362 promise_test(() => { | |
| 363 | |
| 364 const reader = factory().reader; | |
| 365 | |
| 366 return reader.read().then(() => reader.read()).then(v => { | |
| 367 assert_object_equals(v, { value: undefined, done: true }, 'read() should f
ulfill correctly'); | |
| 368 }); | |
| 369 | |
| 370 }, 'read() should work when used within another read() fulfill callback'); | |
| 371 | |
| 372 promise_test(() => { | |
| 373 | |
| 374 const reader = factory().reader; | |
| 375 | |
| 376 return reader.closed.then(v => assert_equals(v, undefined, 'reader closed sh
ould fulfill with undefined')); | |
| 377 | |
| 378 }, 'closed should fulfill with undefined'); | |
| 379 | |
| 380 promise_test(t => { | |
| 381 | |
| 382 const reader = factory().reader; | |
| 383 | |
| 384 const closedBefore = reader.closed; | |
| 385 reader.releaseLock(); | |
| 386 const closedAfter = reader.closed; | |
| 387 | |
| 388 assert_not_equals(closedBefore, closedAfter, 'the closed promise should chan
ge identity'); | |
| 389 | |
| 390 return Promise.all([ | |
| 391 closedBefore.then(v => assert_equals(v, undefined, 'reader.closed acquired
before release should fulfill')), | |
| 392 promise_rejects(t, new TypeError(), closedAfter) | |
| 393 ]); | |
| 394 | |
| 395 }, 'releasing the lock should cause closed to reject and change identity'); | |
| 396 | |
| 397 promise_test(() => { | |
| 398 | |
| 399 const reader = factory().reader; | |
| 400 const cancelPromise1 = reader.cancel(); | |
| 401 const cancelPromise2 = reader.cancel(); | |
| 402 const closedReaderPromise = reader.closed; | |
| 403 | |
| 404 assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should ret
urn distinct promises'); | |
| 405 assert_not_equals(cancelPromise1, closedReaderPromise, 'cancel() promise 1 s
hould be distinct from reader.closed'); | |
| 406 assert_not_equals(cancelPromise2, closedReaderPromise, 'cancel() promise 2 s
hould be distinct from reader.closed'); | |
| 407 | |
| 408 return Promise.all([ | |
| 409 cancelPromise1.then(v => assert_equals(v, undefined, 'first cancel() shoul
d fulfill with undefined')), | |
| 410 cancelPromise2.then(v => assert_equals(v, undefined, 'second cancel() shou
ld fulfill with undefined')) | |
| 411 ]); | |
| 412 | |
| 413 }, 'cancel() should return a distinct fulfilled promise each time'); | |
| 414 }; | |
| 415 | |
| 416 self.templatedRSErroredReader = (label, factory, error) => { | |
| 417 test(() => {}, 'Running templatedRSErroredReader with ' + label); | |
| 418 | |
| 419 promise_test(t => { | |
| 420 | |
| 421 const reader = factory().reader; | |
| 422 return promise_rejects(t, error, reader.closed); | |
| 423 | |
| 424 }, 'closed should reject with the error'); | |
| 425 | |
| 426 promise_test(t => { | |
| 427 | |
| 428 const reader = factory().reader; | |
| 429 const closedBefore = reader.closed; | |
| 430 | |
| 431 return promise_rejects(t, error, closedBefore).then(() => { | |
| 432 reader.releaseLock(); | |
| 433 | |
| 434 const closedAfter = reader.closed; | |
| 435 assert_not_equals(closedBefore, closedAfter, 'the closed promise should ch
ange identity'); | |
| 436 | |
| 437 return promise_rejects(t, new TypeError(), closedAfter); | |
| 438 }); | |
| 439 | |
| 440 }, 'releasing the lock should cause closed to reject and change identity'); | |
| 441 | |
| 442 promise_test(t => { | |
| 443 | |
| 444 const reader = factory().reader; | |
| 445 return promise_rejects(t, error, reader.read()); | |
| 446 | |
| 447 }, 'read() should reject with the error'); | |
| 448 }; | |
| 449 | |
| 450 self.templatedRSTwoChunksOpenReader = (label, factory, chunks) => { | |
| 451 test(() => {}, 'Running templatedRSTwoChunksOpenReader with ' + label); | |
| 452 | |
| 453 promise_test(() => { | |
| 454 | |
| 455 const reader = factory().reader; | |
| 456 | |
| 457 return Promise.all([ | |
| 458 reader.read().then(r => { | |
| 459 assert_object_equals(r, { value: chunks[0], done: false }, 'first result
should be correct'); | |
| 460 }), | |
| 461 reader.read().then(r => { | |
| 462 assert_object_equals(r, { value: chunks[1], done: false }, 'second resul
t should be correct'); | |
| 463 }) | |
| 464 ]); | |
| 465 | |
| 466 }, 'calling read() twice without waiting will eventually give both chunks (seq
uential)'); | |
| 467 | |
| 468 promise_test(() => { | |
| 469 | |
| 470 const reader = factory().reader; | |
| 471 | |
| 472 return reader.read().then(r => { | |
| 473 assert_object_equals(r, { value: chunks[0], done: false }, 'first result s
hould be correct'); | |
| 474 | |
| 475 return reader.read().then(r2 => { | |
| 476 assert_object_equals(r2, { value: chunks[1], done: false }, 'second resu
lt should be correct'); | |
| 477 }); | |
| 478 }); | |
| 479 | |
| 480 }, 'calling read() twice without waiting will eventually give both chunks (nes
ted)'); | |
| 481 | |
| 482 test(() => { | |
| 483 | |
| 484 const reader = factory().reader; | |
| 485 assert_not_equals(reader.read(), reader.read(), 'the promises returned shoul
d be distinct'); | |
| 486 | |
| 487 }, 'read() should return distinct promises each time'); | |
| 488 | |
| 489 promise_test(() => { | |
| 490 | |
| 491 const reader = factory().reader; | |
| 492 | |
| 493 const promise1 = reader.closed.then(v => { | |
| 494 assert_equals(v, undefined, 'reader closed should fulfill with undefined')
; | |
| 495 }); | |
| 496 | |
| 497 const promise2 = reader.read().then(r => { | |
| 498 assert_object_equals(r, { value: chunks[0], done: false }, | |
| 499 'promise returned before cancellation should fulfill
with a chunk'); | |
| 500 }); | |
| 501 | |
| 502 reader.cancel(); | |
| 503 | |
| 504 const promise3 = reader.read().then(r => { | |
| 505 assert_object_equals(r, { value: undefined, done: true }, | |
| 506 'promise returned after cancellation should fulfill w
ith an end-of-stream signal'); | |
| 507 }); | |
| 508 | |
| 509 return Promise.all([promise1, promise2, promise3]); | |
| 510 | |
| 511 }, 'cancel() after a read() should still give that single read result'); | |
| 512 }; | |
| 513 | |
| 514 self.templatedRSTwoChunksClosedReader = function (label, factory, chunks) { | |
| 515 test(() => {}, 'Running templatedRSTwoChunksClosedReader with ' + label); | |
| 516 | |
| 517 promise_test(() => { | |
| 518 | |
| 519 const reader = factory().reader; | |
| 520 | |
| 521 return Promise.all([ | |
| 522 reader.read().then(r => { | |
| 523 assert_object_equals(r, { value: chunks[0], done: false }, 'first result
should be correct'); | |
| 524 }), | |
| 525 reader.read().then(r => { | |
| 526 assert_object_equals(r, { value: chunks[1], done: false }, 'second resul
t should be correct'); | |
| 527 }), | |
| 528 reader.read().then(r => { | |
| 529 assert_object_equals(r, { value: undefined, done: true }, 'third result
should be correct'); | |
| 530 }) | |
| 531 ]); | |
| 532 | |
| 533 }, 'third read(), without waiting, should give { value: undefined, done: true
} (sequential)'); | |
| 534 | |
| 535 promise_test(() => { | |
| 536 | |
| 537 const reader = factory().reader; | |
| 538 | |
| 539 return reader.read().then(r => { | |
| 540 assert_object_equals(r, { value: chunks[0], done: false }, 'first result s
hould be correct'); | |
| 541 | |
| 542 return reader.read().then(r2 => { | |
| 543 assert_object_equals(r2, { value: chunks[1], done: false }, 'second resu
lt should be correct'); | |
| 544 | |
| 545 return reader.read().then(r3 => { | |
| 546 assert_object_equals(r3, { value: undefined, done: true }, 'third resu
lt should be correct'); | |
| 547 }); | |
| 548 }); | |
| 549 }); | |
| 550 | |
| 551 }, 'third read(), without waiting, should give { value: undefined, done: true
} (nested)'); | |
| 552 | |
| 553 promise_test(() => { | |
| 554 | |
| 555 const streamAndReader = factory(); | |
| 556 const stream = streamAndReader.stream; | |
| 557 const reader = streamAndReader.reader; | |
| 558 | |
| 559 assert_true(stream.locked, 'stream should start locked'); | |
| 560 | |
| 561 const promise = reader.closed.then(v => { | |
| 562 assert_equals(v, undefined, 'reader closed should fulfill with undefined')
; | |
| 563 assert_true(stream.locked, 'stream should remain locked'); | |
| 564 }); | |
| 565 | |
| 566 reader.read(); | |
| 567 reader.read(); | |
| 568 | |
| 569 return promise; | |
| 570 | |
| 571 }, 'draining the stream via read() should cause the reader closed promise to f
ulfill, but locked stays true'); | |
| 572 | |
| 573 promise_test(() => { | |
| 574 | |
| 575 const streamAndReader = factory(); | |
| 576 const stream = streamAndReader.stream; | |
| 577 const reader = streamAndReader.reader; | |
| 578 | |
| 579 const promise = reader.closed.then(() => { | |
| 580 assert_true(stream.locked, 'the stream should start locked'); | |
| 581 reader.releaseLock(); // Releasing the lock after reader closed should not
throw. | |
| 582 assert_false(stream.locked, 'the stream should end unlocked'); | |
| 583 }); | |
| 584 | |
| 585 reader.read(); | |
| 586 reader.read(); | |
| 587 | |
| 588 return promise; | |
| 589 | |
| 590 }, 'releasing the lock after the stream is closed should cause locked to becom
e false'); | |
| 591 | |
| 592 promise_test(t => { | |
| 593 | |
| 594 const reader = factory().reader; | |
| 595 | |
| 596 reader.releaseLock(); | |
| 597 | |
| 598 return Promise.all([ | |
| 599 promise_rejects(t, new TypeError(), reader.read()), | |
| 600 promise_rejects(t, new TypeError(), reader.read()), | |
| 601 promise_rejects(t, new TypeError(), reader.read()) | |
| 602 ]); | |
| 603 | |
| 604 }, 'releasing the lock should cause further read() calls to reject with a Type
Error'); | |
| 605 | |
| 606 promise_test(() => { | |
| 607 | |
| 608 const streamAndReader = factory(); | |
| 609 const stream = streamAndReader.stream; | |
| 610 const reader = streamAndReader.reader; | |
| 611 | |
| 612 const readerClosed = reader.closed; | |
| 613 | |
| 614 assert_equals(reader.closed, readerClosed, 'accessing reader.closed twice in
succession gives the same value'); | |
| 615 | |
| 616 const promise = reader.read().then(() => { | |
| 617 assert_equals(reader.closed, readerClosed, 'reader.closed is the same afte
r read() fulfills'); | |
| 618 | |
| 619 reader.releaseLock(); | |
| 620 | |
| 621 assert_equals(reader.closed, readerClosed, 'reader.closed is the same afte
r releasing the lock'); | |
| 622 | |
| 623 const newReader = stream.getReader(); | |
| 624 return newReader.read(); | |
| 625 }); | |
| 626 | |
| 627 assert_equals(reader.closed, readerClosed, 'reader.closed is the same after
calling read()'); | |
| 628 | |
| 629 return promise; | |
| 630 | |
| 631 }, 'reader\'s closed property always returns the same promise'); | |
| 632 }; | |
| OLD | NEW |