11cb0ef41Sopenharmony_ci// META: global=window,worker
21cb0ef41Sopenharmony_ci// META: script=../resources/rs-utils.js
31cb0ef41Sopenharmony_ci'use strict';
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_citest(() => {
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci  assert_throws_js(TypeError, () => new ReadableStreamDefaultReader('potato'));
81cb0ef41Sopenharmony_ci  assert_throws_js(TypeError, () => new ReadableStreamDefaultReader({}));
91cb0ef41Sopenharmony_ci  assert_throws_js(TypeError, () => new ReadableStreamDefaultReader());
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci}, 'ReadableStreamDefaultReader constructor should get a ReadableStream object as argument');
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_citest(() => {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci  const rsReader = new ReadableStreamDefaultReader(new ReadableStream());
161cb0ef41Sopenharmony_ci  assert_equals(rsReader.closed, rsReader.closed, 'closed should return the same promise');
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci}, 'ReadableStreamDefaultReader closed should always return the same promise object');
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_citest(() => {
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
231cb0ef41Sopenharmony_ci  new ReadableStreamDefaultReader(rs); // Constructing directly the first time should be fine.
241cb0ef41Sopenharmony_ci  assert_throws_js(TypeError, () => new ReadableStreamDefaultReader(rs),
251cb0ef41Sopenharmony_ci                   'constructing directly the second time should fail');
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci}, 'Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via direct ' +
281cb0ef41Sopenharmony_ci   'construction)');
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_citest(() => {
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
331cb0ef41Sopenharmony_ci  new ReadableStreamDefaultReader(rs); // Constructing directly should be fine.
341cb0ef41Sopenharmony_ci  assert_throws_js(TypeError, () => rs.getReader(), 'getReader() should fail');
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci}, 'Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via direct ' +
371cb0ef41Sopenharmony_ci   'construction)');
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_citest(() => {
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
421cb0ef41Sopenharmony_ci  rs.getReader(); // getReader() should be fine.
431cb0ef41Sopenharmony_ci  assert_throws_js(TypeError, () => new ReadableStreamDefaultReader(rs), 'constructing directly should fail');
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci}, 'Constructing a ReadableStreamDefaultReader directly should fail if the stream is already locked (via getReader)');
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_citest(() => {
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
501cb0ef41Sopenharmony_ci  rs.getReader(); // getReader() should be fine.
511cb0ef41Sopenharmony_ci  assert_throws_js(TypeError, () => rs.getReader(), 'getReader() should fail');
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci}, 'Getting a ReadableStreamDefaultReader via getReader should fail if the stream is already locked (via getReader)');
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_citest(() => {
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
581cb0ef41Sopenharmony_ci    start(c) {
591cb0ef41Sopenharmony_ci      c.close();
601cb0ef41Sopenharmony_ci    }
611cb0ef41Sopenharmony_ci  });
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  new ReadableStreamDefaultReader(rs); // Constructing directly should not throw.
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci}, 'Constructing a ReadableStreamDefaultReader directly should be OK if the stream is closed');
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_citest(() => {
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  const theError = new Error('don\'t say i didn\'t warn ya');
701cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
711cb0ef41Sopenharmony_ci    start(c) {
721cb0ef41Sopenharmony_ci      c.error(theError);
731cb0ef41Sopenharmony_ci    }
741cb0ef41Sopenharmony_ci  });
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci  new ReadableStreamDefaultReader(rs); // Constructing directly should not throw.
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci}, 'Constructing a ReadableStreamDefaultReader directly should be OK if the stream is errored');
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_cipromise_test(() => {
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  let controller;
831cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
841cb0ef41Sopenharmony_ci    start(c) {
851cb0ef41Sopenharmony_ci      controller = c;
861cb0ef41Sopenharmony_ci    }
871cb0ef41Sopenharmony_ci  });
881cb0ef41Sopenharmony_ci  const reader = rs.getReader();
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  const promise = reader.read().then(result => {
911cb0ef41Sopenharmony_ci    assert_object_equals(result, { value: 'a', done: false }, 'read() should fulfill with the enqueued chunk');
921cb0ef41Sopenharmony_ci  });
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci  controller.enqueue('a');
951cb0ef41Sopenharmony_ci  return promise;
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci}, 'Reading from a reader for an empty stream will wait until a chunk is available');
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_cipromise_test(() => {
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  let cancelCalled = false;
1021cb0ef41Sopenharmony_ci  const passedReason = new Error('it wasn\'t the right time, sorry');
1031cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
1041cb0ef41Sopenharmony_ci    cancel(reason) {
1051cb0ef41Sopenharmony_ci      assert_true(rs.locked, 'the stream should still be locked');
1061cb0ef41Sopenharmony_ci      assert_throws_js(TypeError, () => rs.getReader(), 'should not be able to get another reader');
1071cb0ef41Sopenharmony_ci      assert_equals(reason, passedReason, 'the cancellation reason is passed through to the underlying source');
1081cb0ef41Sopenharmony_ci      cancelCalled = true;
1091cb0ef41Sopenharmony_ci    }
1101cb0ef41Sopenharmony_ci  });
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci  const reader = rs.getReader();
1131cb0ef41Sopenharmony_ci  return reader.cancel(passedReason).then(() => assert_true(cancelCalled));
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci}, 'cancel() on a reader does not release the reader');
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_cipromise_test(() => {
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  let controller;
1201cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
1211cb0ef41Sopenharmony_ci    start(c) {
1221cb0ef41Sopenharmony_ci      controller = c;
1231cb0ef41Sopenharmony_ci    }
1241cb0ef41Sopenharmony_ci  });
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  const reader = rs.getReader();
1271cb0ef41Sopenharmony_ci  const promise = reader.closed;
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  controller.close();
1301cb0ef41Sopenharmony_ci  return promise;
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci}, 'closed should be fulfilled after stream is closed (.closed access before acquiring)');
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_cipromise_test(t => {
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  let controller;
1371cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
1381cb0ef41Sopenharmony_ci    start(c) {
1391cb0ef41Sopenharmony_ci      controller = c;
1401cb0ef41Sopenharmony_ci    }
1411cb0ef41Sopenharmony_ci  });
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  const reader1 = rs.getReader();
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  reader1.releaseLock();
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci  const reader2 = rs.getReader();
1481cb0ef41Sopenharmony_ci  controller.close();
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci  return Promise.all([
1511cb0ef41Sopenharmony_ci    promise_rejects_js(t, TypeError, reader1.closed),
1521cb0ef41Sopenharmony_ci    reader2.closed
1531cb0ef41Sopenharmony_ci  ]);
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci}, 'closed should be rejected after reader releases its lock (multiple stream locks)');
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_cipromise_test(t => {
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci  let controller;
1601cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
1611cb0ef41Sopenharmony_ci    start(c) {
1621cb0ef41Sopenharmony_ci      controller = c;
1631cb0ef41Sopenharmony_ci    }
1641cb0ef41Sopenharmony_ci  });
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  const reader = rs.getReader();
1671cb0ef41Sopenharmony_ci  const promise1 = reader.closed;
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ci  controller.close();
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  reader.releaseLock();
1721cb0ef41Sopenharmony_ci  const promise2 = reader.closed;
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci  assert_not_equals(promise1, promise2, '.closed should be replaced');
1751cb0ef41Sopenharmony_ci  return Promise.all([
1761cb0ef41Sopenharmony_ci    promise1,
1771cb0ef41Sopenharmony_ci    promise_rejects_js(t, TypeError, promise2, '.closed after releasing lock'),
1781cb0ef41Sopenharmony_ci  ]);
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci}, 'closed is replaced when stream closes and reader releases its lock');
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_cipromise_test(t => {
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci  const theError = { name: 'unique error' };
1851cb0ef41Sopenharmony_ci  let controller;
1861cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
1871cb0ef41Sopenharmony_ci    start(c) {
1881cb0ef41Sopenharmony_ci      controller = c;
1891cb0ef41Sopenharmony_ci    }
1901cb0ef41Sopenharmony_ci  });
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ci  const reader = rs.getReader();
1931cb0ef41Sopenharmony_ci  const promise1 = reader.closed;
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ci  controller.error(theError);
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci  reader.releaseLock();
1981cb0ef41Sopenharmony_ci  const promise2 = reader.closed;
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ci  assert_not_equals(promise1, promise2, '.closed should be replaced');
2011cb0ef41Sopenharmony_ci  return Promise.all([
2021cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, theError, promise1, '.closed before releasing lock'),
2031cb0ef41Sopenharmony_ci    promise_rejects_js(t, TypeError, promise2, '.closed after releasing lock')
2041cb0ef41Sopenharmony_ci  ]);
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci}, 'closed is replaced when stream errors and reader releases its lock');
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_cipromise_test(() => {
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2111cb0ef41Sopenharmony_ci    start(c) {
2121cb0ef41Sopenharmony_ci      c.enqueue('a');
2131cb0ef41Sopenharmony_ci      c.enqueue('b');
2141cb0ef41Sopenharmony_ci      c.close();
2151cb0ef41Sopenharmony_ci    }
2161cb0ef41Sopenharmony_ci  });
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci  const reader1 = rs.getReader();
2191cb0ef41Sopenharmony_ci  const promise1 = reader1.read().then(r => {
2201cb0ef41Sopenharmony_ci    assert_object_equals(r, { value: 'a', done: false }, 'reading the first chunk from reader1 works');
2211cb0ef41Sopenharmony_ci  });
2221cb0ef41Sopenharmony_ci  reader1.releaseLock();
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ci  const reader2 = rs.getReader();
2251cb0ef41Sopenharmony_ci  const promise2 = reader2.read().then(r => {
2261cb0ef41Sopenharmony_ci    assert_object_equals(r, { value: 'b', done: false }, 'reading the second chunk from reader2 works');
2271cb0ef41Sopenharmony_ci  });
2281cb0ef41Sopenharmony_ci  reader2.releaseLock();
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci  return Promise.all([promise1, promise2]);
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci}, 'Multiple readers can access the stream in sequence');
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_cipromise_test(() => {
2351cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2361cb0ef41Sopenharmony_ci    start(c) {
2371cb0ef41Sopenharmony_ci      c.enqueue('a');
2381cb0ef41Sopenharmony_ci    }
2391cb0ef41Sopenharmony_ci  });
2401cb0ef41Sopenharmony_ci
2411cb0ef41Sopenharmony_ci  const reader1 = rs.getReader();
2421cb0ef41Sopenharmony_ci  reader1.releaseLock();
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci  const reader2 = rs.getReader();
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_ci  // Should be a no-op
2471cb0ef41Sopenharmony_ci  reader1.releaseLock();
2481cb0ef41Sopenharmony_ci
2491cb0ef41Sopenharmony_ci  return reader2.read().then(result => {
2501cb0ef41Sopenharmony_ci    assert_object_equals(result, { value: 'a', done: false },
2511cb0ef41Sopenharmony_ci                         'read() should still work on reader2 even after reader1 is released');
2521cb0ef41Sopenharmony_ci  });
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_ci}, 'Cannot use an already-released reader to unlock a stream again');
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_cipromise_test(t => {
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2591cb0ef41Sopenharmony_ci    start(c) {
2601cb0ef41Sopenharmony_ci      c.enqueue('a');
2611cb0ef41Sopenharmony_ci    },
2621cb0ef41Sopenharmony_ci    cancel() {
2631cb0ef41Sopenharmony_ci      assert_unreached('underlying source cancel should not be called');
2641cb0ef41Sopenharmony_ci    }
2651cb0ef41Sopenharmony_ci  });
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci  const reader = rs.getReader();
2681cb0ef41Sopenharmony_ci  reader.releaseLock();
2691cb0ef41Sopenharmony_ci  const cancelPromise = reader.cancel();
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci  const reader2 = rs.getReader();
2721cb0ef41Sopenharmony_ci  const readPromise = reader2.read().then(r => {
2731cb0ef41Sopenharmony_ci    assert_object_equals(r, { value: 'a', done: false }, 'a new reader should be able to read a chunk');
2741cb0ef41Sopenharmony_ci  });
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  return Promise.all([
2771cb0ef41Sopenharmony_ci    promise_rejects_js(t, TypeError, cancelPromise),
2781cb0ef41Sopenharmony_ci    readPromise
2791cb0ef41Sopenharmony_ci  ]);
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci}, 'cancel() on a released reader is a no-op and does not pass through');
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_cipromise_test(t => {
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci  const promiseAsserts = [];
2861cb0ef41Sopenharmony_ci
2871cb0ef41Sopenharmony_ci  let controller;
2881cb0ef41Sopenharmony_ci  const theError = { name: 'unique error' };
2891cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2901cb0ef41Sopenharmony_ci    start(c) {
2911cb0ef41Sopenharmony_ci      controller = c;
2921cb0ef41Sopenharmony_ci    }
2931cb0ef41Sopenharmony_ci  });
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci  const reader1 = rs.getReader();
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci  promiseAsserts.push(
2981cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, theError, reader1.closed),
2991cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, theError, reader1.read())
3001cb0ef41Sopenharmony_ci  );
3011cb0ef41Sopenharmony_ci
3021cb0ef41Sopenharmony_ci  assert_throws_js(TypeError, () => rs.getReader(), 'trying to get another reader before erroring should throw');
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  controller.error(theError);
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci  reader1.releaseLock();
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci  const reader2 = rs.getReader();
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  promiseAsserts.push(
3111cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, theError, reader2.closed),
3121cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, theError, reader2.read())
3131cb0ef41Sopenharmony_ci  );
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_ci  return Promise.all(promiseAsserts);
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci}, 'Getting a second reader after erroring the stream and releasing the reader should succeed');
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_cipromise_test(t => {
3201cb0ef41Sopenharmony_ci
3211cb0ef41Sopenharmony_ci  let controller;
3221cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
3231cb0ef41Sopenharmony_ci    start(c) {
3241cb0ef41Sopenharmony_ci      controller = c;
3251cb0ef41Sopenharmony_ci    }
3261cb0ef41Sopenharmony_ci  });
3271cb0ef41Sopenharmony_ci
3281cb0ef41Sopenharmony_ci  const promise = rs.getReader().closed.then(
3291cb0ef41Sopenharmony_ci    t.unreached_func('closed promise should not be fulfilled when stream is errored'),
3301cb0ef41Sopenharmony_ci    err => {
3311cb0ef41Sopenharmony_ci      assert_equals(err, undefined, 'passed error should be undefined as it was');
3321cb0ef41Sopenharmony_ci    }
3331cb0ef41Sopenharmony_ci  );
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ci  controller.error();
3361cb0ef41Sopenharmony_ci  return promise;
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci}, 'ReadableStreamDefaultReader closed promise should be rejected with undefined if that is the error');
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci
3411cb0ef41Sopenharmony_cipromise_test(t => {
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
3441cb0ef41Sopenharmony_ci    start() {
3451cb0ef41Sopenharmony_ci      return Promise.reject();
3461cb0ef41Sopenharmony_ci    }
3471cb0ef41Sopenharmony_ci  });
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci  return rs.getReader().read().then(
3501cb0ef41Sopenharmony_ci    t.unreached_func('read promise should not be fulfilled when stream is errored'),
3511cb0ef41Sopenharmony_ci    err => {
3521cb0ef41Sopenharmony_ci      assert_equals(err, undefined, 'passed error should be undefined as it was');
3531cb0ef41Sopenharmony_ci    }
3541cb0ef41Sopenharmony_ci  );
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_ci}, 'ReadableStreamDefaultReader: if start rejects with no parameter, it should error the stream with an undefined ' +
3571cb0ef41Sopenharmony_ci    'error');
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_cipromise_test(t => {
3601cb0ef41Sopenharmony_ci
3611cb0ef41Sopenharmony_ci  const theError = { name: 'unique string' };
3621cb0ef41Sopenharmony_ci  let controller;
3631cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
3641cb0ef41Sopenharmony_ci    start(c) {
3651cb0ef41Sopenharmony_ci      controller = c;
3661cb0ef41Sopenharmony_ci    }
3671cb0ef41Sopenharmony_ci  });
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_ci  const promise = promise_rejects_exactly(t, theError, rs.getReader().closed);
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  controller.error(theError);
3721cb0ef41Sopenharmony_ci  return promise;
3731cb0ef41Sopenharmony_ci
3741cb0ef41Sopenharmony_ci}, 'Erroring a ReadableStream after checking closed should reject ReadableStreamDefaultReader closed promise');
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_cipromise_test(t => {
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci  const theError = { name: 'unique string' };
3791cb0ef41Sopenharmony_ci  let controller;
3801cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
3811cb0ef41Sopenharmony_ci    start(c) {
3821cb0ef41Sopenharmony_ci      controller = c;
3831cb0ef41Sopenharmony_ci    }
3841cb0ef41Sopenharmony_ci  });
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ci  controller.error(theError);
3871cb0ef41Sopenharmony_ci
3881cb0ef41Sopenharmony_ci  // Let's call getReader twice for extra test coverage of this code path.
3891cb0ef41Sopenharmony_ci  rs.getReader().releaseLock();
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, theError, rs.getReader().closed);
3921cb0ef41Sopenharmony_ci
3931cb0ef41Sopenharmony_ci}, 'Erroring a ReadableStream before checking closed should reject ReadableStreamDefaultReader closed promise');
3941cb0ef41Sopenharmony_ci
3951cb0ef41Sopenharmony_cipromise_test(() => {
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_ci  let controller;
3981cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
3991cb0ef41Sopenharmony_ci    start(c) {
4001cb0ef41Sopenharmony_ci      controller = c;
4011cb0ef41Sopenharmony_ci    }
4021cb0ef41Sopenharmony_ci  });
4031cb0ef41Sopenharmony_ci  const reader = rs.getReader();
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ci  const promise = Promise.all([
4061cb0ef41Sopenharmony_ci    reader.read().then(result => {
4071cb0ef41Sopenharmony_ci      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (1)');
4081cb0ef41Sopenharmony_ci    }),
4091cb0ef41Sopenharmony_ci    reader.read().then(result => {
4101cb0ef41Sopenharmony_ci      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (2)');
4111cb0ef41Sopenharmony_ci    }),
4121cb0ef41Sopenharmony_ci    reader.closed
4131cb0ef41Sopenharmony_ci  ]);
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci  controller.close();
4161cb0ef41Sopenharmony_ci  return promise;
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci}, 'Reading twice on a stream that gets closed');
4191cb0ef41Sopenharmony_ci
4201cb0ef41Sopenharmony_cipromise_test(() => {
4211cb0ef41Sopenharmony_ci
4221cb0ef41Sopenharmony_ci  let controller;
4231cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
4241cb0ef41Sopenharmony_ci    start(c) {
4251cb0ef41Sopenharmony_ci      controller = c;
4261cb0ef41Sopenharmony_ci    }
4271cb0ef41Sopenharmony_ci  });
4281cb0ef41Sopenharmony_ci
4291cb0ef41Sopenharmony_ci  controller.close();
4301cb0ef41Sopenharmony_ci  const reader = rs.getReader();
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_ci  return Promise.all([
4331cb0ef41Sopenharmony_ci    reader.read().then(result => {
4341cb0ef41Sopenharmony_ci      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (1)');
4351cb0ef41Sopenharmony_ci    }),
4361cb0ef41Sopenharmony_ci    reader.read().then(result => {
4371cb0ef41Sopenharmony_ci      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (2)');
4381cb0ef41Sopenharmony_ci    }),
4391cb0ef41Sopenharmony_ci    reader.closed
4401cb0ef41Sopenharmony_ci  ]);
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci}, 'Reading twice on a closed stream');
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_cipromise_test(t => {
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci  let controller;
4471cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
4481cb0ef41Sopenharmony_ci    start(c) {
4491cb0ef41Sopenharmony_ci      controller = c;
4501cb0ef41Sopenharmony_ci    }
4511cb0ef41Sopenharmony_ci  });
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_ci  const myError = { name: 'mashed potatoes' };
4541cb0ef41Sopenharmony_ci  controller.error(myError);
4551cb0ef41Sopenharmony_ci
4561cb0ef41Sopenharmony_ci  const reader = rs.getReader();
4571cb0ef41Sopenharmony_ci
4581cb0ef41Sopenharmony_ci  return Promise.all([
4591cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, myError, reader.read()),
4601cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, myError, reader.read()),
4611cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, myError, reader.closed)
4621cb0ef41Sopenharmony_ci  ]);
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_ci}, 'Reading twice on an errored stream');
4651cb0ef41Sopenharmony_ci
4661cb0ef41Sopenharmony_cipromise_test(t => {
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_ci  let controller;
4691cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
4701cb0ef41Sopenharmony_ci    start(c) {
4711cb0ef41Sopenharmony_ci      controller = c;
4721cb0ef41Sopenharmony_ci    }
4731cb0ef41Sopenharmony_ci  });
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_ci  const myError = { name: 'mashed potatoes' };
4761cb0ef41Sopenharmony_ci  const reader = rs.getReader();
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_ci  const promise = Promise.all([
4791cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, myError, reader.read()),
4801cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, myError, reader.read()),
4811cb0ef41Sopenharmony_ci    promise_rejects_exactly(t, myError, reader.closed)
4821cb0ef41Sopenharmony_ci  ]);
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ci  controller.error(myError);
4851cb0ef41Sopenharmony_ci  return promise;
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_ci}, 'Reading twice on a stream that gets errored');
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_citest(() => {
4901cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
4911cb0ef41Sopenharmony_ci  let toStringCalled = false;
4921cb0ef41Sopenharmony_ci  const mode = {
4931cb0ef41Sopenharmony_ci    toString() {
4941cb0ef41Sopenharmony_ci      toStringCalled = true;
4951cb0ef41Sopenharmony_ci      return '';
4961cb0ef41Sopenharmony_ci    }
4971cb0ef41Sopenharmony_ci  };
4981cb0ef41Sopenharmony_ci  assert_throws_js(TypeError, () => rs.getReader({ mode }), 'getReader() should throw');
4991cb0ef41Sopenharmony_ci  assert_true(toStringCalled, 'toString() should be called');
5001cb0ef41Sopenharmony_ci}, 'getReader() should call ToString() on mode');
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_cipromise_test(() => {
5031cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
5041cb0ef41Sopenharmony_ci    pull(controller) {
5051cb0ef41Sopenharmony_ci      controller.close();
5061cb0ef41Sopenharmony_ci    }
5071cb0ef41Sopenharmony_ci  });
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci  const reader = rs.getReader();
5101cb0ef41Sopenharmony_ci  return reader.read().then(() => {
5111cb0ef41Sopenharmony_ci    // The test passes if releaseLock() does not throw.
5121cb0ef41Sopenharmony_ci    reader.releaseLock();
5131cb0ef41Sopenharmony_ci  });
5141cb0ef41Sopenharmony_ci}, 'controller.close() should clear the list of pending read requests');
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_cipromise_test(t => {
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_ci  let controller;
5191cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
5201cb0ef41Sopenharmony_ci    start(c) {
5211cb0ef41Sopenharmony_ci      controller = c;
5221cb0ef41Sopenharmony_ci    }
5231cb0ef41Sopenharmony_ci  });
5241cb0ef41Sopenharmony_ci
5251cb0ef41Sopenharmony_ci  const reader1 = rs.getReader();
5261cb0ef41Sopenharmony_ci  const promise1 = promise_rejects_js(t, TypeError, reader1.read(), 'read() from reader1 should reject when reader1 is released');
5271cb0ef41Sopenharmony_ci  reader1.releaseLock();
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ci  controller.enqueue('a');
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci  const reader2 = rs.getReader();
5321cb0ef41Sopenharmony_ci  const promise2 = reader2.read().then(r => {
5331cb0ef41Sopenharmony_ci    assert_object_equals(r, { value: 'a', done: false }, 'read() from reader2 should resolve with enqueued chunk');
5341cb0ef41Sopenharmony_ci  })
5351cb0ef41Sopenharmony_ci  reader2.releaseLock();
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_ci  return Promise.all([promise1, promise2]);
5381cb0ef41Sopenharmony_ci
5391cb0ef41Sopenharmony_ci}, 'Second reader can read chunks after first reader was released with pending read requests');
540