• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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