1// META: global=window,worker 2'use strict'; 3 4promise_test(() => { 5 const stream = new ReadableStream({ 6 start(c) { 7 c.close(); 8 }, 9 type: 'bytes' 10 }); 11 12 const reader = stream.getReader({ mode: 'byob' }); 13 const view = new Uint8Array([1, 2, 3]); 14 return reader.read(view).then(({ value, done }) => { 15 // Sanity checks 16 assert_true(value instanceof Uint8Array, 'The value read must be a Uint8Array'); 17 assert_not_equals(value, view, 'The value read must not be the *same* Uint8Array'); 18 assert_array_equals(value, [], 'The value read must be an empty Uint8Array, since the stream is closed'); 19 assert_true(done, 'done must be true, since the stream is closed'); 20 21 // The important assertions 22 assert_not_equals(value.buffer, view.buffer, 'a different ArrayBuffer must underlie the value'); 23 assert_equals(view.buffer.byteLength, 0, 'the original buffer must be detached'); 24 }); 25}, 'ReadableStream with byte source: read()ing from a closed stream still transfers the buffer'); 26 27promise_test(() => { 28 const stream = new ReadableStream({ 29 start(c) { 30 c.enqueue(new Uint8Array([1, 2, 3])); 31 }, 32 type: 'bytes' 33 }); 34 35 const reader = stream.getReader({ mode: 'byob' }); 36 const view = new Uint8Array([4, 5, 6]); 37 return reader.read(view).then(({ value, done }) => { 38 // Sanity checks 39 assert_true(value instanceof Uint8Array, 'The value read must be a Uint8Array'); 40 assert_not_equals(value, view, 'The value read must not be the *same* Uint8Array'); 41 assert_array_equals(value, [1, 2, 3], 'The value read must be the enqueued Uint8Array, not the original values'); 42 assert_false(done, 'done must be false, since the stream is not closed'); 43 44 // The important assertions 45 assert_not_equals(value.buffer, view.buffer, 'a different ArrayBuffer must underlie the value'); 46 assert_equals(view.buffer.byteLength, 0, 'the original buffer must be detached'); 47 }); 48}, 'ReadableStream with byte source: read()ing from a stream with queued chunks still transfers the buffer'); 49 50test(() => { 51 new ReadableStream({ 52 start(c) { 53 const view = new Uint8Array([1, 2, 3]); 54 c.enqueue(view); 55 assert_throws_js(TypeError, () => c.enqueue(view)); 56 }, 57 type: 'bytes' 58 }); 59}, 'ReadableStream with byte source: enqueuing an already-detached buffer throws'); 60 61test(() => { 62 new ReadableStream({ 63 start(c) { 64 const view = new Uint8Array([]); 65 assert_throws_js(TypeError, () => c.enqueue(view)); 66 }, 67 type: 'bytes' 68 }); 69}, 'ReadableStream with byte source: enqueuing a zero-length buffer throws'); 70 71test(() => { 72 new ReadableStream({ 73 start(c) { 74 const view = new Uint8Array(new ArrayBuffer(10), 0, 0); 75 assert_throws_js(TypeError, () => c.enqueue(view)); 76 }, 77 type: 'bytes' 78 }); 79}, 'ReadableStream with byte source: enqueuing a zero-length view on a non-zero-length buffer throws'); 80 81promise_test(t => { 82 const stream = new ReadableStream({ 83 start(c) { 84 c.enqueue(new Uint8Array([1, 2, 3])); 85 }, 86 type: 'bytes' 87 }); 88 const reader = stream.getReader({ mode: 'byob' }); 89 90 const view = new Uint8Array([4, 5, 6]); 91 return reader.read(view).then(() => { 92 // view is now detached 93 return promise_rejects_js(t, TypeError, reader.read(view)); 94 }); 95}, 'ReadableStream with byte source: reading into an already-detached buffer rejects'); 96 97promise_test(t => { 98 const stream = new ReadableStream({ 99 start(c) { 100 c.enqueue(new Uint8Array([1, 2, 3])); 101 }, 102 type: 'bytes' 103 }); 104 const reader = stream.getReader({ mode: 'byob' }); 105 106 const view = new Uint8Array(); 107 return promise_rejects_js(t, TypeError, reader.read(view)); 108}, 'ReadableStream with byte source: reading into a zero-length buffer rejects'); 109 110promise_test(t => { 111 const stream = new ReadableStream({ 112 start(c) { 113 c.enqueue(new Uint8Array([1, 2, 3])); 114 }, 115 type: 'bytes' 116 }); 117 const reader = stream.getReader({ mode: 'byob' }); 118 119 const view = new Uint8Array(new ArrayBuffer(10), 0, 0); 120 return promise_rejects_js(t, TypeError, reader.read(view)); 121}, 'ReadableStream with byte source: reading into a zero-length view on a non-zero-length buffer rejects'); 122 123async_test(t => { 124 const stream = new ReadableStream({ 125 pull: t.step_func_done(c => { 126 // Detach it by reading into it 127 reader.read(c.byobRequest.view); 128 129 assert_throws_js(TypeError, () => c.byobRequest.respond(1), 130 'respond() must throw if the corresponding view has become detached'); 131 }), 132 type: 'bytes' 133 }); 134 const reader = stream.getReader({ mode: 'byob' }); 135 136 reader.read(new Uint8Array([4, 5, 6])); 137}, 'ReadableStream with byte source: respond() throws if the BYOB request\'s buffer has been detached (in the ' + 138 'readable state)'); 139 140async_test(t => { 141 const stream = new ReadableStream({ 142 pull: t.step_func_done(c => { 143 c.close(); 144 145 // Detach it by reading into it 146 reader.read(c.byobRequest.view); 147 148 assert_throws_js(TypeError, () => c.byobRequest.respond(0), 149 'respond() must throw if the corresponding view has become detached'); 150 }), 151 type: 'bytes' 152 }); 153 const reader = stream.getReader({ mode: 'byob' }); 154 155 reader.read(new Uint8Array([4, 5, 6])); 156}, 'ReadableStream with byte source: respond() throws if the BYOB request\'s buffer has been detached (in the ' + 157 'closed state)'); 158 159async_test(t => { 160 const stream = new ReadableStream({ 161 pull: t.step_func_done(c => { 162 // Detach it by reading into it 163 const view = new Uint8Array([1, 2, 3]); 164 reader.read(view); 165 166 assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view)); 167 }), 168 type: 'bytes' 169 }); 170 const reader = stream.getReader({ mode: 'byob' }); 171 172 reader.read(new Uint8Array([4, 5, 6])); 173}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has been detached ' + 174 '(in the readable state)'); 175 176async_test(t => { 177 const stream = new ReadableStream({ 178 pull: t.step_func_done(c => { 179 const view = new Uint8Array(); 180 181 assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view)); 182 }), 183 type: 'bytes' 184 }); 185 const reader = stream.getReader({ mode: 'byob' }); 186 187 reader.read(new Uint8Array([4, 5, 6])); 188}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer is zero-length ' + 189 '(in the readable state)'); 190 191async_test(t => { 192 const stream = new ReadableStream({ 193 pull: t.step_func_done(c => { 194 const view = new Uint8Array(c.byobRequest.view.buffer, 0, 0); 195 196 assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view)); 197 }), 198 type: 'bytes' 199 }); 200 const reader = stream.getReader({ mode: 'byob' }); 201 202 reader.read(new Uint8Array([4, 5, 6])); 203}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view is zero-length on a ' + 204 'non-zero-length buffer (in the readable state)'); 205 206async_test(t => { 207 const stream = new ReadableStream({ 208 pull: t.step_func_done(c => { 209 const view = c.byobRequest.view.subarray(1, 2); 210 211 assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view)); 212 }), 213 type: 'bytes' 214 }); 215 const reader = stream.getReader({ mode: 'byob' }); 216 217 reader.read(new Uint8Array([4, 5, 6])); 218}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset ' + 219 '(in the readable state)'); 220 221async_test(t => { 222 const stream = new ReadableStream({ 223 pull: t.step_func_done(c => { 224 c.close(); 225 226 const view = c.byobRequest.view.subarray(1, 1); 227 228 assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view)); 229 }), 230 type: 'bytes' 231 }); 232 const reader = stream.getReader({ mode: 'byob' }); 233 234 reader.read(new Uint8Array([4, 5, 6])); 235}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view has a different offset ' + 236 '(in the closed state)'); 237 238async_test(t => { 239 const stream = new ReadableStream({ 240 pull: t.step_func_done(c => { 241 const view = new Uint8Array(new ArrayBuffer(10), 0, 3); 242 243 assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view)); 244 }), 245 type: 'bytes' 246 }); 247 const reader = stream.getReader({ mode: 'byob' }); 248 249 reader.read(new Uint8Array([4, 5, 6])); 250}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has a ' + 251 'different length (in the readable state)'); 252 253async_test(t => { 254 // Tests https://github.com/nodejs/node/issues/41886 255 const stream = new ReadableStream({ 256 pull: t.step_func_done(c => { 257 const view = new Uint8Array(new ArrayBuffer(11), 0, 3); 258 259 assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view)); 260 }), 261 type: 'bytes', 262 autoAllocateChunkSize: 10 263 }); 264 const reader = stream.getReader(); 265 266 reader.read(); 267}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has a ' + 268 'different length (autoAllocateChunkSize)'); 269 270async_test(t => { 271 const stream = new ReadableStream({ 272 pull: t.step_func_done(c => { 273 const view = new Uint8Array(c.byobRequest.view.buffer, 0, 4); 274 view[0] = 20; 275 view[1] = 21; 276 view[2] = 22; 277 view[3] = 23; 278 279 assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view)); 280 }), 281 type: 'bytes' 282 }); 283 const reader = stream.getReader({ mode: 'byob' }); 284 285 const buffer = new ArrayBuffer(10); 286 const view = new Uint8Array(buffer, 0, 3); 287 view[0] = 10; 288 view[1] = 11; 289 view[2] = 12; 290 reader.read(view); 291}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view has a larger length ' + 292 '(in the readable state)'); 293 294async_test(t => { 295 const stream = new ReadableStream({ 296 pull: t.step_func_done(c => { 297 c.close(); 298 299 // Detach it by reading into it 300 const view = new Uint8Array([1, 2, 3]); 301 reader.read(view); 302 303 assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view)); 304 }), 305 type: 'bytes' 306 }); 307 const reader = stream.getReader({ mode: 'byob' }); 308 309 reader.read(new Uint8Array([4, 5, 6])); 310}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has been detached ' + 311 '(in the closed state)'); 312 313async_test(t => { 314 const stream = new ReadableStream({ 315 pull: t.step_func_done(c => { 316 const view = new Uint8Array(); 317 318 c.close(); 319 320 assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view)); 321 }), 322 type: 'bytes' 323 }); 324 const reader = stream.getReader({ mode: 'byob' }); 325 326 reader.read(new Uint8Array([4, 5, 6])); 327}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer is zero-length ' + 328 '(in the closed state)'); 329 330async_test(t => { 331 const stream = new ReadableStream({ 332 pull: t.step_func_done(c => { 333 const view = new Uint8Array(c.byobRequest.view.buffer, 0, 1); 334 335 c.close(); 336 337 assert_throws_js(TypeError, () => c.byobRequest.respondWithNewView(view)); 338 }), 339 type: 'bytes' 340 }); 341 const reader = stream.getReader({ mode: 'byob' }); 342 343 reader.read(new Uint8Array([4, 5, 6])); 344}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view is non-zero-length ' + 345 '(in the closed state)'); 346 347async_test(t => { 348 const stream = new ReadableStream({ 349 pull: t.step_func_done(c => { 350 const view = new Uint8Array(new ArrayBuffer(10), 0, 0); 351 352 c.close(); 353 354 assert_throws_js(RangeError, () => c.byobRequest.respondWithNewView(view)); 355 }), 356 type: 'bytes' 357 }); 358 const reader = stream.getReader({ mode: 'byob' }); 359 360 reader.read(new Uint8Array([4, 5, 6])); 361}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has a ' + 362 'different length (in the closed state)'); 363 364async_test(t => { 365 const stream = new ReadableStream({ 366 pull: t.step_func_done(c => { 367 // Detach it by reading into it 368 reader.read(c.byobRequest.view); 369 370 assert_throws_js(TypeError, () => c.enqueue(new Uint8Array([1])), 371 'enqueue() must throw if the BYOB request\'s buffer has become detached'); 372 }), 373 type: 'bytes' 374 }); 375 const reader = stream.getReader({ mode: 'byob' }); 376 377 reader.read(new Uint8Array([4, 5, 6])); 378}, 'ReadableStream with byte source: enqueue() throws if the BYOB request\'s buffer has been detached (in the ' + 379 'readable state)'); 380 381async_test(t => { 382 const stream = new ReadableStream({ 383 pull: t.step_func_done(c => { 384 c.close(); 385 386 // Detach it by reading into it 387 reader.read(c.byobRequest.view); 388 389 assert_throws_js(TypeError, () => c.enqueue(new Uint8Array([1])), 390 'enqueue() must throw if the BYOB request\'s buffer has become detached'); 391 }), 392 type: 'bytes' 393 }); 394 const reader = stream.getReader({ mode: 'byob' }); 395 396 reader.read(new Uint8Array([4, 5, 6])); 397}, 'ReadableStream with byte source: enqueue() throws if the BYOB request\'s buffer has been detached (in the ' + 398 'closed state)'); 399