11cb0ef41Sopenharmony_ci// META: title=Blob Stream
21cb0ef41Sopenharmony_ci// META: script=../support/Blob.js
31cb0ef41Sopenharmony_ci// META: script=../../streams/resources/test-utils.js
41cb0ef41Sopenharmony_ci'use strict';
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci// Helper function that triggers garbage collection while reading a chunk
71cb0ef41Sopenharmony_ci// if perform_gc is true.
81cb0ef41Sopenharmony_ciasync function read_and_gc(reader, perform_gc) {
91cb0ef41Sopenharmony_ci  const read_promise = reader.read();
101cb0ef41Sopenharmony_ci  if (perform_gc)
111cb0ef41Sopenharmony_ci    garbageCollect();
121cb0ef41Sopenharmony_ci  return read_promise;
131cb0ef41Sopenharmony_ci}
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// Takes in a ReadableStream and reads from it until it is done, returning
161cb0ef41Sopenharmony_ci// an array that contains the results of each read operation. If perform_gc
171cb0ef41Sopenharmony_ci// is true, garbage collection is triggered while reading every chunk.
181cb0ef41Sopenharmony_ciasync function read_all_chunks(stream, perform_gc = false) {
191cb0ef41Sopenharmony_ci  assert_true(stream instanceof ReadableStream);
201cb0ef41Sopenharmony_ci  assert_true('getReader' in stream);
211cb0ef41Sopenharmony_ci  const reader = stream.getReader();
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci  assert_true('read' in reader);
241cb0ef41Sopenharmony_ci  let read_value = await read_and_gc(reader, perform_gc);
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  let out = [];
271cb0ef41Sopenharmony_ci  let i = 0;
281cb0ef41Sopenharmony_ci  while (!read_value.done) {
291cb0ef41Sopenharmony_ci    for (let val of read_value.value) {
301cb0ef41Sopenharmony_ci      out[i++] = val;
311cb0ef41Sopenharmony_ci    }
321cb0ef41Sopenharmony_ci    read_value = await read_and_gc(reader, perform_gc);
331cb0ef41Sopenharmony_ci  }
341cb0ef41Sopenharmony_ci  return out;
351cb0ef41Sopenharmony_ci}
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cipromise_test(async () => {
381cb0ef41Sopenharmony_ci  const blob = new Blob(["PASS"]);
391cb0ef41Sopenharmony_ci  const stream = blob.stream();
401cb0ef41Sopenharmony_ci  const chunks = await read_all_chunks(stream);
411cb0ef41Sopenharmony_ci  for (let [index, value] of chunks.entries()) {
421cb0ef41Sopenharmony_ci    assert_equals(value, "PASS".charCodeAt(index));
431cb0ef41Sopenharmony_ci  }
441cb0ef41Sopenharmony_ci}, "Blob.stream()")
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_cipromise_test(async () => {
471cb0ef41Sopenharmony_ci  const blob = new Blob();
481cb0ef41Sopenharmony_ci  const stream = blob.stream();
491cb0ef41Sopenharmony_ci  const chunks = await read_all_chunks(stream);
501cb0ef41Sopenharmony_ci  assert_array_equals(chunks, []);
511cb0ef41Sopenharmony_ci}, "Blob.stream() empty Blob")
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_cipromise_test(async () => {
541cb0ef41Sopenharmony_ci  const input_arr = [8, 241, 48, 123, 151];
551cb0ef41Sopenharmony_ci  const typed_arr = new Uint8Array(input_arr);
561cb0ef41Sopenharmony_ci  const blob = new Blob([typed_arr]);
571cb0ef41Sopenharmony_ci  const stream = blob.stream();
581cb0ef41Sopenharmony_ci  const chunks = await read_all_chunks(stream);
591cb0ef41Sopenharmony_ci  assert_array_equals(chunks, input_arr);
601cb0ef41Sopenharmony_ci}, "Blob.stream() non-unicode input")
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_cipromise_test(async() => {
631cb0ef41Sopenharmony_ci  const input_arr = [8, 241, 48, 123, 151];
641cb0ef41Sopenharmony_ci  const typed_arr = new Uint8Array(input_arr);
651cb0ef41Sopenharmony_ci  let blob = new Blob([typed_arr]);
661cb0ef41Sopenharmony_ci  const stream = blob.stream();
671cb0ef41Sopenharmony_ci  blob = null;
681cb0ef41Sopenharmony_ci  garbageCollect();
691cb0ef41Sopenharmony_ci  const chunks = await read_all_chunks(stream, /*perform_gc=*/true);
701cb0ef41Sopenharmony_ci  assert_array_equals(chunks, input_arr);
711cb0ef41Sopenharmony_ci}, "Blob.stream() garbage collection of blob shouldn't break stream" +
721cb0ef41Sopenharmony_ci      "consumption")
73