11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst { mustCall, mustNotCall } = require('../common');
41cb0ef41Sopenharmony_ciconst { Readable } = require('stream');
51cb0ef41Sopenharmony_ciconst { strictEqual } = require('assert');
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciasync function asyncSupport() {
81cb0ef41Sopenharmony_ci  const finallyMustCall = mustCall();
91cb0ef41Sopenharmony_ci  const bodyMustCall = mustCall();
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci  async function* infiniteGenerate() {
121cb0ef41Sopenharmony_ci    try {
131cb0ef41Sopenharmony_ci      while (true) yield 'a';
141cb0ef41Sopenharmony_ci    } finally {
151cb0ef41Sopenharmony_ci      finallyMustCall();
161cb0ef41Sopenharmony_ci    }
171cb0ef41Sopenharmony_ci  }
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci  const stream = Readable.from(infiniteGenerate());
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci  for await (const chunk of stream) {
221cb0ef41Sopenharmony_ci    bodyMustCall();
231cb0ef41Sopenharmony_ci    strictEqual(chunk, 'a');
241cb0ef41Sopenharmony_ci    break;
251cb0ef41Sopenharmony_ci  }
261cb0ef41Sopenharmony_ci}
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciasync function syncSupport() {
291cb0ef41Sopenharmony_ci  const finallyMustCall = mustCall();
301cb0ef41Sopenharmony_ci  const bodyMustCall = mustCall();
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  function* infiniteGenerate() {
331cb0ef41Sopenharmony_ci    try {
341cb0ef41Sopenharmony_ci      while (true) yield 'a';
351cb0ef41Sopenharmony_ci    } finally {
361cb0ef41Sopenharmony_ci      finallyMustCall();
371cb0ef41Sopenharmony_ci    }
381cb0ef41Sopenharmony_ci  }
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  const stream = Readable.from(infiniteGenerate());
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  for await (const chunk of stream) {
431cb0ef41Sopenharmony_ci    bodyMustCall();
441cb0ef41Sopenharmony_ci    strictEqual(chunk, 'a');
451cb0ef41Sopenharmony_ci    break;
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci}
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ciasync function syncPromiseSupport() {
501cb0ef41Sopenharmony_ci  const returnMustBeAwaited = mustCall();
511cb0ef41Sopenharmony_ci  const bodyMustCall = mustCall();
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  function* infiniteGenerate() {
541cb0ef41Sopenharmony_ci    try {
551cb0ef41Sopenharmony_ci      while (true) yield Promise.resolve('a');
561cb0ef41Sopenharmony_ci    } finally {
571cb0ef41Sopenharmony_ci      // eslint-disable-next-line no-unsafe-finally
581cb0ef41Sopenharmony_ci      return { then(cb) {
591cb0ef41Sopenharmony_ci        returnMustBeAwaited();
601cb0ef41Sopenharmony_ci        cb();
611cb0ef41Sopenharmony_ci      } };
621cb0ef41Sopenharmony_ci    }
631cb0ef41Sopenharmony_ci  }
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  const stream = Readable.from(infiniteGenerate());
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  for await (const chunk of stream) {
681cb0ef41Sopenharmony_ci    bodyMustCall();
691cb0ef41Sopenharmony_ci    strictEqual(chunk, 'a');
701cb0ef41Sopenharmony_ci    break;
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci}
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ciasync function syncRejectedSupport() {
751cb0ef41Sopenharmony_ci  const returnMustBeAwaited = mustCall();
761cb0ef41Sopenharmony_ci  const bodyMustNotCall = mustNotCall();
771cb0ef41Sopenharmony_ci  const catchMustCall = mustCall();
781cb0ef41Sopenharmony_ci  const secondNextMustNotCall = mustNotCall();
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  function* generate() {
811cb0ef41Sopenharmony_ci    try {
821cb0ef41Sopenharmony_ci      yield Promise.reject('a');
831cb0ef41Sopenharmony_ci      secondNextMustNotCall();
841cb0ef41Sopenharmony_ci    } finally {
851cb0ef41Sopenharmony_ci      // eslint-disable-next-line no-unsafe-finally
861cb0ef41Sopenharmony_ci      return { then(cb) {
871cb0ef41Sopenharmony_ci        returnMustBeAwaited();
881cb0ef41Sopenharmony_ci        cb();
891cb0ef41Sopenharmony_ci      } };
901cb0ef41Sopenharmony_ci    }
911cb0ef41Sopenharmony_ci  }
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  const stream = Readable.from(generate());
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  try {
961cb0ef41Sopenharmony_ci    for await (const chunk of stream) {
971cb0ef41Sopenharmony_ci      bodyMustNotCall(chunk);
981cb0ef41Sopenharmony_ci    }
991cb0ef41Sopenharmony_ci  } catch {
1001cb0ef41Sopenharmony_ci    catchMustCall();
1011cb0ef41Sopenharmony_ci  }
1021cb0ef41Sopenharmony_ci}
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ciasync function noReturnAfterThrow() {
1051cb0ef41Sopenharmony_ci  const returnMustNotCall = mustNotCall();
1061cb0ef41Sopenharmony_ci  const bodyMustNotCall = mustNotCall();
1071cb0ef41Sopenharmony_ci  const catchMustCall = mustCall();
1081cb0ef41Sopenharmony_ci  const nextMustCall = mustCall();
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  const stream = Readable.from({
1111cb0ef41Sopenharmony_ci    [Symbol.asyncIterator]() { return this; },
1121cb0ef41Sopenharmony_ci    async next() {
1131cb0ef41Sopenharmony_ci      nextMustCall();
1141cb0ef41Sopenharmony_ci      throw new Error('a');
1151cb0ef41Sopenharmony_ci    },
1161cb0ef41Sopenharmony_ci    async return() {
1171cb0ef41Sopenharmony_ci      returnMustNotCall();
1181cb0ef41Sopenharmony_ci      return { done: true };
1191cb0ef41Sopenharmony_ci    },
1201cb0ef41Sopenharmony_ci  });
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  try {
1231cb0ef41Sopenharmony_ci    for await (const chunk of stream) {
1241cb0ef41Sopenharmony_ci      bodyMustNotCall(chunk);
1251cb0ef41Sopenharmony_ci    }
1261cb0ef41Sopenharmony_ci  } catch {
1271cb0ef41Sopenharmony_ci    catchMustCall();
1281cb0ef41Sopenharmony_ci  }
1291cb0ef41Sopenharmony_ci}
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ciasync function closeStreamWhileNextIsPending() {
1321cb0ef41Sopenharmony_ci  const finallyMustCall = mustCall();
1331cb0ef41Sopenharmony_ci  const dataMustCall = mustCall();
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  let resolveDestroy;
1361cb0ef41Sopenharmony_ci  const destroyed =
1371cb0ef41Sopenharmony_ci    new Promise((resolve) => { resolveDestroy = mustCall(resolve); });
1381cb0ef41Sopenharmony_ci  let resolveYielded;
1391cb0ef41Sopenharmony_ci  const yielded =
1401cb0ef41Sopenharmony_ci    new Promise((resolve) => { resolveYielded = mustCall(resolve); });
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  async function* infiniteGenerate() {
1431cb0ef41Sopenharmony_ci    try {
1441cb0ef41Sopenharmony_ci      while (true) {
1451cb0ef41Sopenharmony_ci        yield 'a';
1461cb0ef41Sopenharmony_ci        resolveYielded();
1471cb0ef41Sopenharmony_ci        await destroyed;
1481cb0ef41Sopenharmony_ci      }
1491cb0ef41Sopenharmony_ci    } finally {
1501cb0ef41Sopenharmony_ci      finallyMustCall();
1511cb0ef41Sopenharmony_ci    }
1521cb0ef41Sopenharmony_ci  }
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci  const stream = Readable.from(infiniteGenerate());
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci  stream.on('data', (data) => {
1571cb0ef41Sopenharmony_ci    dataMustCall();
1581cb0ef41Sopenharmony_ci    strictEqual(data, 'a');
1591cb0ef41Sopenharmony_ci  });
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci  yielded.then(() => {
1621cb0ef41Sopenharmony_ci    stream.destroy();
1631cb0ef41Sopenharmony_ci    resolveDestroy();
1641cb0ef41Sopenharmony_ci  });
1651cb0ef41Sopenharmony_ci}
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ciasync function closeAfterNullYielded() {
1681cb0ef41Sopenharmony_ci  const finallyMustCall = mustCall();
1691cb0ef41Sopenharmony_ci  const dataMustCall = mustCall(3);
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  function* generate() {
1721cb0ef41Sopenharmony_ci    try {
1731cb0ef41Sopenharmony_ci      yield 'a';
1741cb0ef41Sopenharmony_ci      yield 'a';
1751cb0ef41Sopenharmony_ci      yield 'a';
1761cb0ef41Sopenharmony_ci    } finally {
1771cb0ef41Sopenharmony_ci      finallyMustCall();
1781cb0ef41Sopenharmony_ci    }
1791cb0ef41Sopenharmony_ci  }
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci  const stream = Readable.from(generate());
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci  stream.on('data', (chunk) => {
1841cb0ef41Sopenharmony_ci    dataMustCall();
1851cb0ef41Sopenharmony_ci    strictEqual(chunk, 'a');
1861cb0ef41Sopenharmony_ci  });
1871cb0ef41Sopenharmony_ci}
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ciPromise.all([
1901cb0ef41Sopenharmony_ci  asyncSupport(),
1911cb0ef41Sopenharmony_ci  syncSupport(),
1921cb0ef41Sopenharmony_ci  syncPromiseSupport(),
1931cb0ef41Sopenharmony_ci  syncRejectedSupport(),
1941cb0ef41Sopenharmony_ci  noReturnAfterThrow(),
1951cb0ef41Sopenharmony_ci  closeStreamWhileNextIsPending(),
1961cb0ef41Sopenharmony_ci  closeAfterNullYielded(),
1971cb0ef41Sopenharmony_ci]).then(mustCall());
198