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_citest(() => {
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
91cb0ef41Sopenharmony_ci  const ws = new WritableStream();
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci  assert_false(rs.locked, 'sanity check: the ReadableStream must not start locked');
121cb0ef41Sopenharmony_ci  assert_false(ws.locked, 'sanity check: the WritableStream must not start locked');
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci  rs.pipeTo(ws);
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci  assert_true(rs.locked, 'the ReadableStream must become locked');
171cb0ef41Sopenharmony_ci  assert_true(ws.locked, 'the WritableStream must become locked');
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci}, 'Piping must lock both the ReadableStream and WritableStream');
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_cipromise_test(() => {
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
241cb0ef41Sopenharmony_ci    start(controller) {
251cb0ef41Sopenharmony_ci      controller.close();
261cb0ef41Sopenharmony_ci    }
271cb0ef41Sopenharmony_ci  });
281cb0ef41Sopenharmony_ci  const ws = new WritableStream();
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  return rs.pipeTo(ws).then(() => {
311cb0ef41Sopenharmony_ci    assert_false(rs.locked, 'the ReadableStream must become unlocked');
321cb0ef41Sopenharmony_ci    assert_false(ws.locked, 'the WritableStream must become unlocked');
331cb0ef41Sopenharmony_ci  });
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci}, 'Piping finishing must unlock both the ReadableStream and WritableStream');
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cipromise_test(t => {
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  const fakeRS = Object.create(ReadableStream.prototype);
401cb0ef41Sopenharmony_ci  const ws = new WritableStream();
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  return methodRejects(t, ReadableStream.prototype, 'pipeTo', fakeRS, [ws]);
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci}, 'pipeTo must check the brand of its ReadableStream this value');
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_cipromise_test(t => {
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
491cb0ef41Sopenharmony_ci  const fakeWS = Object.create(WritableStream.prototype);
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  return methodRejects(t, ReadableStream.prototype, 'pipeTo', rs, [fakeWS]);
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci}, 'pipeTo must check the brand of its WritableStream argument');
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_cipromise_test(t => {
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
581cb0ef41Sopenharmony_ci  const ws = new WritableStream();
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  rs.getReader();
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  assert_true(rs.locked, 'sanity check: the ReadableStream starts locked');
631cb0ef41Sopenharmony_ci  assert_false(ws.locked, 'sanity check: the WritableStream does not start locked');
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  return promise_rejects_js(t, TypeError, rs.pipeTo(ws)).then(() => {
661cb0ef41Sopenharmony_ci    assert_false(ws.locked, 'the WritableStream must still be unlocked');
671cb0ef41Sopenharmony_ci  });
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci}, 'pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream');
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_cipromise_test(t => {
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
741cb0ef41Sopenharmony_ci  const ws = new WritableStream();
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci  ws.getWriter();
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  assert_false(rs.locked, 'sanity check: the ReadableStream does not start locked');
791cb0ef41Sopenharmony_ci  assert_true(ws.locked, 'sanity check: the WritableStream starts locked');
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  return promise_rejects_js(t, TypeError, rs.pipeTo(ws)).then(() => {
821cb0ef41Sopenharmony_ci    assert_false(rs.locked, 'the ReadableStream must still be unlocked');
831cb0ef41Sopenharmony_ci  });
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci}, 'pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream');
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_cipromise_test(() => {
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  const CHUNKS = 10;
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
921cb0ef41Sopenharmony_ci    start(c) {
931cb0ef41Sopenharmony_ci      for (let i = 0; i < CHUNKS; ++i) {
941cb0ef41Sopenharmony_ci        c.enqueue(i);
951cb0ef41Sopenharmony_ci      }
961cb0ef41Sopenharmony_ci      c.close();
971cb0ef41Sopenharmony_ci    }
981cb0ef41Sopenharmony_ci  });
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  const written = [];
1011cb0ef41Sopenharmony_ci  const ws = new WritableStream({
1021cb0ef41Sopenharmony_ci    write(chunk) {
1031cb0ef41Sopenharmony_ci      written.push(chunk);
1041cb0ef41Sopenharmony_ci    },
1051cb0ef41Sopenharmony_ci    close() {
1061cb0ef41Sopenharmony_ci      written.push('closed');
1071cb0ef41Sopenharmony_ci    }
1081cb0ef41Sopenharmony_ci  }, new CountQueuingStrategy({ highWaterMark: CHUNKS }));
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  return rs.pipeTo(ws).then(() => {
1111cb0ef41Sopenharmony_ci    const targetValues = [];
1121cb0ef41Sopenharmony_ci    for (let i = 0; i < CHUNKS; ++i) {
1131cb0ef41Sopenharmony_ci      targetValues.push(i);
1141cb0ef41Sopenharmony_ci    }
1151cb0ef41Sopenharmony_ci    targetValues.push('closed');
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci    assert_array_equals(written, targetValues, 'the correct values must be written');
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci    // Ensure both readable and writable are closed by the time the pipe finishes.
1201cb0ef41Sopenharmony_ci    return Promise.all([
1211cb0ef41Sopenharmony_ci      rs.getReader().closed,
1221cb0ef41Sopenharmony_ci      ws.getWriter().closed
1231cb0ef41Sopenharmony_ci    ]);
1241cb0ef41Sopenharmony_ci  });
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  // NOTE: no requirement on *when* the pipe finishes; that is left to implementations.
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci}, 'Piping from a ReadableStream from which lots of chunks are synchronously readable');
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_cipromise_test(t => {
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  let controller;
1331cb0ef41Sopenharmony_ci  const rs = recordingReadableStream({
1341cb0ef41Sopenharmony_ci    start(c) {
1351cb0ef41Sopenharmony_ci      controller = c;
1361cb0ef41Sopenharmony_ci    }
1371cb0ef41Sopenharmony_ci  });
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci  const ws = recordingWritableStream();
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci  const pipePromise = rs.pipeTo(ws).then(() => {
1421cb0ef41Sopenharmony_ci    assert_array_equals(ws.events, ['write', 'Hello', 'close']);
1431cb0ef41Sopenharmony_ci  });
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  t.step_timeout(() => {
1461cb0ef41Sopenharmony_ci    controller.enqueue('Hello');
1471cb0ef41Sopenharmony_ci    t.step_timeout(() => controller.close(), 10);
1481cb0ef41Sopenharmony_ci  }, 10);
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci  return pipePromise;
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci}, 'Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo');
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_cifor (const preventAbort of [true, false]) {
1551cb0ef41Sopenharmony_ci  promise_test(() => {
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci    const rs = new ReadableStream({
1581cb0ef41Sopenharmony_ci      pull() {
1591cb0ef41Sopenharmony_ci        return Promise.reject(undefined);
1601cb0ef41Sopenharmony_ci      }
1611cb0ef41Sopenharmony_ci    });
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci    return rs.pipeTo(new WritableStream(), { preventAbort }).then(
1641cb0ef41Sopenharmony_ci        () => assert_unreached('pipeTo promise should be rejected'),
1651cb0ef41Sopenharmony_ci        value => assert_equals(value, undefined, 'rejection value should be undefined'));
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci  }, `an undefined rejection from pull should cause pipeTo() to reject when preventAbort is ${preventAbort}`);
1681cb0ef41Sopenharmony_ci}
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_cifor (const preventCancel of [true, false]) {
1711cb0ef41Sopenharmony_ci  promise_test(() => {
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci    const rs = new ReadableStream({
1741cb0ef41Sopenharmony_ci      pull(controller) {
1751cb0ef41Sopenharmony_ci        controller.enqueue(0);
1761cb0ef41Sopenharmony_ci      }
1771cb0ef41Sopenharmony_ci    });
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci    const ws = new WritableStream({
1801cb0ef41Sopenharmony_ci      write() {
1811cb0ef41Sopenharmony_ci        return Promise.reject(undefined);
1821cb0ef41Sopenharmony_ci      }
1831cb0ef41Sopenharmony_ci    });
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci    return rs.pipeTo(ws, { preventCancel }).then(
1861cb0ef41Sopenharmony_ci         () => assert_unreached('pipeTo promise should be rejected'),
1871cb0ef41Sopenharmony_ci        value => assert_equals(value, undefined, 'rejection value should be undefined'));
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ci  }, `an undefined rejection from write should cause pipeTo() to reject when preventCancel is ${preventCancel}`);
1901cb0ef41Sopenharmony_ci}
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_cipromise_test(t => {
1931cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
1941cb0ef41Sopenharmony_ci  const ws = new WritableStream();
1951cb0ef41Sopenharmony_ci  return promise_rejects_js(t, TypeError, rs.pipeTo(ws, {
1961cb0ef41Sopenharmony_ci    get preventAbort() {
1971cb0ef41Sopenharmony_ci      ws.getWriter();
1981cb0ef41Sopenharmony_ci    }
1991cb0ef41Sopenharmony_ci  }), 'pipeTo should reject');
2001cb0ef41Sopenharmony_ci}, 'pipeTo() should reject if an option getter grabs a writer');
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_cipromise_test(t => {
2031cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
2041cb0ef41Sopenharmony_ci    start(controller) {
2051cb0ef41Sopenharmony_ci      controller.close();
2061cb0ef41Sopenharmony_ci    }
2071cb0ef41Sopenharmony_ci  });
2081cb0ef41Sopenharmony_ci  const ws = new WritableStream();
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci  return rs.pipeTo(ws, null);
2111cb0ef41Sopenharmony_ci}, 'pipeTo() promise should resolve if null is passed');
212