11cb0ef41Sopenharmony_ci// META: global=window,worker 21cb0ef41Sopenharmony_ci// META: script=../resources/rs-utils.js 31cb0ef41Sopenharmony_ci// META: script=../resources/test-utils.js 41cb0ef41Sopenharmony_ci// META: script=../resources/recording-streams.js 51cb0ef41Sopenharmony_ci'use strict'; 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst error1 = new Error('error1'); 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_cifunction assert_iter_result(iterResult, value, done, message) { 101cb0ef41Sopenharmony_ci const prefix = message === undefined ? '' : `${message} `; 111cb0ef41Sopenharmony_ci assert_equals(typeof iterResult, 'object', `${prefix}type is object`); 121cb0ef41Sopenharmony_ci assert_equals(Object.getPrototypeOf(iterResult), Object.prototype, `${prefix}[[Prototype]]`); 131cb0ef41Sopenharmony_ci assert_array_equals(Object.getOwnPropertyNames(iterResult).sort(), ['done', 'value'], `${prefix}property names`); 141cb0ef41Sopenharmony_ci assert_equals(iterResult.value, value, `${prefix}value`); 151cb0ef41Sopenharmony_ci assert_equals(iterResult.done, done, `${prefix}done`); 161cb0ef41Sopenharmony_ci} 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_citest(() => { 191cb0ef41Sopenharmony_ci const s = new ReadableStream(); 201cb0ef41Sopenharmony_ci const it = s.values(); 211cb0ef41Sopenharmony_ci const proto = Object.getPrototypeOf(it); 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {}).prototype); 241cb0ef41Sopenharmony_ci assert_equals(Object.getPrototypeOf(proto), AsyncIteratorPrototype, 'prototype should extend AsyncIteratorPrototype'); 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci const methods = ['next', 'return'].sort(); 271cb0ef41Sopenharmony_ci assert_array_equals(Object.getOwnPropertyNames(proto).sort(), methods, 'should have all the correct methods'); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci for (const m of methods) { 301cb0ef41Sopenharmony_ci const propDesc = Object.getOwnPropertyDescriptor(proto, m); 311cb0ef41Sopenharmony_ci assert_true(propDesc.enumerable, 'method should be enumerable'); 321cb0ef41Sopenharmony_ci assert_true(propDesc.configurable, 'method should be configurable'); 331cb0ef41Sopenharmony_ci assert_true(propDesc.writable, 'method should be writable'); 341cb0ef41Sopenharmony_ci assert_equals(typeof it[m], 'function', 'method should be a function'); 351cb0ef41Sopenharmony_ci assert_equals(it[m].name, m, 'method should have the correct name'); 361cb0ef41Sopenharmony_ci } 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci assert_equals(it.next.length, 0, 'next should have no parameters'); 391cb0ef41Sopenharmony_ci assert_equals(it.return.length, 1, 'return should have 1 parameter'); 401cb0ef41Sopenharmony_ci assert_equals(typeof it.throw, 'undefined', 'throw should not exist'); 411cb0ef41Sopenharmony_ci}, 'Async iterator instances should have the correct list of properties'); 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_cipromise_test(async () => { 441cb0ef41Sopenharmony_ci const s = new ReadableStream({ 451cb0ef41Sopenharmony_ci start(c) { 461cb0ef41Sopenharmony_ci c.enqueue(1); 471cb0ef41Sopenharmony_ci c.enqueue(2); 481cb0ef41Sopenharmony_ci c.enqueue(3); 491cb0ef41Sopenharmony_ci c.close(); 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci }); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci const chunks = []; 541cb0ef41Sopenharmony_ci for await (const chunk of s) { 551cb0ef41Sopenharmony_ci chunks.push(chunk); 561cb0ef41Sopenharmony_ci } 571cb0ef41Sopenharmony_ci assert_array_equals(chunks, [1, 2, 3]); 581cb0ef41Sopenharmony_ci}, 'Async-iterating a push source'); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_cipromise_test(async () => { 611cb0ef41Sopenharmony_ci let i = 1; 621cb0ef41Sopenharmony_ci const s = new ReadableStream({ 631cb0ef41Sopenharmony_ci pull(c) { 641cb0ef41Sopenharmony_ci c.enqueue(i); 651cb0ef41Sopenharmony_ci if (i >= 3) { 661cb0ef41Sopenharmony_ci c.close(); 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci i += 1; 691cb0ef41Sopenharmony_ci } 701cb0ef41Sopenharmony_ci }); 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci const chunks = []; 731cb0ef41Sopenharmony_ci for await (const chunk of s) { 741cb0ef41Sopenharmony_ci chunks.push(chunk); 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci assert_array_equals(chunks, [1, 2, 3]); 771cb0ef41Sopenharmony_ci}, 'Async-iterating a pull source'); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_cipromise_test(async () => { 801cb0ef41Sopenharmony_ci const s = new ReadableStream({ 811cb0ef41Sopenharmony_ci start(c) { 821cb0ef41Sopenharmony_ci c.enqueue(undefined); 831cb0ef41Sopenharmony_ci c.enqueue(undefined); 841cb0ef41Sopenharmony_ci c.enqueue(undefined); 851cb0ef41Sopenharmony_ci c.close(); 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci }); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci const chunks = []; 901cb0ef41Sopenharmony_ci for await (const chunk of s) { 911cb0ef41Sopenharmony_ci chunks.push(chunk); 921cb0ef41Sopenharmony_ci } 931cb0ef41Sopenharmony_ci assert_array_equals(chunks, [undefined, undefined, undefined]); 941cb0ef41Sopenharmony_ci}, 'Async-iterating a push source with undefined values'); 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_cipromise_test(async () => { 971cb0ef41Sopenharmony_ci let i = 1; 981cb0ef41Sopenharmony_ci const s = new ReadableStream({ 991cb0ef41Sopenharmony_ci pull(c) { 1001cb0ef41Sopenharmony_ci c.enqueue(undefined); 1011cb0ef41Sopenharmony_ci if (i >= 3) { 1021cb0ef41Sopenharmony_ci c.close(); 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci i += 1; 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci }); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci const chunks = []; 1091cb0ef41Sopenharmony_ci for await (const chunk of s) { 1101cb0ef41Sopenharmony_ci chunks.push(chunk); 1111cb0ef41Sopenharmony_ci } 1121cb0ef41Sopenharmony_ci assert_array_equals(chunks, [undefined, undefined, undefined]); 1131cb0ef41Sopenharmony_ci}, 'Async-iterating a pull source with undefined values'); 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_cipromise_test(async () => { 1161cb0ef41Sopenharmony_ci let i = 1; 1171cb0ef41Sopenharmony_ci const s = recordingReadableStream({ 1181cb0ef41Sopenharmony_ci pull(c) { 1191cb0ef41Sopenharmony_ci c.enqueue(i); 1201cb0ef41Sopenharmony_ci if (i >= 3) { 1211cb0ef41Sopenharmony_ci c.close(); 1221cb0ef41Sopenharmony_ci } 1231cb0ef41Sopenharmony_ci i += 1; 1241cb0ef41Sopenharmony_ci }, 1251cb0ef41Sopenharmony_ci }, new CountQueuingStrategy({ highWaterMark: 0 })); 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci const it = s.values(); 1281cb0ef41Sopenharmony_ci assert_array_equals(s.events, []); 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci const read1 = await it.next(); 1311cb0ef41Sopenharmony_ci assert_iter_result(read1, 1, false); 1321cb0ef41Sopenharmony_ci assert_array_equals(s.events, ['pull']); 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci const read2 = await it.next(); 1351cb0ef41Sopenharmony_ci assert_iter_result(read2, 2, false); 1361cb0ef41Sopenharmony_ci assert_array_equals(s.events, ['pull', 'pull']); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci const read3 = await it.next(); 1391cb0ef41Sopenharmony_ci assert_iter_result(read3, 3, false); 1401cb0ef41Sopenharmony_ci assert_array_equals(s.events, ['pull', 'pull', 'pull']); 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci const read4 = await it.next(); 1431cb0ef41Sopenharmony_ci assert_iter_result(read4, undefined, true); 1441cb0ef41Sopenharmony_ci assert_array_equals(s.events, ['pull', 'pull', 'pull']); 1451cb0ef41Sopenharmony_ci}, 'Async-iterating a pull source manually'); 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_cipromise_test(async () => { 1481cb0ef41Sopenharmony_ci const s = new ReadableStream({ 1491cb0ef41Sopenharmony_ci start(c) { 1501cb0ef41Sopenharmony_ci c.error('e'); 1511cb0ef41Sopenharmony_ci }, 1521cb0ef41Sopenharmony_ci }); 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci try { 1551cb0ef41Sopenharmony_ci for await (const chunk of s) {} 1561cb0ef41Sopenharmony_ci assert_unreached(); 1571cb0ef41Sopenharmony_ci } catch (e) { 1581cb0ef41Sopenharmony_ci assert_equals(e, 'e'); 1591cb0ef41Sopenharmony_ci } 1601cb0ef41Sopenharmony_ci}, 'Async-iterating an errored stream throws'); 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_cipromise_test(async () => { 1631cb0ef41Sopenharmony_ci const s = new ReadableStream({ 1641cb0ef41Sopenharmony_ci start(c) { 1651cb0ef41Sopenharmony_ci c.close(); 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci }); 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ci for await (const chunk of s) { 1701cb0ef41Sopenharmony_ci assert_unreached(); 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci}, 'Async-iterating a closed stream never executes the loop body, but works fine'); 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_cipromise_test(async () => { 1751cb0ef41Sopenharmony_ci const s = new ReadableStream(); 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci const loop = async () => { 1781cb0ef41Sopenharmony_ci for await (const chunk of s) { 1791cb0ef41Sopenharmony_ci assert_unreached(); 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci assert_unreached(); 1821cb0ef41Sopenharmony_ci }; 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci await Promise.race([ 1851cb0ef41Sopenharmony_ci loop(), 1861cb0ef41Sopenharmony_ci flushAsyncEvents() 1871cb0ef41Sopenharmony_ci ]); 1881cb0ef41Sopenharmony_ci}, 'Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function'); 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_cipromise_test(async () => { 1911cb0ef41Sopenharmony_ci const s = new ReadableStream({ 1921cb0ef41Sopenharmony_ci start(c) { 1931cb0ef41Sopenharmony_ci c.enqueue(1); 1941cb0ef41Sopenharmony_ci c.enqueue(2); 1951cb0ef41Sopenharmony_ci c.enqueue(3); 1961cb0ef41Sopenharmony_ci c.close(); 1971cb0ef41Sopenharmony_ci }, 1981cb0ef41Sopenharmony_ci }); 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci const reader = s.getReader(); 2011cb0ef41Sopenharmony_ci const readResult = await reader.read(); 2021cb0ef41Sopenharmony_ci assert_iter_result(readResult, 1, false); 2031cb0ef41Sopenharmony_ci reader.releaseLock(); 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci const chunks = []; 2061cb0ef41Sopenharmony_ci for await (const chunk of s) { 2071cb0ef41Sopenharmony_ci chunks.push(chunk); 2081cb0ef41Sopenharmony_ci } 2091cb0ef41Sopenharmony_ci assert_array_equals(chunks, [2, 3]); 2101cb0ef41Sopenharmony_ci}, 'Async-iterating a partially consumed stream'); 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_cifor (const type of ['throw', 'break', 'return']) { 2131cb0ef41Sopenharmony_ci for (const preventCancel of [false, true]) { 2141cb0ef41Sopenharmony_ci promise_test(async () => { 2151cb0ef41Sopenharmony_ci const s = recordingReadableStream({ 2161cb0ef41Sopenharmony_ci start(c) { 2171cb0ef41Sopenharmony_ci c.enqueue(0); 2181cb0ef41Sopenharmony_ci } 2191cb0ef41Sopenharmony_ci }); 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci // use a separate function for the loop body so return does not stop the test 2221cb0ef41Sopenharmony_ci const loop = async () => { 2231cb0ef41Sopenharmony_ci for await (const c of s.values({ preventCancel })) { 2241cb0ef41Sopenharmony_ci if (type === 'throw') { 2251cb0ef41Sopenharmony_ci throw new Error(); 2261cb0ef41Sopenharmony_ci } else if (type === 'break') { 2271cb0ef41Sopenharmony_ci break; 2281cb0ef41Sopenharmony_ci } else if (type === 'return') { 2291cb0ef41Sopenharmony_ci return; 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci } 2321cb0ef41Sopenharmony_ci }; 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci try { 2351cb0ef41Sopenharmony_ci await loop(); 2361cb0ef41Sopenharmony_ci } catch (e) {} 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci if (preventCancel) { 2391cb0ef41Sopenharmony_ci assert_array_equals(s.events, ['pull'], `cancel() should not be called`); 2401cb0ef41Sopenharmony_ci } else { 2411cb0ef41Sopenharmony_ci assert_array_equals(s.events, ['pull', 'cancel', undefined], `cancel() should be called`); 2421cb0ef41Sopenharmony_ci } 2431cb0ef41Sopenharmony_ci }, `Cancellation behavior when ${type}ing inside loop body; preventCancel = ${preventCancel}`); 2441cb0ef41Sopenharmony_ci } 2451cb0ef41Sopenharmony_ci} 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_cifor (const preventCancel of [false, true]) { 2481cb0ef41Sopenharmony_ci promise_test(async () => { 2491cb0ef41Sopenharmony_ci const s = recordingReadableStream({ 2501cb0ef41Sopenharmony_ci start(c) { 2511cb0ef41Sopenharmony_ci c.enqueue(0); 2521cb0ef41Sopenharmony_ci } 2531cb0ef41Sopenharmony_ci }); 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci const it = s.values({ preventCancel }); 2561cb0ef41Sopenharmony_ci await it.return(); 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci if (preventCancel) { 2591cb0ef41Sopenharmony_ci assert_array_equals(s.events, [], `cancel() should not be called`); 2601cb0ef41Sopenharmony_ci } else { 2611cb0ef41Sopenharmony_ci assert_array_equals(s.events, ['cancel', undefined], `cancel() should be called`); 2621cb0ef41Sopenharmony_ci } 2631cb0ef41Sopenharmony_ci }, `Cancellation behavior when manually calling return(); preventCancel = ${preventCancel}`); 2641cb0ef41Sopenharmony_ci} 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_cipromise_test(async t => { 2671cb0ef41Sopenharmony_ci let timesPulled = 0; 2681cb0ef41Sopenharmony_ci const s = new ReadableStream({ 2691cb0ef41Sopenharmony_ci pull(c) { 2701cb0ef41Sopenharmony_ci if (timesPulled === 0) { 2711cb0ef41Sopenharmony_ci c.enqueue(0); 2721cb0ef41Sopenharmony_ci ++timesPulled; 2731cb0ef41Sopenharmony_ci } else { 2741cb0ef41Sopenharmony_ci c.error(error1); 2751cb0ef41Sopenharmony_ci } 2761cb0ef41Sopenharmony_ci } 2771cb0ef41Sopenharmony_ci }); 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator](); 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ci const iterResult1 = await it.next(); 2821cb0ef41Sopenharmony_ci assert_iter_result(iterResult1, 0, false, '1st next()'); 2831cb0ef41Sopenharmony_ci 2841cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, error1, it.next(), '2nd next()'); 2851cb0ef41Sopenharmony_ci}, 'next() rejects if the stream errors'); 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_cipromise_test(async () => { 2881cb0ef41Sopenharmony_ci let timesPulled = 0; 2891cb0ef41Sopenharmony_ci const s = new ReadableStream({ 2901cb0ef41Sopenharmony_ci pull(c) { 2911cb0ef41Sopenharmony_ci if (timesPulled === 0) { 2921cb0ef41Sopenharmony_ci c.enqueue(0); 2931cb0ef41Sopenharmony_ci ++timesPulled; 2941cb0ef41Sopenharmony_ci } else { 2951cb0ef41Sopenharmony_ci c.error(error1); 2961cb0ef41Sopenharmony_ci } 2971cb0ef41Sopenharmony_ci } 2981cb0ef41Sopenharmony_ci }); 2991cb0ef41Sopenharmony_ci 3001cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator](); 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_ci const iterResult = await it.return('return value'); 3031cb0ef41Sopenharmony_ci assert_iter_result(iterResult, 'return value', true); 3041cb0ef41Sopenharmony_ci}, 'return() does not rejects if the stream has not errored yet'); 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_cipromise_test(async t => { 3071cb0ef41Sopenharmony_ci let timesPulled = 0; 3081cb0ef41Sopenharmony_ci const s = new ReadableStream({ 3091cb0ef41Sopenharmony_ci pull(c) { 3101cb0ef41Sopenharmony_ci // Do not error in start() because doing so would prevent acquiring a reader/async iterator. 3111cb0ef41Sopenharmony_ci c.error(error1); 3121cb0ef41Sopenharmony_ci } 3131cb0ef41Sopenharmony_ci }); 3141cb0ef41Sopenharmony_ci 3151cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator](); 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci await flushAsyncEvents(); 3181cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, error1, it.return('return value')); 3191cb0ef41Sopenharmony_ci}, 'return() rejects if the stream has errored'); 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_cipromise_test(async t => { 3221cb0ef41Sopenharmony_ci let timesPulled = 0; 3231cb0ef41Sopenharmony_ci const s = new ReadableStream({ 3241cb0ef41Sopenharmony_ci pull(c) { 3251cb0ef41Sopenharmony_ci if (timesPulled === 0) { 3261cb0ef41Sopenharmony_ci c.enqueue(0); 3271cb0ef41Sopenharmony_ci ++timesPulled; 3281cb0ef41Sopenharmony_ci } else { 3291cb0ef41Sopenharmony_ci c.error(error1); 3301cb0ef41Sopenharmony_ci } 3311cb0ef41Sopenharmony_ci } 3321cb0ef41Sopenharmony_ci }); 3331cb0ef41Sopenharmony_ci 3341cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator](); 3351cb0ef41Sopenharmony_ci 3361cb0ef41Sopenharmony_ci const iterResult1 = await it.next(); 3371cb0ef41Sopenharmony_ci assert_iter_result(iterResult1, 0, false, '1st next()'); 3381cb0ef41Sopenharmony_ci 3391cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, error1, it.next(), '2nd next()'); 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_ci const iterResult3 = await it.next(); 3421cb0ef41Sopenharmony_ci assert_iter_result(iterResult3, undefined, true, '3rd next()'); 3431cb0ef41Sopenharmony_ci}, 'next() that succeeds; next() that reports an error; next()'); 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_cipromise_test(async () => { 3461cb0ef41Sopenharmony_ci let timesPulled = 0; 3471cb0ef41Sopenharmony_ci const s = new ReadableStream({ 3481cb0ef41Sopenharmony_ci pull(c) { 3491cb0ef41Sopenharmony_ci if (timesPulled === 0) { 3501cb0ef41Sopenharmony_ci c.enqueue(0); 3511cb0ef41Sopenharmony_ci ++timesPulled; 3521cb0ef41Sopenharmony_ci } else { 3531cb0ef41Sopenharmony_ci c.error(error1); 3541cb0ef41Sopenharmony_ci } 3551cb0ef41Sopenharmony_ci } 3561cb0ef41Sopenharmony_ci }); 3571cb0ef41Sopenharmony_ci 3581cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator](); 3591cb0ef41Sopenharmony_ci 3601cb0ef41Sopenharmony_ci const iterResults = await Promise.allSettled([it.next(), it.next(), it.next()]); 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci assert_equals(iterResults[0].status, 'fulfilled', '1st next() promise status'); 3631cb0ef41Sopenharmony_ci assert_iter_result(iterResults[0].value, 0, false, '1st next()'); 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ci assert_equals(iterResults[1].status, 'rejected', '2nd next() promise status'); 3661cb0ef41Sopenharmony_ci assert_equals(iterResults[1].reason, error1, '2nd next() rejection reason'); 3671cb0ef41Sopenharmony_ci 3681cb0ef41Sopenharmony_ci assert_equals(iterResults[2].status, 'fulfilled', '3rd next() promise status'); 3691cb0ef41Sopenharmony_ci assert_iter_result(iterResults[2].value, undefined, true, '3rd next()'); 3701cb0ef41Sopenharmony_ci}, 'next() that succeeds; next() that reports an error(); next() [no awaiting]'); 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_cipromise_test(async t => { 3731cb0ef41Sopenharmony_ci let timesPulled = 0; 3741cb0ef41Sopenharmony_ci const s = new ReadableStream({ 3751cb0ef41Sopenharmony_ci pull(c) { 3761cb0ef41Sopenharmony_ci if (timesPulled === 0) { 3771cb0ef41Sopenharmony_ci c.enqueue(0); 3781cb0ef41Sopenharmony_ci ++timesPulled; 3791cb0ef41Sopenharmony_ci } else { 3801cb0ef41Sopenharmony_ci c.error(error1); 3811cb0ef41Sopenharmony_ci } 3821cb0ef41Sopenharmony_ci } 3831cb0ef41Sopenharmony_ci }); 3841cb0ef41Sopenharmony_ci 3851cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator](); 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ci const iterResult1 = await it.next(); 3881cb0ef41Sopenharmony_ci assert_iter_result(iterResult1, 0, false, '1st next()'); 3891cb0ef41Sopenharmony_ci 3901cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, error1, it.next(), '2nd next()'); 3911cb0ef41Sopenharmony_ci 3921cb0ef41Sopenharmony_ci const iterResult3 = await it.return('return value'); 3931cb0ef41Sopenharmony_ci assert_iter_result(iterResult3, 'return value', true, 'return()'); 3941cb0ef41Sopenharmony_ci}, 'next() that succeeds; next() that reports an error(); return()'); 3951cb0ef41Sopenharmony_ci 3961cb0ef41Sopenharmony_cipromise_test(async () => { 3971cb0ef41Sopenharmony_ci let timesPulled = 0; 3981cb0ef41Sopenharmony_ci const s = new ReadableStream({ 3991cb0ef41Sopenharmony_ci pull(c) { 4001cb0ef41Sopenharmony_ci if (timesPulled === 0) { 4011cb0ef41Sopenharmony_ci c.enqueue(0); 4021cb0ef41Sopenharmony_ci ++timesPulled; 4031cb0ef41Sopenharmony_ci } else { 4041cb0ef41Sopenharmony_ci c.error(error1); 4051cb0ef41Sopenharmony_ci } 4061cb0ef41Sopenharmony_ci } 4071cb0ef41Sopenharmony_ci }); 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator](); 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ci const iterResults = await Promise.allSettled([it.next(), it.next(), it.return('return value')]); 4121cb0ef41Sopenharmony_ci 4131cb0ef41Sopenharmony_ci assert_equals(iterResults[0].status, 'fulfilled', '1st next() promise status'); 4141cb0ef41Sopenharmony_ci assert_iter_result(iterResults[0].value, 0, false, '1st next()'); 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci assert_equals(iterResults[1].status, 'rejected', '2nd next() promise status'); 4171cb0ef41Sopenharmony_ci assert_equals(iterResults[1].reason, error1, '2nd next() rejection reason'); 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci assert_equals(iterResults[2].status, 'fulfilled', 'return() promise status'); 4201cb0ef41Sopenharmony_ci assert_iter_result(iterResults[2].value, 'return value', true, 'return()'); 4211cb0ef41Sopenharmony_ci}, 'next() that succeeds; next() that reports an error(); return() [no awaiting]'); 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_cipromise_test(async () => { 4241cb0ef41Sopenharmony_ci let timesPulled = 0; 4251cb0ef41Sopenharmony_ci const s = new ReadableStream({ 4261cb0ef41Sopenharmony_ci pull(c) { 4271cb0ef41Sopenharmony_ci c.enqueue(timesPulled); 4281cb0ef41Sopenharmony_ci ++timesPulled; 4291cb0ef41Sopenharmony_ci } 4301cb0ef41Sopenharmony_ci }); 4311cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator](); 4321cb0ef41Sopenharmony_ci 4331cb0ef41Sopenharmony_ci const iterResult1 = await it.next(); 4341cb0ef41Sopenharmony_ci assert_iter_result(iterResult1, 0, false, 'next()'); 4351cb0ef41Sopenharmony_ci 4361cb0ef41Sopenharmony_ci const iterResult2 = await it.return('return value'); 4371cb0ef41Sopenharmony_ci assert_iter_result(iterResult2, 'return value', true, 'return()'); 4381cb0ef41Sopenharmony_ci 4391cb0ef41Sopenharmony_ci assert_equals(timesPulled, 2); 4401cb0ef41Sopenharmony_ci}, 'next() that succeeds; return()'); 4411cb0ef41Sopenharmony_ci 4421cb0ef41Sopenharmony_cipromise_test(async () => { 4431cb0ef41Sopenharmony_ci let timesPulled = 0; 4441cb0ef41Sopenharmony_ci const s = new ReadableStream({ 4451cb0ef41Sopenharmony_ci pull(c) { 4461cb0ef41Sopenharmony_ci c.enqueue(timesPulled); 4471cb0ef41Sopenharmony_ci ++timesPulled; 4481cb0ef41Sopenharmony_ci } 4491cb0ef41Sopenharmony_ci }); 4501cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator](); 4511cb0ef41Sopenharmony_ci 4521cb0ef41Sopenharmony_ci const iterResults = await Promise.allSettled([it.next(), it.return('return value')]); 4531cb0ef41Sopenharmony_ci 4541cb0ef41Sopenharmony_ci assert_equals(iterResults[0].status, 'fulfilled', 'next() promise status'); 4551cb0ef41Sopenharmony_ci assert_iter_result(iterResults[0].value, 0, false, 'next()'); 4561cb0ef41Sopenharmony_ci 4571cb0ef41Sopenharmony_ci assert_equals(iterResults[1].status, 'fulfilled', 'return() promise status'); 4581cb0ef41Sopenharmony_ci assert_iter_result(iterResults[1].value, 'return value', true, 'return()'); 4591cb0ef41Sopenharmony_ci 4601cb0ef41Sopenharmony_ci assert_equals(timesPulled, 2); 4611cb0ef41Sopenharmony_ci}, 'next() that succeeds; return() [no awaiting]'); 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_cipromise_test(async () => { 4641cb0ef41Sopenharmony_ci const rs = new ReadableStream(); 4651cb0ef41Sopenharmony_ci const it = rs.values(); 4661cb0ef41Sopenharmony_ci 4671cb0ef41Sopenharmony_ci const iterResult1 = await it.return('return value'); 4681cb0ef41Sopenharmony_ci assert_iter_result(iterResult1, 'return value', true, 'return()'); 4691cb0ef41Sopenharmony_ci 4701cb0ef41Sopenharmony_ci const iterResult2 = await it.next(); 4711cb0ef41Sopenharmony_ci assert_iter_result(iterResult2, undefined, true, 'next()'); 4721cb0ef41Sopenharmony_ci}, 'return(); next()'); 4731cb0ef41Sopenharmony_ci 4741cb0ef41Sopenharmony_cipromise_test(async () => { 4751cb0ef41Sopenharmony_ci const rs = new ReadableStream(); 4761cb0ef41Sopenharmony_ci const it = rs.values(); 4771cb0ef41Sopenharmony_ci 4781cb0ef41Sopenharmony_ci const iterResults = await Promise.allSettled([it.return('return value'), it.next()]); 4791cb0ef41Sopenharmony_ci 4801cb0ef41Sopenharmony_ci assert_equals(iterResults[0].status, 'fulfilled', 'return() promise status'); 4811cb0ef41Sopenharmony_ci assert_iter_result(iterResults[0].value, 'return value', true, 'return()'); 4821cb0ef41Sopenharmony_ci 4831cb0ef41Sopenharmony_ci assert_equals(iterResults[1].status, 'fulfilled', 'next() promise status'); 4841cb0ef41Sopenharmony_ci assert_iter_result(iterResults[1].value, undefined, true, 'next()'); 4851cb0ef41Sopenharmony_ci}, 'return(); next() [no awaiting]'); 4861cb0ef41Sopenharmony_ci 4871cb0ef41Sopenharmony_cipromise_test(async () => { 4881cb0ef41Sopenharmony_ci const rs = new ReadableStream(); 4891cb0ef41Sopenharmony_ci const it = rs.values(); 4901cb0ef41Sopenharmony_ci 4911cb0ef41Sopenharmony_ci const iterResult1 = await it.return('return value 1'); 4921cb0ef41Sopenharmony_ci assert_iter_result(iterResult1, 'return value 1', true, '1st return()'); 4931cb0ef41Sopenharmony_ci 4941cb0ef41Sopenharmony_ci const iterResult2 = await it.return('return value 2'); 4951cb0ef41Sopenharmony_ci assert_iter_result(iterResult2, 'return value 2', true, '1st return()'); 4961cb0ef41Sopenharmony_ci}, 'return(); return()'); 4971cb0ef41Sopenharmony_ci 4981cb0ef41Sopenharmony_cipromise_test(async () => { 4991cb0ef41Sopenharmony_ci const rs = new ReadableStream(); 5001cb0ef41Sopenharmony_ci const it = rs.values(); 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_ci const iterResults = await Promise.allSettled([it.return('return value 1'), it.return('return value 2')]); 5031cb0ef41Sopenharmony_ci 5041cb0ef41Sopenharmony_ci assert_equals(iterResults[0].status, 'fulfilled', '1st return() promise status'); 5051cb0ef41Sopenharmony_ci assert_iter_result(iterResults[0].value, 'return value 1', true, '1st return()'); 5061cb0ef41Sopenharmony_ci 5071cb0ef41Sopenharmony_ci assert_equals(iterResults[1].status, 'fulfilled', '2nd return() promise status'); 5081cb0ef41Sopenharmony_ci assert_iter_result(iterResults[1].value, 'return value 2', true, '1st return()'); 5091cb0ef41Sopenharmony_ci}, 'return(); return() [no awaiting]'); 5101cb0ef41Sopenharmony_ci 5111cb0ef41Sopenharmony_citest(() => { 5121cb0ef41Sopenharmony_ci const s = new ReadableStream({ 5131cb0ef41Sopenharmony_ci start(c) { 5141cb0ef41Sopenharmony_ci c.enqueue(0); 5151cb0ef41Sopenharmony_ci c.close(); 5161cb0ef41Sopenharmony_ci }, 5171cb0ef41Sopenharmony_ci }); 5181cb0ef41Sopenharmony_ci s.values(); 5191cb0ef41Sopenharmony_ci assert_throws_js(TypeError, () => s.values(), 'values() should throw'); 5201cb0ef41Sopenharmony_ci}, 'values() throws if there\'s already a lock'); 5211cb0ef41Sopenharmony_ci 5221cb0ef41Sopenharmony_cipromise_test(async () => { 5231cb0ef41Sopenharmony_ci const s = new ReadableStream({ 5241cb0ef41Sopenharmony_ci start(c) { 5251cb0ef41Sopenharmony_ci c.enqueue(1); 5261cb0ef41Sopenharmony_ci c.enqueue(2); 5271cb0ef41Sopenharmony_ci c.enqueue(3); 5281cb0ef41Sopenharmony_ci c.close(); 5291cb0ef41Sopenharmony_ci } 5301cb0ef41Sopenharmony_ci }); 5311cb0ef41Sopenharmony_ci 5321cb0ef41Sopenharmony_ci const chunks = []; 5331cb0ef41Sopenharmony_ci for await (const chunk of s) { 5341cb0ef41Sopenharmony_ci chunks.push(chunk); 5351cb0ef41Sopenharmony_ci } 5361cb0ef41Sopenharmony_ci assert_array_equals(chunks, [1, 2, 3]); 5371cb0ef41Sopenharmony_ci 5381cb0ef41Sopenharmony_ci const reader = s.getReader(); 5391cb0ef41Sopenharmony_ci await reader.closed; 5401cb0ef41Sopenharmony_ci}, 'Acquiring a reader after exhaustively async-iterating a stream'); 5411cb0ef41Sopenharmony_ci 5421cb0ef41Sopenharmony_cipromise_test(async t => { 5431cb0ef41Sopenharmony_ci let timesPulled = 0; 5441cb0ef41Sopenharmony_ci const s = new ReadableStream({ 5451cb0ef41Sopenharmony_ci pull(c) { 5461cb0ef41Sopenharmony_ci if (timesPulled === 0) { 5471cb0ef41Sopenharmony_ci c.enqueue(0); 5481cb0ef41Sopenharmony_ci ++timesPulled; 5491cb0ef41Sopenharmony_ci } else { 5501cb0ef41Sopenharmony_ci c.error(error1); 5511cb0ef41Sopenharmony_ci } 5521cb0ef41Sopenharmony_ci } 5531cb0ef41Sopenharmony_ci }); 5541cb0ef41Sopenharmony_ci 5551cb0ef41Sopenharmony_ci const it = s[Symbol.asyncIterator]({ preventCancel: true }); 5561cb0ef41Sopenharmony_ci 5571cb0ef41Sopenharmony_ci const iterResult1 = await it.next(); 5581cb0ef41Sopenharmony_ci assert_iter_result(iterResult1, 0, false, '1st next()'); 5591cb0ef41Sopenharmony_ci 5601cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, error1, it.next(), '2nd next()'); 5611cb0ef41Sopenharmony_ci 5621cb0ef41Sopenharmony_ci const iterResult2 = await it.return('return value'); 5631cb0ef41Sopenharmony_ci assert_iter_result(iterResult2, 'return value', true, 'return()'); 5641cb0ef41Sopenharmony_ci 5651cb0ef41Sopenharmony_ci // i.e. it should not reject with a generic "this stream is locked" TypeError. 5661cb0ef41Sopenharmony_ci const reader = s.getReader(); 5671cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, error1, reader.closed, 'closed on the new reader should reject with the error'); 5681cb0ef41Sopenharmony_ci}, 'Acquiring a reader after return()ing from a stream that errors'); 5691cb0ef41Sopenharmony_ci 5701cb0ef41Sopenharmony_cipromise_test(async () => { 5711cb0ef41Sopenharmony_ci const s = new ReadableStream({ 5721cb0ef41Sopenharmony_ci start(c) { 5731cb0ef41Sopenharmony_ci c.enqueue(1); 5741cb0ef41Sopenharmony_ci c.enqueue(2); 5751cb0ef41Sopenharmony_ci c.enqueue(3); 5761cb0ef41Sopenharmony_ci c.close(); 5771cb0ef41Sopenharmony_ci }, 5781cb0ef41Sopenharmony_ci }); 5791cb0ef41Sopenharmony_ci 5801cb0ef41Sopenharmony_ci // read the first two chunks, then cancel 5811cb0ef41Sopenharmony_ci const chunks = []; 5821cb0ef41Sopenharmony_ci for await (const chunk of s) { 5831cb0ef41Sopenharmony_ci chunks.push(chunk); 5841cb0ef41Sopenharmony_ci if (chunk >= 2) { 5851cb0ef41Sopenharmony_ci break; 5861cb0ef41Sopenharmony_ci } 5871cb0ef41Sopenharmony_ci } 5881cb0ef41Sopenharmony_ci assert_array_equals(chunks, [1, 2]); 5891cb0ef41Sopenharmony_ci 5901cb0ef41Sopenharmony_ci const reader = s.getReader(); 5911cb0ef41Sopenharmony_ci await reader.closed; 5921cb0ef41Sopenharmony_ci}, 'Acquiring a reader after partially async-iterating a stream'); 5931cb0ef41Sopenharmony_ci 5941cb0ef41Sopenharmony_cipromise_test(async () => { 5951cb0ef41Sopenharmony_ci const s = new ReadableStream({ 5961cb0ef41Sopenharmony_ci start(c) { 5971cb0ef41Sopenharmony_ci c.enqueue(1); 5981cb0ef41Sopenharmony_ci c.enqueue(2); 5991cb0ef41Sopenharmony_ci c.enqueue(3); 6001cb0ef41Sopenharmony_ci c.close(); 6011cb0ef41Sopenharmony_ci }, 6021cb0ef41Sopenharmony_ci }); 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_ci // read the first two chunks, then release lock 6051cb0ef41Sopenharmony_ci const chunks = []; 6061cb0ef41Sopenharmony_ci for await (const chunk of s.values({preventCancel: true})) { 6071cb0ef41Sopenharmony_ci chunks.push(chunk); 6081cb0ef41Sopenharmony_ci if (chunk >= 2) { 6091cb0ef41Sopenharmony_ci break; 6101cb0ef41Sopenharmony_ci } 6111cb0ef41Sopenharmony_ci } 6121cb0ef41Sopenharmony_ci assert_array_equals(chunks, [1, 2]); 6131cb0ef41Sopenharmony_ci 6141cb0ef41Sopenharmony_ci const reader = s.getReader(); 6151cb0ef41Sopenharmony_ci const readResult = await reader.read(); 6161cb0ef41Sopenharmony_ci assert_iter_result(readResult, 3, false); 6171cb0ef41Sopenharmony_ci await reader.closed; 6181cb0ef41Sopenharmony_ci}, 'Acquiring a reader and reading the remaining chunks after partially async-iterating a stream with preventCancel = true'); 6191cb0ef41Sopenharmony_ci 6201cb0ef41Sopenharmony_cifor (const preventCancel of [false, true]) { 6211cb0ef41Sopenharmony_ci test(() => { 6221cb0ef41Sopenharmony_ci const rs = new ReadableStream(); 6231cb0ef41Sopenharmony_ci rs.values({ preventCancel }).return(); 6241cb0ef41Sopenharmony_ci // The test passes if this line doesn't throw. 6251cb0ef41Sopenharmony_ci rs.getReader(); 6261cb0ef41Sopenharmony_ci }, `return() should unlock the stream synchronously when preventCancel = ${preventCancel}`); 6271cb0ef41Sopenharmony_ci} 6281cb0ef41Sopenharmony_ci 6291cb0ef41Sopenharmony_cipromise_test(async () => { 6301cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 6311cb0ef41Sopenharmony_ci async start(c) { 6321cb0ef41Sopenharmony_ci c.enqueue('a'); 6331cb0ef41Sopenharmony_ci c.enqueue('b'); 6341cb0ef41Sopenharmony_ci c.enqueue('c'); 6351cb0ef41Sopenharmony_ci await flushAsyncEvents(); 6361cb0ef41Sopenharmony_ci // At this point, the async iterator has a read request in the stream's queue for its pending next() promise. 6371cb0ef41Sopenharmony_ci // Closing the stream now causes two things to happen *synchronously*: 6381cb0ef41Sopenharmony_ci // 1. ReadableStreamClose resolves reader.[[closedPromise]] with undefined. 6391cb0ef41Sopenharmony_ci // 2. ReadableStreamClose calls the read request's close steps, which calls ReadableStreamReaderGenericRelease, 6401cb0ef41Sopenharmony_ci // which replaces reader.[[closedPromise]] with a rejected promise. 6411cb0ef41Sopenharmony_ci c.close(); 6421cb0ef41Sopenharmony_ci } 6431cb0ef41Sopenharmony_ci }); 6441cb0ef41Sopenharmony_ci 6451cb0ef41Sopenharmony_ci const chunks = []; 6461cb0ef41Sopenharmony_ci for await (const chunk of rs) { 6471cb0ef41Sopenharmony_ci chunks.push(chunk); 6481cb0ef41Sopenharmony_ci } 6491cb0ef41Sopenharmony_ci assert_array_equals(chunks, ['a', 'b', 'c']); 6501cb0ef41Sopenharmony_ci}, 'close() while next() is pending'); 651