11cb0ef41Sopenharmony_ci// META: global=window,worker
21cb0ef41Sopenharmony_ci// META: script=../resources/test-utils.js
31cb0ef41Sopenharmony_ci// META: script=../resources/recording-streams.js
41cb0ef41Sopenharmony_ci'use strict';
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciconst error1 = new Error('error1!');
71cb0ef41Sopenharmony_cierror1.name = 'error1';
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst error2 = new Error('error2!');
101cb0ef41Sopenharmony_cierror2.name = 'error2';
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cipromise_test(t => {
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
171cb0ef41Sopenharmony_ci    start() {
181cb0ef41Sopenharmony_ci      return Promise.reject(error1);
191cb0ef41Sopenharmony_ci    }
201cb0ef41Sopenharmony_ci  });
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error')
231cb0ef41Sopenharmony_ci    .then(() => {
241cb0ef41Sopenharmony_ci      assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
251cb0ef41Sopenharmony_ci      assert_array_equals(ws.events, []);
261cb0ef41Sopenharmony_ci    });
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: starts errored; preventCancel omitted; fulfilled cancel promise');
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_cipromise_test(t => {
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
351cb0ef41Sopenharmony_ci    write() {
361cb0ef41Sopenharmony_ci      return Promise.reject(error1);
371cb0ef41Sopenharmony_ci    }
381cb0ef41Sopenharmony_ci  });
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  const writer = ws.getWriter();
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
431cb0ef41Sopenharmony_ci    .then(() => promise_rejects_exactly(t, error1, writer.closed, 'writer.closed must reject with the write error'))
441cb0ef41Sopenharmony_ci    .then(() => {
451cb0ef41Sopenharmony_ci      writer.releaseLock();
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci      return promise_rejects_exactly(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the write error')
481cb0ef41Sopenharmony_ci        .then(() => {
491cb0ef41Sopenharmony_ci          assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
501cb0ef41Sopenharmony_ci          assert_array_equals(ws.events, ['write', 'Hello']);
511cb0ef41Sopenharmony_ci        });
521cb0ef41Sopenharmony_ci    });
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; ' +
551cb0ef41Sopenharmony_ci   'fulfilled cancel promise');
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_cipromise_test(t => {
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
601cb0ef41Sopenharmony_ci    cancel() {
611cb0ef41Sopenharmony_ci      throw error2;
621cb0ef41Sopenharmony_ci    }
631cb0ef41Sopenharmony_ci  });
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
661cb0ef41Sopenharmony_ci    write() {
671cb0ef41Sopenharmony_ci      return Promise.reject(error1);
681cb0ef41Sopenharmony_ci    }
691cb0ef41Sopenharmony_ci  });
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  const writer = ws.getWriter();
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
741cb0ef41Sopenharmony_ci    .then(() => promise_rejects_exactly(t, error1, writer.closed, 'writer.closed must reject with the write error'))
751cb0ef41Sopenharmony_ci    .then(() => {
761cb0ef41Sopenharmony_ci      writer.releaseLock();
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci      return promise_rejects_exactly(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error')
791cb0ef41Sopenharmony_ci        .then(() => {
801cb0ef41Sopenharmony_ci          assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
811cb0ef41Sopenharmony_ci          assert_array_equals(ws.events, ['write', 'Hello']);
821cb0ef41Sopenharmony_ci        });
831cb0ef41Sopenharmony_ci    });
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored before piping due to write; preventCancel omitted; rejected ' +
861cb0ef41Sopenharmony_ci   'cancel promise');
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_cifor (const falsy of [undefined, null, false, +0, -0, NaN, '']) {
891cb0ef41Sopenharmony_ci  const stringVersion = Object.is(falsy, -0) ? '-0' : String(falsy);
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  promise_test(t => {
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci    const rs = recordingReadableStream();
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci    const ws = recordingWritableStream({
961cb0ef41Sopenharmony_ci      write() {
971cb0ef41Sopenharmony_ci        return Promise.reject(error1);
981cb0ef41Sopenharmony_ci      }
991cb0ef41Sopenharmony_ci    });
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci    const writer = ws.getWriter();
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci    return promise_rejects_exactly(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
1041cb0ef41Sopenharmony_ci      .then(() => promise_rejects_exactly(t, error1, writer.closed, 'writer.closed must reject with the write error'))
1051cb0ef41Sopenharmony_ci      .then(() => {
1061cb0ef41Sopenharmony_ci        writer.releaseLock();
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci        return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: falsy }),
1091cb0ef41Sopenharmony_ci                               'pipeTo must reject with the write error')
1101cb0ef41Sopenharmony_ci          .then(() => {
1111cb0ef41Sopenharmony_ci            assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
1121cb0ef41Sopenharmony_ci            assert_array_equals(ws.events, ['write', 'Hello']);
1131cb0ef41Sopenharmony_ci          });
1141cb0ef41Sopenharmony_ci      });
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci  }, `Errors must be propagated backward: becomes errored before piping due to write; preventCancel = ` +
1171cb0ef41Sopenharmony_ci     `${stringVersion} (falsy); fulfilled cancel promise`);
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_cifor (const truthy of [true, 'a', 1, Symbol(), { }]) {
1211cb0ef41Sopenharmony_ci  promise_test(t => {
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci    const rs = recordingReadableStream();
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci    const ws = recordingWritableStream({
1261cb0ef41Sopenharmony_ci      write() {
1271cb0ef41Sopenharmony_ci        return Promise.reject(error1);
1281cb0ef41Sopenharmony_ci      }
1291cb0ef41Sopenharmony_ci    });
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci    const writer = ws.getWriter();
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci    return promise_rejects_exactly(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
1341cb0ef41Sopenharmony_ci      .then(() => promise_rejects_exactly(t, error1, writer.closed, 'writer.closed must reject with the write error'))
1351cb0ef41Sopenharmony_ci      .then(() => {
1361cb0ef41Sopenharmony_ci        writer.releaseLock();
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci        return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: truthy }),
1391cb0ef41Sopenharmony_ci                               'pipeTo must reject with the write error')
1401cb0ef41Sopenharmony_ci          .then(() => {
1411cb0ef41Sopenharmony_ci            assert_array_equals(rs.eventsWithoutPulls, []);
1421cb0ef41Sopenharmony_ci            assert_array_equals(ws.events, ['write', 'Hello']);
1431cb0ef41Sopenharmony_ci          });
1441cb0ef41Sopenharmony_ci      });
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  }, `Errors must be propagated backward: becomes errored before piping due to write; preventCancel = ` +
1471cb0ef41Sopenharmony_ci     `${String(truthy)} (truthy)`);
1481cb0ef41Sopenharmony_ci}
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_cipromise_test(t => {
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
1551cb0ef41Sopenharmony_ci    write() {
1561cb0ef41Sopenharmony_ci      return Promise.reject(error1);
1571cb0ef41Sopenharmony_ci    }
1581cb0ef41Sopenharmony_ci  });
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci  const writer = ws.getWriter();
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
1631cb0ef41Sopenharmony_ci    .then(() => promise_rejects_exactly(t, error1, writer.closed, 'writer.closed must reject with the write error'))
1641cb0ef41Sopenharmony_ci    .then(() => {
1651cb0ef41Sopenharmony_ci      writer.releaseLock();
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci      return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: true, preventAbort: true }),
1681cb0ef41Sopenharmony_ci                             'pipeTo must reject with the write error')
1691cb0ef41Sopenharmony_ci        .then(() => {
1701cb0ef41Sopenharmony_ci          assert_array_equals(rs.eventsWithoutPulls, []);
1711cb0ef41Sopenharmony_ci          assert_array_equals(ws.events, ['write', 'Hello']);
1721cb0ef41Sopenharmony_ci        });
1731cb0ef41Sopenharmony_ci    });
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored before piping due to write, preventCancel = true; ' +
1761cb0ef41Sopenharmony_ci   'preventAbort = true');
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_cipromise_test(t => {
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
1831cb0ef41Sopenharmony_ci    write() {
1841cb0ef41Sopenharmony_ci      return Promise.reject(error1);
1851cb0ef41Sopenharmony_ci    }
1861cb0ef41Sopenharmony_ci  });
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci  const writer = ws.getWriter();
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
1911cb0ef41Sopenharmony_ci    .then(() => promise_rejects_exactly(t, error1, writer.closed, 'writer.closed must reject with the write error'))
1921cb0ef41Sopenharmony_ci    .then(() => {
1931cb0ef41Sopenharmony_ci      writer.releaseLock();
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ci      return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: true, preventAbort: true, preventClose: true }),
1961cb0ef41Sopenharmony_ci                             'pipeTo must reject with the write error')
1971cb0ef41Sopenharmony_ci        .then(() => {
1981cb0ef41Sopenharmony_ci          assert_array_equals(rs.eventsWithoutPulls, []);
1991cb0ef41Sopenharmony_ci          assert_array_equals(ws.events, ['write', 'Hello']);
2001cb0ef41Sopenharmony_ci        });
2011cb0ef41Sopenharmony_ci    });
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored before piping due to write; preventCancel = true, ' +
2041cb0ef41Sopenharmony_ci   'preventAbort = true, preventClose = true');
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_cipromise_test(t => {
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
2091cb0ef41Sopenharmony_ci    start(controller) {
2101cb0ef41Sopenharmony_ci      controller.enqueue('Hello');
2111cb0ef41Sopenharmony_ci    }
2121cb0ef41Sopenharmony_ci  });
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
2151cb0ef41Sopenharmony_ci    write() {
2161cb0ef41Sopenharmony_ci      throw error1;
2171cb0ef41Sopenharmony_ci    }
2181cb0ef41Sopenharmony_ci  });
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error').then(() => {
2211cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
2221cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['write', 'Hello']);
2231cb0ef41Sopenharmony_ci  });
2241cb0ef41Sopenharmony_ci
2251cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; fulfilled ' +
2261cb0ef41Sopenharmony_ci   'cancel promise');
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_cipromise_test(t => {
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
2311cb0ef41Sopenharmony_ci    start(controller) {
2321cb0ef41Sopenharmony_ci      controller.enqueue('Hello');
2331cb0ef41Sopenharmony_ci    },
2341cb0ef41Sopenharmony_ci    cancel() {
2351cb0ef41Sopenharmony_ci      throw error2;
2361cb0ef41Sopenharmony_ci    }
2371cb0ef41Sopenharmony_ci  });
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
2401cb0ef41Sopenharmony_ci    write() {
2411cb0ef41Sopenharmony_ci      throw error1;
2421cb0ef41Sopenharmony_ci    }
2431cb0ef41Sopenharmony_ci  });
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error').then(() => {
2461cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
2471cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['write', 'Hello']);
2481cb0ef41Sopenharmony_ci  });
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored during piping due to write; preventCancel omitted; rejected ' +
2511cb0ef41Sopenharmony_ci   'cancel promise');
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_cipromise_test(t => {
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
2561cb0ef41Sopenharmony_ci    start(controller) {
2571cb0ef41Sopenharmony_ci      controller.enqueue('Hello');
2581cb0ef41Sopenharmony_ci    }
2591cb0ef41Sopenharmony_ci  });
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
2621cb0ef41Sopenharmony_ci    write() {
2631cb0ef41Sopenharmony_ci      throw error1;
2641cb0ef41Sopenharmony_ci    }
2651cb0ef41Sopenharmony_ci  });
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: true }), 'pipeTo must reject with the same error')
2681cb0ef41Sopenharmony_ci  .then(() => {
2691cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, []);
2701cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['write', 'Hello']);
2711cb0ef41Sopenharmony_ci  });
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored during piping due to write; preventCancel = true');
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_cipromise_test(t => {
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
2781cb0ef41Sopenharmony_ci    start(controller) {
2791cb0ef41Sopenharmony_ci      controller.enqueue('a');
2801cb0ef41Sopenharmony_ci      controller.enqueue('b');
2811cb0ef41Sopenharmony_ci      controller.enqueue('c');
2821cb0ef41Sopenharmony_ci    }
2831cb0ef41Sopenharmony_ci  });
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
2861cb0ef41Sopenharmony_ci    write() {
2871cb0ef41Sopenharmony_ci      if (ws.events.length > 2) {
2881cb0ef41Sopenharmony_ci        return delay(0).then(() => {
2891cb0ef41Sopenharmony_ci          throw error1;
2901cb0ef41Sopenharmony_ci        });
2911cb0ef41Sopenharmony_ci      }
2921cb0ef41Sopenharmony_ci      return undefined;
2931cb0ef41Sopenharmony_ci    }
2941cb0ef41Sopenharmony_ci  });
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error').then(() => {
2971cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
2981cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['write', 'a', 'write', 'b']);
2991cb0ef41Sopenharmony_ci  });
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = ' +
3021cb0ef41Sopenharmony_ci   'false; fulfilled cancel promise');
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_cipromise_test(t => {
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
3071cb0ef41Sopenharmony_ci    start(controller) {
3081cb0ef41Sopenharmony_ci      controller.enqueue('a');
3091cb0ef41Sopenharmony_ci      controller.enqueue('b');
3101cb0ef41Sopenharmony_ci      controller.enqueue('c');
3111cb0ef41Sopenharmony_ci    },
3121cb0ef41Sopenharmony_ci    cancel() {
3131cb0ef41Sopenharmony_ci      throw error2;
3141cb0ef41Sopenharmony_ci    }
3151cb0ef41Sopenharmony_ci  });
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
3181cb0ef41Sopenharmony_ci    write() {
3191cb0ef41Sopenharmony_ci      if (ws.events.length > 2) {
3201cb0ef41Sopenharmony_ci        return delay(0).then(() => {
3211cb0ef41Sopenharmony_ci          throw error1;
3221cb0ef41Sopenharmony_ci        });
3231cb0ef41Sopenharmony_ci      }
3241cb0ef41Sopenharmony_ci      return undefined;
3251cb0ef41Sopenharmony_ci    }
3261cb0ef41Sopenharmony_ci  });
3271cb0ef41Sopenharmony_ci
3281cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error').then(() => {
3291cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
3301cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['write', 'a', 'write', 'b']);
3311cb0ef41Sopenharmony_ci  });
3321cb0ef41Sopenharmony_ci
3331cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = ' +
3341cb0ef41Sopenharmony_ci   'false; rejected cancel promise');
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_cipromise_test(t => {
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
3391cb0ef41Sopenharmony_ci    start(controller) {
3401cb0ef41Sopenharmony_ci      controller.enqueue('a');
3411cb0ef41Sopenharmony_ci      controller.enqueue('b');
3421cb0ef41Sopenharmony_ci      controller.enqueue('c');
3431cb0ef41Sopenharmony_ci    }
3441cb0ef41Sopenharmony_ci  });
3451cb0ef41Sopenharmony_ci
3461cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
3471cb0ef41Sopenharmony_ci    write() {
3481cb0ef41Sopenharmony_ci      if (ws.events.length > 2) {
3491cb0ef41Sopenharmony_ci        return delay(0).then(() => {
3501cb0ef41Sopenharmony_ci          throw error1;
3511cb0ef41Sopenharmony_ci        });
3521cb0ef41Sopenharmony_ci      }
3531cb0ef41Sopenharmony_ci      return undefined;
3541cb0ef41Sopenharmony_ci    }
3551cb0ef41Sopenharmony_ci  });
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: true }), 'pipeTo must reject with the same error')
3581cb0ef41Sopenharmony_ci  .then(() => {
3591cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, []);
3601cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['write', 'a', 'write', 'b']);
3611cb0ef41Sopenharmony_ci  });
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored during piping due to write, but async; preventCancel = true');
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_cipromise_test(t => {
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_ci  const ws = recordingWritableStream();
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  const pipePromise = promise_rejects_exactly(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error');
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_ci  t.step_timeout(() => ws.controller.error(error1), 10);
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci  return pipePromise.then(() => {
3761cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
3771cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, []);
3781cb0ef41Sopenharmony_ci  });
3791cb0ef41Sopenharmony_ci
3801cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored after piping; preventCancel omitted; fulfilled cancel promise');
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_cipromise_test(t => {
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
3851cb0ef41Sopenharmony_ci    cancel() {
3861cb0ef41Sopenharmony_ci      throw error2;
3871cb0ef41Sopenharmony_ci    }
3881cb0ef41Sopenharmony_ci  });
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ci  const ws = recordingWritableStream();
3911cb0ef41Sopenharmony_ci
3921cb0ef41Sopenharmony_ci  const pipePromise = promise_rejects_exactly(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error');
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ci  t.step_timeout(() => ws.controller.error(error1), 10);
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_ci  return pipePromise.then(() => {
3971cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
3981cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, []);
3991cb0ef41Sopenharmony_ci  });
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored after piping; preventCancel omitted; rejected cancel promise');
4021cb0ef41Sopenharmony_ci
4031cb0ef41Sopenharmony_cipromise_test(t => {
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
4061cb0ef41Sopenharmony_ci
4071cb0ef41Sopenharmony_ci  const ws = recordingWritableStream();
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci  const pipePromise = promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: true }),
4101cb0ef41Sopenharmony_ci                                              'pipeTo must reject with the same error');
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci  t.step_timeout(() => ws.controller.error(error1), 10);
4131cb0ef41Sopenharmony_ci
4141cb0ef41Sopenharmony_ci  return pipePromise.then(() => {
4151cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, []);
4161cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, []);
4171cb0ef41Sopenharmony_ci  });
4181cb0ef41Sopenharmony_ci
4191cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored after piping; preventCancel = true');
4201cb0ef41Sopenharmony_ci
4211cb0ef41Sopenharmony_cipromise_test(t => {
4221cb0ef41Sopenharmony_ci
4231cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
4241cb0ef41Sopenharmony_ci    start(controller) {
4251cb0ef41Sopenharmony_ci      controller.enqueue('a');
4261cb0ef41Sopenharmony_ci      controller.enqueue('b');
4271cb0ef41Sopenharmony_ci      controller.enqueue('c');
4281cb0ef41Sopenharmony_ci      controller.close();
4291cb0ef41Sopenharmony_ci    }
4301cb0ef41Sopenharmony_ci  });
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
4331cb0ef41Sopenharmony_ci    write(chunk) {
4341cb0ef41Sopenharmony_ci      if (chunk === 'c') {
4351cb0ef41Sopenharmony_ci        return Promise.reject(error1);
4361cb0ef41Sopenharmony_ci      }
4371cb0ef41Sopenharmony_ci      return undefined;
4381cb0ef41Sopenharmony_ci    }
4391cb0ef41Sopenharmony_ci  });
4401cb0ef41Sopenharmony_ci
4411cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error').then(() => {
4421cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, []);
4431cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['write', 'a', 'write', 'b', 'write', 'c']);
4441cb0ef41Sopenharmony_ci  });
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored after piping due to last write; source is closed; ' +
4471cb0ef41Sopenharmony_ci   'preventCancel omitted (but cancel is never called)');
4481cb0ef41Sopenharmony_ci
4491cb0ef41Sopenharmony_cipromise_test(t => {
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
4521cb0ef41Sopenharmony_ci    start(controller) {
4531cb0ef41Sopenharmony_ci      controller.enqueue('a');
4541cb0ef41Sopenharmony_ci      controller.enqueue('b');
4551cb0ef41Sopenharmony_ci      controller.enqueue('c');
4561cb0ef41Sopenharmony_ci      controller.close();
4571cb0ef41Sopenharmony_ci    }
4581cb0ef41Sopenharmony_ci  });
4591cb0ef41Sopenharmony_ci
4601cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
4611cb0ef41Sopenharmony_ci    write(chunk) {
4621cb0ef41Sopenharmony_ci      if (chunk === 'c') {
4631cb0ef41Sopenharmony_ci        return Promise.reject(error1);
4641cb0ef41Sopenharmony_ci      }
4651cb0ef41Sopenharmony_ci      return undefined;
4661cb0ef41Sopenharmony_ci    }
4671cb0ef41Sopenharmony_ci  });
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: true }), 'pipeTo must reject with the same error')
4701cb0ef41Sopenharmony_ci    .then(() => {
4711cb0ef41Sopenharmony_ci      assert_array_equals(rs.eventsWithoutPulls, []);
4721cb0ef41Sopenharmony_ci      assert_array_equals(ws.events, ['write', 'a', 'write', 'b', 'write', 'c']);
4731cb0ef41Sopenharmony_ci    });
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored after piping due to last write; source is closed; ' +
4761cb0ef41Sopenharmony_ci   'preventCancel = true');
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_cipromise_test(t => {
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
4811cb0ef41Sopenharmony_ci
4821cb0ef41Sopenharmony_ci  const ws = recordingWritableStream(undefined, new CountQueuingStrategy({ highWaterMark: 0 }));
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ci  const pipePromise = promise_rejects_exactly(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error');
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci  t.step_timeout(() => ws.controller.error(error1), 10);
4871cb0ef41Sopenharmony_ci
4881cb0ef41Sopenharmony_ci  return pipePromise.then(() => {
4891cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
4901cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, []);
4911cb0ef41Sopenharmony_ci  });
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = ' +
4941cb0ef41Sopenharmony_ci   'false; fulfilled cancel promise');
4951cb0ef41Sopenharmony_ci
4961cb0ef41Sopenharmony_cipromise_test(t => {
4971cb0ef41Sopenharmony_ci
4981cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
4991cb0ef41Sopenharmony_ci    cancel() {
5001cb0ef41Sopenharmony_ci      throw error2;
5011cb0ef41Sopenharmony_ci    }
5021cb0ef41Sopenharmony_ci  });
5031cb0ef41Sopenharmony_ci
5041cb0ef41Sopenharmony_ci  const ws = recordingWritableStream(undefined, new CountQueuingStrategy({ highWaterMark: 0 }));
5051cb0ef41Sopenharmony_ci
5061cb0ef41Sopenharmony_ci  const pipePromise = promise_rejects_exactly(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error');
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_ci  t.step_timeout(() => ws.controller.error(error1), 10);
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_ci  return pipePromise.then(() => {
5111cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
5121cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, []);
5131cb0ef41Sopenharmony_ci  });
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = ' +
5161cb0ef41Sopenharmony_ci   'false; rejected cancel promise');
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_cipromise_test(t => {
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
5211cb0ef41Sopenharmony_ci
5221cb0ef41Sopenharmony_ci  const ws = recordingWritableStream(undefined, new CountQueuingStrategy({ highWaterMark: 0 }));
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci  const pipePromise = promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: true }),
5251cb0ef41Sopenharmony_ci                                              'pipeTo must reject with the same error');
5261cb0ef41Sopenharmony_ci
5271cb0ef41Sopenharmony_ci  t.step_timeout(() => ws.controller.error(error1), 10);
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ci  return pipePromise.then(() => {
5301cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, []);
5311cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, []);
5321cb0ef41Sopenharmony_ci  });
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = ' +
5351cb0ef41Sopenharmony_ci   'true');
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_cipromise_test(() => {
5381cb0ef41Sopenharmony_ci
5391cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_ci  const ws = recordingWritableStream();
5421cb0ef41Sopenharmony_ci
5431cb0ef41Sopenharmony_ci  ws.abort(error1);
5441cb0ef41Sopenharmony_ci
5451cb0ef41Sopenharmony_ci  return rs.pipeTo(ws).then(
5461cb0ef41Sopenharmony_ci    () => assert_unreached('the promise must not fulfill'),
5471cb0ef41Sopenharmony_ci    err => {
5481cb0ef41Sopenharmony_ci      assert_equals(err, error1, 'the promise must reject with error1');
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci      assert_array_equals(rs.eventsWithoutPulls, ['cancel', err]);
5511cb0ef41Sopenharmony_ci      assert_array_equals(ws.events, ['abort', error1]);
5521cb0ef41Sopenharmony_ci    }
5531cb0ef41Sopenharmony_ci  );
5541cb0ef41Sopenharmony_ci
5551cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled ' +
5561cb0ef41Sopenharmony_ci   'cancel promise');
5571cb0ef41Sopenharmony_ci
5581cb0ef41Sopenharmony_cipromise_test(t => {
5591cb0ef41Sopenharmony_ci
5601cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
5611cb0ef41Sopenharmony_ci    cancel() {
5621cb0ef41Sopenharmony_ci      throw error2;
5631cb0ef41Sopenharmony_ci    }
5641cb0ef41Sopenharmony_ci  });
5651cb0ef41Sopenharmony_ci
5661cb0ef41Sopenharmony_ci  const ws = recordingWritableStream();
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci  ws.abort(error1);
5691cb0ef41Sopenharmony_ci
5701cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error')
5711cb0ef41Sopenharmony_ci    .then(() => {
5721cb0ef41Sopenharmony_ci      return ws.getWriter().closed.then(
5731cb0ef41Sopenharmony_ci        () => assert_unreached('the promise must not fulfill'),
5741cb0ef41Sopenharmony_ci        err => {
5751cb0ef41Sopenharmony_ci          assert_equals(err, error1, 'the promise must reject with error1');
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci          assert_array_equals(rs.eventsWithoutPulls, ['cancel', err]);
5781cb0ef41Sopenharmony_ci          assert_array_equals(ws.events, ['abort', error1]);
5791cb0ef41Sopenharmony_ci        }
5801cb0ef41Sopenharmony_ci      );
5811cb0ef41Sopenharmony_ci    });
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected ' +
5841cb0ef41Sopenharmony_ci   'cancel promise');
5851cb0ef41Sopenharmony_ci
5861cb0ef41Sopenharmony_cipromise_test(t => {
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
5891cb0ef41Sopenharmony_ci
5901cb0ef41Sopenharmony_ci  const ws = recordingWritableStream();
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_ci  ws.abort(error1);
5931cb0ef41Sopenharmony_ci
5941cb0ef41Sopenharmony_ci  return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { preventCancel: true })).then(() => {
5951cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, []);
5961cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['abort', error1]);
5971cb0ef41Sopenharmony_ci  });
5981cb0ef41Sopenharmony_ci
5991cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true');
6001cb0ef41Sopenharmony_ci
6011cb0ef41Sopenharmony_cipromise_test(t => {
6021cb0ef41Sopenharmony_ci
6031cb0ef41Sopenharmony_ci  const rs = recordingReadableStream();
6041cb0ef41Sopenharmony_ci
6051cb0ef41Sopenharmony_ci  let resolveWriteCalled;
6061cb0ef41Sopenharmony_ci  const writeCalledPromise = new Promise(resolve => {
6071cb0ef41Sopenharmony_ci    resolveWriteCalled = resolve;
6081cb0ef41Sopenharmony_ci  });
6091cb0ef41Sopenharmony_ci
6101cb0ef41Sopenharmony_ci  const ws = recordingWritableStream({
6111cb0ef41Sopenharmony_ci    write() {
6121cb0ef41Sopenharmony_ci      resolveWriteCalled();
6131cb0ef41Sopenharmony_ci      return flushAsyncEvents();
6141cb0ef41Sopenharmony_ci    }
6151cb0ef41Sopenharmony_ci  });
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_ci  const pipePromise = rs.pipeTo(ws);
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci  rs.controller.enqueue('a');
6201cb0ef41Sopenharmony_ci
6211cb0ef41Sopenharmony_ci  return writeCalledPromise.then(() => {
6221cb0ef41Sopenharmony_ci    ws.controller.error(error1);
6231cb0ef41Sopenharmony_ci
6241cb0ef41Sopenharmony_ci    return promise_rejects_exactly(t, error1, pipePromise);
6251cb0ef41Sopenharmony_ci  }).then(() => {
6261cb0ef41Sopenharmony_ci    assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
6271cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['write', 'a']);
6281cb0ef41Sopenharmony_ci  });
6291cb0ef41Sopenharmony_ci
6301cb0ef41Sopenharmony_ci}, 'Errors must be propagated backward: erroring via the controller errors once pending write completes');
631