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