11cb0ef41Sopenharmony_ci// META: global=window,worker
21cb0ef41Sopenharmony_ci// META: script=../resources/recording-streams.js
31cb0ef41Sopenharmony_ci// META: script=../resources/test-utils.js
41cb0ef41Sopenharmony_ci'use strict';
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci// Tests for the use of pipeTo with AbortSignal.
71cb0ef41Sopenharmony_ci// There is some extra complexity to avoid timeouts in environments where abort is not implemented.
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst error1 = new Error('error1');
101cb0ef41Sopenharmony_cierror1.name = 'error1';
111cb0ef41Sopenharmony_ciconst error2 = new Error('error2');
121cb0ef41Sopenharmony_cierror2.name = 'error2';
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciconst errorOnPull = {
151cb0ef41Sopenharmony_ci  pull(controller) {
161cb0ef41Sopenharmony_ci    // This will cause the test to error if pipeTo abort is not implemented.
171cb0ef41Sopenharmony_ci    controller.error('failed to abort');
181cb0ef41Sopenharmony_ci  }
191cb0ef41Sopenharmony_ci};
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci// To stop pull() being called immediately when the stream is created, we need to set highWaterMark to 0.
221cb0ef41Sopenharmony_ciconst hwm0 = { highWaterMark: 0 };
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_cifor (const invalidSignal of [null, 'AbortSignal', true, -1, Object.create(AbortSignal.prototype)]) {
251cb0ef41Sopenharmony_ci  promise_test(t => {
261cb0ef41Sopenharmony_ci    const rs = recordingReadableStream(errorOnPull, hwm0);
271cb0ef41Sopenharmony_ci    const ws = recordingWritableStream();
281cb0ef41Sopenharmony_ci    return promise_rejects_js(t, TypeError, rs.pipeTo(ws, { signal: invalidSignal }), 'pipeTo should reject')
291cb0ef41Sopenharmony_ci        .then(() => {
301cb0ef41Sopenharmony_ci          assert_equals(rs.events.length, 0, 'no ReadableStream methods should have been called');
311cb0ef41Sopenharmony_ci          assert_equals(ws.events.length, 0, 'no WritableStream methods should have been called');
321cb0ef41Sopenharmony_ci        });
331cb0ef41Sopenharmony_ci  }, `a signal argument '${invalidSignal}' should cause pipeTo() to reject`);
341cb0ef41Sopenharmony_ci}
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_cipromise_test(t => {
371cb0ef41Sopenharmony_ci  const rs = recordingReadableStream(errorOnPull, hwm0);
381cb0ef41Sopenharmony_ci  const ws = new WritableStream();
391cb0ef41Sopenharmony_ci  const abortController = new AbortController();
401cb0ef41Sopenharmony_ci  const signal = abortController.signal;
411cb0ef41Sopenharmony_ci  abortController.abort();
421cb0ef41Sopenharmony_ci  return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject')
431cb0ef41Sopenharmony_ci      .then(() => Promise.all([
441cb0ef41Sopenharmony_ci        rs.getReader().closed,
451cb0ef41Sopenharmony_ci        promise_rejects_dom(t, 'AbortError', ws.getWriter().closed, 'writer.closed should reject')
461cb0ef41Sopenharmony_ci      ]))
471cb0ef41Sopenharmony_ci      .then(() => {
481cb0ef41Sopenharmony_ci        assert_equals(rs.events.length, 2, 'cancel should have been called');
491cb0ef41Sopenharmony_ci        assert_equals(rs.events[0], 'cancel', 'first event should be cancel');
501cb0ef41Sopenharmony_ci        assert_equals(rs.events[1].name, 'AbortError', 'the argument to cancel should be an AbortError');
511cb0ef41Sopenharmony_ci        assert_equals(rs.events[1].constructor.name, 'DOMException',
521cb0ef41Sopenharmony_ci                      'the argument to cancel should be a DOMException');
531cb0ef41Sopenharmony_ci      });
541cb0ef41Sopenharmony_ci}, 'an aborted signal should cause the writable stream to reject with an AbortError');
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_cifor (const reason of [null, undefined, error1]) {
571cb0ef41Sopenharmony_ci  promise_test(async t => {
581cb0ef41Sopenharmony_ci    const rs = recordingReadableStream(errorOnPull, hwm0);
591cb0ef41Sopenharmony_ci    const ws = new WritableStream();
601cb0ef41Sopenharmony_ci    const abortController = new AbortController();
611cb0ef41Sopenharmony_ci    const signal = abortController.signal;
621cb0ef41Sopenharmony_ci    abortController.abort(reason);
631cb0ef41Sopenharmony_ci    const pipeToPromise = rs.pipeTo(ws, { signal });
641cb0ef41Sopenharmony_ci    if (reason !== undefined) {
651cb0ef41Sopenharmony_ci      await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason');
661cb0ef41Sopenharmony_ci    } else {
671cb0ef41Sopenharmony_ci      await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError');
681cb0ef41Sopenharmony_ci    }
691cb0ef41Sopenharmony_ci    const error = await pipeToPromise.catch(e => e);
701cb0ef41Sopenharmony_ci    await rs.getReader().closed;
711cb0ef41Sopenharmony_ci    await promise_rejects_exactly(t, error, ws.getWriter().closed, 'the writable should be errored with the same object');
721cb0ef41Sopenharmony_ci    assert_equals(signal.reason, error, 'signal.reason should be error'),
731cb0ef41Sopenharmony_ci    assert_equals(rs.events.length, 2, 'cancel should have been called');
741cb0ef41Sopenharmony_ci    assert_equals(rs.events[0], 'cancel', 'first event should be cancel');
751cb0ef41Sopenharmony_ci    assert_equals(rs.events[1], error, 'the readable should be canceled with the same object');
761cb0ef41Sopenharmony_ci  }, `(reason: '${reason}') all the error objects should be the same object`);
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_cipromise_test(t => {
801cb0ef41Sopenharmony_ci  const rs = recordingReadableStream(errorOnPull, hwm0);
811cb0ef41Sopenharmony_ci  const ws = new WritableStream();
821cb0ef41Sopenharmony_ci  const abortController = new AbortController();
831cb0ef41Sopenharmony_ci  const signal = abortController.signal;
841cb0ef41Sopenharmony_ci  abortController.abort();
851cb0ef41Sopenharmony_ci  return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal, preventCancel: true }), 'pipeTo should reject')
861cb0ef41Sopenharmony_ci      .then(() => assert_equals(rs.events.length, 0, 'cancel should not be called'));
871cb0ef41Sopenharmony_ci}, 'preventCancel should prevent canceling the readable');
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_cipromise_test(t => {
901cb0ef41Sopenharmony_ci  const rs = new ReadableStream(errorOnPull, hwm0);
911cb0ef41Sopenharmony_ci  const ws = recordingWritableStream();
921cb0ef41Sopenharmony_ci  const abortController = new AbortController();
931cb0ef41Sopenharmony_ci  const signal = abortController.signal;
941cb0ef41Sopenharmony_ci  abortController.abort();
951cb0ef41Sopenharmony_ci  return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal, preventAbort: true }), 'pipeTo should reject')
961cb0ef41Sopenharmony_ci      .then(() => {
971cb0ef41Sopenharmony_ci        assert_equals(ws.events.length, 0, 'writable should not have been aborted');
981cb0ef41Sopenharmony_ci        return ws.getWriter().ready;
991cb0ef41Sopenharmony_ci      });
1001cb0ef41Sopenharmony_ci}, 'preventAbort should prevent aborting the readable');
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_cipromise_test(t => {
1031cb0ef41Sopenharmony_ci  const rs = recordingReadableStream(errorOnPull, hwm0);
1041cb0ef41Sopenharmony_ci  const ws = recordingWritableStream();
1051cb0ef41Sopenharmony_ci  const abortController = new AbortController();
1061cb0ef41Sopenharmony_ci  const signal = abortController.signal;
1071cb0ef41Sopenharmony_ci  abortController.abort();
1081cb0ef41Sopenharmony_ci  return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal, preventCancel: true, preventAbort: true }),
1091cb0ef41Sopenharmony_ci                         'pipeTo should reject')
1101cb0ef41Sopenharmony_ci    .then(() => {
1111cb0ef41Sopenharmony_ci      assert_equals(rs.events.length, 0, 'cancel should not be called');
1121cb0ef41Sopenharmony_ci      assert_equals(ws.events.length, 0, 'writable should not have been aborted');
1131cb0ef41Sopenharmony_ci      return ws.getWriter().ready;
1141cb0ef41Sopenharmony_ci    });
1151cb0ef41Sopenharmony_ci}, 'preventCancel and preventAbort should prevent canceling the readable and aborting the readable');
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_cifor (const reason of [null, undefined, error1]) {
1181cb0ef41Sopenharmony_ci  promise_test(async t => {
1191cb0ef41Sopenharmony_ci    const rs = new ReadableStream({
1201cb0ef41Sopenharmony_ci      start(controller) {
1211cb0ef41Sopenharmony_ci        controller.enqueue('a');
1221cb0ef41Sopenharmony_ci        controller.enqueue('b');
1231cb0ef41Sopenharmony_ci        controller.close();
1241cb0ef41Sopenharmony_ci      }
1251cb0ef41Sopenharmony_ci    });
1261cb0ef41Sopenharmony_ci    const abortController = new AbortController();
1271cb0ef41Sopenharmony_ci    const signal = abortController.signal;
1281cb0ef41Sopenharmony_ci    const ws = recordingWritableStream({
1291cb0ef41Sopenharmony_ci      write() {
1301cb0ef41Sopenharmony_ci        abortController.abort(reason);
1311cb0ef41Sopenharmony_ci      }
1321cb0ef41Sopenharmony_ci    });
1331cb0ef41Sopenharmony_ci    const pipeToPromise = rs.pipeTo(ws, { signal });
1341cb0ef41Sopenharmony_ci    if (reason !== undefined) {
1351cb0ef41Sopenharmony_ci      await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason');
1361cb0ef41Sopenharmony_ci    } else {
1371cb0ef41Sopenharmony_ci      await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError');
1381cb0ef41Sopenharmony_ci    }
1391cb0ef41Sopenharmony_ci    const error = await pipeToPromise.catch(e => e);
1401cb0ef41Sopenharmony_ci    assert_equals(signal.reason, error, 'signal.reason should be error');
1411cb0ef41Sopenharmony_ci    assert_equals(ws.events.length, 4, 'only chunk "a" should have been written');
1421cb0ef41Sopenharmony_ci    assert_array_equals(ws.events.slice(0, 3), ['write', 'a', 'abort'], 'events should match');
1431cb0ef41Sopenharmony_ci    assert_equals(ws.events[3], error, 'abort reason should be error');
1441cb0ef41Sopenharmony_ci  }, `(reason: '${reason}') abort should prevent further reads`);
1451cb0ef41Sopenharmony_ci}
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_cifor (const reason of [null, undefined, error1]) {
1481cb0ef41Sopenharmony_ci  promise_test(async t => {
1491cb0ef41Sopenharmony_ci    let readController;
1501cb0ef41Sopenharmony_ci    const rs = new ReadableStream({
1511cb0ef41Sopenharmony_ci      start(c) {
1521cb0ef41Sopenharmony_ci        readController = c;
1531cb0ef41Sopenharmony_ci        c.enqueue('a');
1541cb0ef41Sopenharmony_ci        c.enqueue('b');
1551cb0ef41Sopenharmony_ci      }
1561cb0ef41Sopenharmony_ci    });
1571cb0ef41Sopenharmony_ci    const abortController = new AbortController();
1581cb0ef41Sopenharmony_ci    const signal = abortController.signal;
1591cb0ef41Sopenharmony_ci    let resolveWrite;
1601cb0ef41Sopenharmony_ci    const writePromise = new Promise(resolve => {
1611cb0ef41Sopenharmony_ci      resolveWrite = resolve;
1621cb0ef41Sopenharmony_ci    });
1631cb0ef41Sopenharmony_ci    const ws = recordingWritableStream({
1641cb0ef41Sopenharmony_ci      write() {
1651cb0ef41Sopenharmony_ci        return writePromise;
1661cb0ef41Sopenharmony_ci      }
1671cb0ef41Sopenharmony_ci    }, new CountQueuingStrategy({ highWaterMark: Infinity }));
1681cb0ef41Sopenharmony_ci    const pipeToPromise = rs.pipeTo(ws, { signal });
1691cb0ef41Sopenharmony_ci    await delay(0);
1701cb0ef41Sopenharmony_ci    await abortController.abort(reason);
1711cb0ef41Sopenharmony_ci    await readController.close(); // Make sure the test terminates when signal is not implemented.
1721cb0ef41Sopenharmony_ci    await resolveWrite();
1731cb0ef41Sopenharmony_ci    if (reason !== undefined) {
1741cb0ef41Sopenharmony_ci      await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason');
1751cb0ef41Sopenharmony_ci    } else {
1761cb0ef41Sopenharmony_ci      await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError');
1771cb0ef41Sopenharmony_ci    }
1781cb0ef41Sopenharmony_ci    const error = await pipeToPromise.catch(e => e);
1791cb0ef41Sopenharmony_ci    assert_equals(signal.reason, error, 'signal.reason should be error');
1801cb0ef41Sopenharmony_ci    assert_equals(ws.events.length, 6, 'chunks "a" and "b" should have been written');
1811cb0ef41Sopenharmony_ci    assert_array_equals(ws.events.slice(0, 5), ['write', 'a', 'write', 'b', 'abort'], 'events should match');
1821cb0ef41Sopenharmony_ci    assert_equals(ws.events[5], error, 'abort reason should be error');
1831cb0ef41Sopenharmony_ci  }, `(reason: '${reason}') all pending writes should complete on abort`);
1841cb0ef41Sopenharmony_ci}
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_cipromise_test(t => {
1871cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
1881cb0ef41Sopenharmony_ci    pull(controller) {
1891cb0ef41Sopenharmony_ci      controller.error('failed to abort');
1901cb0ef41Sopenharmony_ci    },
1911cb0ef41Sopenharmony_ci    cancel() {
1921cb0ef41Sopenharmony_ci      return Promise.reject(error1);
1931cb0ef41Sopenharmony_ci    }
1941cb0ef41Sopenharmony_ci  }, hwm0);
1951cb0ef41Sopenharmony_ci  const ws = new WritableStream();
1961cb0ef41Sopenharmony_ci  const abortController = new AbortController();
1971cb0ef41Sopenharmony_ci  const signal = abortController.signal;
1981cb0ef41Sopenharmony_ci  abortController.abort();
1991cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { signal }), 'pipeTo should reject');
2001cb0ef41Sopenharmony_ci}, 'a rejection from underlyingSource.cancel() should be returned by pipeTo()');
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_cipromise_test(t => {
2031cb0ef41Sopenharmony_ci  const rs = new ReadableStream(errorOnPull, hwm0);
2041cb0ef41Sopenharmony_ci  const ws = new WritableStream({
2051cb0ef41Sopenharmony_ci    abort() {
2061cb0ef41Sopenharmony_ci      return Promise.reject(error1);
2071cb0ef41Sopenharmony_ci    }
2081cb0ef41Sopenharmony_ci  });
2091cb0ef41Sopenharmony_ci  const abortController = new AbortController();
2101cb0ef41Sopenharmony_ci  const signal = abortController.signal;
2111cb0ef41Sopenharmony_ci  abortController.abort();
2121cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { signal }), 'pipeTo should reject');
2131cb0ef41Sopenharmony_ci}, 'a rejection from underlyingSink.abort() should be returned by pipeTo()');
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_cipromise_test(t => {
2161cb0ef41Sopenharmony_ci  const events = [];
2171cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2181cb0ef41Sopenharmony_ci    pull(controller) {
2191cb0ef41Sopenharmony_ci      controller.error('failed to abort');
2201cb0ef41Sopenharmony_ci    },
2211cb0ef41Sopenharmony_ci    cancel() {
2221cb0ef41Sopenharmony_ci      events.push('cancel');
2231cb0ef41Sopenharmony_ci      return Promise.reject(error1);
2241cb0ef41Sopenharmony_ci    }
2251cb0ef41Sopenharmony_ci  }, hwm0);
2261cb0ef41Sopenharmony_ci  const ws = new WritableStream({
2271cb0ef41Sopenharmony_ci    abort() {
2281cb0ef41Sopenharmony_ci      events.push('abort');
2291cb0ef41Sopenharmony_ci      return Promise.reject(error2);
2301cb0ef41Sopenharmony_ci    }
2311cb0ef41Sopenharmony_ci  });
2321cb0ef41Sopenharmony_ci  const abortController = new AbortController();
2331cb0ef41Sopenharmony_ci  const signal = abortController.signal;
2341cb0ef41Sopenharmony_ci  abortController.abort();
2351cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error2, rs.pipeTo(ws, { signal }), 'pipeTo should reject')
2361cb0ef41Sopenharmony_ci      .then(() => assert_array_equals(events, ['abort', 'cancel'], 'abort() should be called before cancel()'));
2371cb0ef41Sopenharmony_ci}, 'a rejection from underlyingSink.abort() should be preferred to one from underlyingSource.cancel()');
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_cipromise_test(t => {
2401cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2411cb0ef41Sopenharmony_ci    start(controller) {
2421cb0ef41Sopenharmony_ci      controller.close();
2431cb0ef41Sopenharmony_ci    }
2441cb0ef41Sopenharmony_ci  });
2451cb0ef41Sopenharmony_ci  const ws = new WritableStream();
2461cb0ef41Sopenharmony_ci  const abortController = new AbortController();
2471cb0ef41Sopenharmony_ci  const signal = abortController.signal;
2481cb0ef41Sopenharmony_ci  abortController.abort();
2491cb0ef41Sopenharmony_ci  return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject');
2501cb0ef41Sopenharmony_ci}, 'abort signal takes priority over closed readable');
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_cipromise_test(t => {
2531cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2541cb0ef41Sopenharmony_ci    start(controller) {
2551cb0ef41Sopenharmony_ci      controller.error(error1);
2561cb0ef41Sopenharmony_ci    }
2571cb0ef41Sopenharmony_ci  });
2581cb0ef41Sopenharmony_ci  const ws = new WritableStream();
2591cb0ef41Sopenharmony_ci  const abortController = new AbortController();
2601cb0ef41Sopenharmony_ci  const signal = abortController.signal;
2611cb0ef41Sopenharmony_ci  abortController.abort();
2621cb0ef41Sopenharmony_ci  return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject');
2631cb0ef41Sopenharmony_ci}, 'abort signal takes priority over errored readable');
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_cipromise_test(t => {
2661cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2671cb0ef41Sopenharmony_ci    pull(controller) {
2681cb0ef41Sopenharmony_ci      controller.error('failed to abort');
2691cb0ef41Sopenharmony_ci    }
2701cb0ef41Sopenharmony_ci  }, hwm0);
2711cb0ef41Sopenharmony_ci  const ws = new WritableStream();
2721cb0ef41Sopenharmony_ci  const abortController = new AbortController();
2731cb0ef41Sopenharmony_ci  const signal = abortController.signal;
2741cb0ef41Sopenharmony_ci  abortController.abort();
2751cb0ef41Sopenharmony_ci  const writer = ws.getWriter();
2761cb0ef41Sopenharmony_ci  return writer.close().then(() => {
2771cb0ef41Sopenharmony_ci    writer.releaseLock();
2781cb0ef41Sopenharmony_ci    return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject');
2791cb0ef41Sopenharmony_ci  });
2801cb0ef41Sopenharmony_ci}, 'abort signal takes priority over closed writable');
2811cb0ef41Sopenharmony_ci
2821cb0ef41Sopenharmony_cipromise_test(t => {
2831cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2841cb0ef41Sopenharmony_ci    pull(controller) {
2851cb0ef41Sopenharmony_ci      controller.error('failed to abort');
2861cb0ef41Sopenharmony_ci    }
2871cb0ef41Sopenharmony_ci  }, hwm0);
2881cb0ef41Sopenharmony_ci  const ws = new WritableStream({
2891cb0ef41Sopenharmony_ci    start(controller) {
2901cb0ef41Sopenharmony_ci      controller.error(error1);
2911cb0ef41Sopenharmony_ci    }
2921cb0ef41Sopenharmony_ci  });
2931cb0ef41Sopenharmony_ci  const abortController = new AbortController();
2941cb0ef41Sopenharmony_ci  const signal = abortController.signal;
2951cb0ef41Sopenharmony_ci  abortController.abort();
2961cb0ef41Sopenharmony_ci  return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject');
2971cb0ef41Sopenharmony_ci}, 'abort signal takes priority over errored writable');
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_cipromise_test(() => {
3001cb0ef41Sopenharmony_ci  let readController;
3011cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
3021cb0ef41Sopenharmony_ci    start(c) {
3031cb0ef41Sopenharmony_ci      readController = c;
3041cb0ef41Sopenharmony_ci    }
3051cb0ef41Sopenharmony_ci  });
3061cb0ef41Sopenharmony_ci  const ws = new WritableStream();
3071cb0ef41Sopenharmony_ci  const abortController = new AbortController();
3081cb0ef41Sopenharmony_ci  const signal = abortController.signal;
3091cb0ef41Sopenharmony_ci  const pipeToPromise = rs.pipeTo(ws, { signal, preventClose: true });
3101cb0ef41Sopenharmony_ci  readController.close();
3111cb0ef41Sopenharmony_ci  return Promise.resolve().then(() => {
3121cb0ef41Sopenharmony_ci    abortController.abort();
3131cb0ef41Sopenharmony_ci    return pipeToPromise;
3141cb0ef41Sopenharmony_ci  }).then(() => ws.getWriter().write('this should succeed'));
3151cb0ef41Sopenharmony_ci}, 'abort should do nothing after the readable is closed');
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_cipromise_test(t => {
3181cb0ef41Sopenharmony_ci  let readController;
3191cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
3201cb0ef41Sopenharmony_ci    start(c) {
3211cb0ef41Sopenharmony_ci      readController = c;
3221cb0ef41Sopenharmony_ci    }
3231cb0ef41Sopenharmony_ci  });
3241cb0ef41Sopenharmony_ci  const ws = new WritableStream();
3251cb0ef41Sopenharmony_ci  const abortController = new AbortController();
3261cb0ef41Sopenharmony_ci  const signal = abortController.signal;
3271cb0ef41Sopenharmony_ci  const pipeToPromise = rs.pipeTo(ws, { signal, preventAbort: true });
3281cb0ef41Sopenharmony_ci  readController.error(error1);
3291cb0ef41Sopenharmony_ci  return Promise.resolve().then(() => {
3301cb0ef41Sopenharmony_ci    abortController.abort();
3311cb0ef41Sopenharmony_ci    return promise_rejects_exactly(t, error1, pipeToPromise, 'pipeTo should reject');
3321cb0ef41Sopenharmony_ci  }).then(() => ws.getWriter().write('this should succeed'));
3331cb0ef41Sopenharmony_ci}, 'abort should do nothing after the readable is errored');
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_cipromise_test(t => {
3361cb0ef41Sopenharmony_ci  let readController;
3371cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
3381cb0ef41Sopenharmony_ci    start(c) {
3391cb0ef41Sopenharmony_ci      readController = c;
3401cb0ef41Sopenharmony_ci    }
3411cb0ef41Sopenharmony_ci  });
3421cb0ef41Sopenharmony_ci  let resolveWrite;
3431cb0ef41Sopenharmony_ci  const writePromise = new Promise(resolve => {
3441cb0ef41Sopenharmony_ci    resolveWrite = resolve;
3451cb0ef41Sopenharmony_ci  });
3461cb0ef41Sopenharmony_ci  const ws = new WritableStream({
3471cb0ef41Sopenharmony_ci    write() {
3481cb0ef41Sopenharmony_ci      readController.error(error1);
3491cb0ef41Sopenharmony_ci      return writePromise;
3501cb0ef41Sopenharmony_ci    }
3511cb0ef41Sopenharmony_ci  });
3521cb0ef41Sopenharmony_ci  const abortController = new AbortController();
3531cb0ef41Sopenharmony_ci  const signal = abortController.signal;
3541cb0ef41Sopenharmony_ci  const pipeToPromise = rs.pipeTo(ws, { signal, preventAbort: true });
3551cb0ef41Sopenharmony_ci  readController.enqueue('a');
3561cb0ef41Sopenharmony_ci  return delay(0).then(() => {
3571cb0ef41Sopenharmony_ci    abortController.abort();
3581cb0ef41Sopenharmony_ci    resolveWrite();
3591cb0ef41Sopenharmony_ci    return promise_rejects_exactly(t, error1, pipeToPromise, 'pipeTo should reject');
3601cb0ef41Sopenharmony_ci  }).then(() => ws.getWriter().write('this should succeed'));
3611cb0ef41Sopenharmony_ci}, 'abort should do nothing after the readable is errored, even with pending writes');
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_cipromise_test(t => {
3641cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
3651cb0ef41Sopenharmony_ci    pull(controller) {
3661cb0ef41Sopenharmony_ci      return delay(0).then(() => controller.close());
3671cb0ef41Sopenharmony_ci    }
3681cb0ef41Sopenharmony_ci  });
3691cb0ef41Sopenharmony_ci  let writeController;
3701cb0ef41Sopenharmony_ci  const ws = new WritableStream({
3711cb0ef41Sopenharmony_ci    start(c) {
3721cb0ef41Sopenharmony_ci      writeController = c;
3731cb0ef41Sopenharmony_ci    }
3741cb0ef41Sopenharmony_ci  });
3751cb0ef41Sopenharmony_ci  const abortController = new AbortController();
3761cb0ef41Sopenharmony_ci  const signal = abortController.signal;
3771cb0ef41Sopenharmony_ci  const pipeToPromise = rs.pipeTo(ws, { signal, preventCancel: true });
3781cb0ef41Sopenharmony_ci  return Promise.resolve().then(() => {
3791cb0ef41Sopenharmony_ci    writeController.error(error1);
3801cb0ef41Sopenharmony_ci    return Promise.resolve();
3811cb0ef41Sopenharmony_ci  }).then(() => {
3821cb0ef41Sopenharmony_ci    abortController.abort();
3831cb0ef41Sopenharmony_ci    return promise_rejects_exactly(t, error1, pipeToPromise, 'pipeTo should reject');
3841cb0ef41Sopenharmony_ci  }).then(() => {
3851cb0ef41Sopenharmony_ci    assert_array_equals(rs.events, ['pull'], 'cancel should not have been called');
3861cb0ef41Sopenharmony_ci  });
3871cb0ef41Sopenharmony_ci}, 'abort should do nothing after the writable is errored');
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_cipromise_test(async t => {
3901cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
3911cb0ef41Sopenharmony_ci    pull(c) {
3921cb0ef41Sopenharmony_ci      c.enqueue(new Uint8Array([]));
3931cb0ef41Sopenharmony_ci    },
3941cb0ef41Sopenharmony_ci    type: "bytes",
3951cb0ef41Sopenharmony_ci  });
3961cb0ef41Sopenharmony_ci  const ws = new WritableStream();
3971cb0ef41Sopenharmony_ci  const [first, second] = rs.tee();
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci  let aborted = false;
4001cb0ef41Sopenharmony_ci  first.pipeTo(ws, { signal: AbortSignal.abort() }).catch(() => {
4011cb0ef41Sopenharmony_ci    aborted = true;
4021cb0ef41Sopenharmony_ci  });
4031cb0ef41Sopenharmony_ci  await delay(0);
4041cb0ef41Sopenharmony_ci  assert_true(!aborted, "pipeTo should not resolve yet");
4051cb0ef41Sopenharmony_ci  await second.cancel();
4061cb0ef41Sopenharmony_ci  await delay(0);
4071cb0ef41Sopenharmony_ci  assert_true(aborted, "pipeTo should be aborted now");
4081cb0ef41Sopenharmony_ci}, "pipeTo on a teed readable byte stream should only be aborted when both branches are aborted");
409