11cb0ef41Sopenharmony_ci// META: global=window,worker 21cb0ef41Sopenharmony_ci// META: script=../resources/recording-streams.js 31cb0ef41Sopenharmony_ci// META: script=../resources/test-utils.js 41cb0ef41Sopenharmony_ci'use strict'; 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci// Tests for the use of pipeTo with AbortSignal. 71cb0ef41Sopenharmony_ci// There is some extra complexity to avoid timeouts in environments where abort is not implemented. 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciconst error1 = new Error('error1'); 101cb0ef41Sopenharmony_cierror1.name = 'error1'; 111cb0ef41Sopenharmony_ciconst error2 = new Error('error2'); 121cb0ef41Sopenharmony_cierror2.name = 'error2'; 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciconst errorOnPull = { 151cb0ef41Sopenharmony_ci pull(controller) { 161cb0ef41Sopenharmony_ci // This will cause the test to error if pipeTo abort is not implemented. 171cb0ef41Sopenharmony_ci controller.error('failed to abort'); 181cb0ef41Sopenharmony_ci } 191cb0ef41Sopenharmony_ci}; 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci// To stop pull() being called immediately when the stream is created, we need to set highWaterMark to 0. 221cb0ef41Sopenharmony_ciconst hwm0 = { highWaterMark: 0 }; 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_cifor (const invalidSignal of [null, 'AbortSignal', true, -1, Object.create(AbortSignal.prototype)]) { 251cb0ef41Sopenharmony_ci promise_test(t => { 261cb0ef41Sopenharmony_ci const rs = recordingReadableStream(errorOnPull, hwm0); 271cb0ef41Sopenharmony_ci const ws = recordingWritableStream(); 281cb0ef41Sopenharmony_ci return promise_rejects_js(t, TypeError, rs.pipeTo(ws, { signal: invalidSignal }), 'pipeTo should reject') 291cb0ef41Sopenharmony_ci .then(() => { 301cb0ef41Sopenharmony_ci assert_equals(rs.events.length, 0, 'no ReadableStream methods should have been called'); 311cb0ef41Sopenharmony_ci assert_equals(ws.events.length, 0, 'no WritableStream methods should have been called'); 321cb0ef41Sopenharmony_ci }); 331cb0ef41Sopenharmony_ci }, `a signal argument '${invalidSignal}' should cause pipeTo() to reject`); 341cb0ef41Sopenharmony_ci} 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_cipromise_test(t => { 371cb0ef41Sopenharmony_ci const rs = recordingReadableStream(errorOnPull, hwm0); 381cb0ef41Sopenharmony_ci const ws = new WritableStream(); 391cb0ef41Sopenharmony_ci const abortController = new AbortController(); 401cb0ef41Sopenharmony_ci const signal = abortController.signal; 411cb0ef41Sopenharmony_ci abortController.abort(); 421cb0ef41Sopenharmony_ci return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject') 431cb0ef41Sopenharmony_ci .then(() => Promise.all([ 441cb0ef41Sopenharmony_ci rs.getReader().closed, 451cb0ef41Sopenharmony_ci promise_rejects_dom(t, 'AbortError', ws.getWriter().closed, 'writer.closed should reject') 461cb0ef41Sopenharmony_ci ])) 471cb0ef41Sopenharmony_ci .then(() => { 481cb0ef41Sopenharmony_ci assert_equals(rs.events.length, 2, 'cancel should have been called'); 491cb0ef41Sopenharmony_ci assert_equals(rs.events[0], 'cancel', 'first event should be cancel'); 501cb0ef41Sopenharmony_ci assert_equals(rs.events[1].name, 'AbortError', 'the argument to cancel should be an AbortError'); 511cb0ef41Sopenharmony_ci assert_equals(rs.events[1].constructor.name, 'DOMException', 521cb0ef41Sopenharmony_ci 'the argument to cancel should be a DOMException'); 531cb0ef41Sopenharmony_ci }); 541cb0ef41Sopenharmony_ci}, 'an aborted signal should cause the writable stream to reject with an AbortError'); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_cifor (const reason of [null, undefined, error1]) { 571cb0ef41Sopenharmony_ci promise_test(async t => { 581cb0ef41Sopenharmony_ci const rs = recordingReadableStream(errorOnPull, hwm0); 591cb0ef41Sopenharmony_ci const ws = new WritableStream(); 601cb0ef41Sopenharmony_ci const abortController = new AbortController(); 611cb0ef41Sopenharmony_ci const signal = abortController.signal; 621cb0ef41Sopenharmony_ci abortController.abort(reason); 631cb0ef41Sopenharmony_ci const pipeToPromise = rs.pipeTo(ws, { signal }); 641cb0ef41Sopenharmony_ci if (reason !== undefined) { 651cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason'); 661cb0ef41Sopenharmony_ci } else { 671cb0ef41Sopenharmony_ci await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError'); 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci const error = await pipeToPromise.catch(e => e); 701cb0ef41Sopenharmony_ci await rs.getReader().closed; 711cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, error, ws.getWriter().closed, 'the writable should be errored with the same object'); 721cb0ef41Sopenharmony_ci assert_equals(signal.reason, error, 'signal.reason should be error'), 731cb0ef41Sopenharmony_ci assert_equals(rs.events.length, 2, 'cancel should have been called'); 741cb0ef41Sopenharmony_ci assert_equals(rs.events[0], 'cancel', 'first event should be cancel'); 751cb0ef41Sopenharmony_ci assert_equals(rs.events[1], error, 'the readable should be canceled with the same object'); 761cb0ef41Sopenharmony_ci }, `(reason: '${reason}') all the error objects should be the same object`); 771cb0ef41Sopenharmony_ci} 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_cipromise_test(t => { 801cb0ef41Sopenharmony_ci const rs = recordingReadableStream(errorOnPull, hwm0); 811cb0ef41Sopenharmony_ci const ws = new WritableStream(); 821cb0ef41Sopenharmony_ci const abortController = new AbortController(); 831cb0ef41Sopenharmony_ci const signal = abortController.signal; 841cb0ef41Sopenharmony_ci abortController.abort(); 851cb0ef41Sopenharmony_ci return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal, preventCancel: true }), 'pipeTo should reject') 861cb0ef41Sopenharmony_ci .then(() => assert_equals(rs.events.length, 0, 'cancel should not be called')); 871cb0ef41Sopenharmony_ci}, 'preventCancel should prevent canceling the readable'); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_cipromise_test(t => { 901cb0ef41Sopenharmony_ci const rs = new ReadableStream(errorOnPull, hwm0); 911cb0ef41Sopenharmony_ci const ws = recordingWritableStream(); 921cb0ef41Sopenharmony_ci const abortController = new AbortController(); 931cb0ef41Sopenharmony_ci const signal = abortController.signal; 941cb0ef41Sopenharmony_ci abortController.abort(); 951cb0ef41Sopenharmony_ci return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal, preventAbort: true }), 'pipeTo should reject') 961cb0ef41Sopenharmony_ci .then(() => { 971cb0ef41Sopenharmony_ci assert_equals(ws.events.length, 0, 'writable should not have been aborted'); 981cb0ef41Sopenharmony_ci return ws.getWriter().ready; 991cb0ef41Sopenharmony_ci }); 1001cb0ef41Sopenharmony_ci}, 'preventAbort should prevent aborting the readable'); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_cipromise_test(t => { 1031cb0ef41Sopenharmony_ci const rs = recordingReadableStream(errorOnPull, hwm0); 1041cb0ef41Sopenharmony_ci const ws = recordingWritableStream(); 1051cb0ef41Sopenharmony_ci const abortController = new AbortController(); 1061cb0ef41Sopenharmony_ci const signal = abortController.signal; 1071cb0ef41Sopenharmony_ci abortController.abort(); 1081cb0ef41Sopenharmony_ci return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal, preventCancel: true, preventAbort: true }), 1091cb0ef41Sopenharmony_ci 'pipeTo should reject') 1101cb0ef41Sopenharmony_ci .then(() => { 1111cb0ef41Sopenharmony_ci assert_equals(rs.events.length, 0, 'cancel should not be called'); 1121cb0ef41Sopenharmony_ci assert_equals(ws.events.length, 0, 'writable should not have been aborted'); 1131cb0ef41Sopenharmony_ci return ws.getWriter().ready; 1141cb0ef41Sopenharmony_ci }); 1151cb0ef41Sopenharmony_ci}, 'preventCancel and preventAbort should prevent canceling the readable and aborting the readable'); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_cifor (const reason of [null, undefined, error1]) { 1181cb0ef41Sopenharmony_ci promise_test(async t => { 1191cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 1201cb0ef41Sopenharmony_ci start(controller) { 1211cb0ef41Sopenharmony_ci controller.enqueue('a'); 1221cb0ef41Sopenharmony_ci controller.enqueue('b'); 1231cb0ef41Sopenharmony_ci controller.close(); 1241cb0ef41Sopenharmony_ci } 1251cb0ef41Sopenharmony_ci }); 1261cb0ef41Sopenharmony_ci const abortController = new AbortController(); 1271cb0ef41Sopenharmony_ci const signal = abortController.signal; 1281cb0ef41Sopenharmony_ci const ws = recordingWritableStream({ 1291cb0ef41Sopenharmony_ci write() { 1301cb0ef41Sopenharmony_ci abortController.abort(reason); 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci }); 1331cb0ef41Sopenharmony_ci const pipeToPromise = rs.pipeTo(ws, { signal }); 1341cb0ef41Sopenharmony_ci if (reason !== undefined) { 1351cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason'); 1361cb0ef41Sopenharmony_ci } else { 1371cb0ef41Sopenharmony_ci await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError'); 1381cb0ef41Sopenharmony_ci } 1391cb0ef41Sopenharmony_ci const error = await pipeToPromise.catch(e => e); 1401cb0ef41Sopenharmony_ci assert_equals(signal.reason, error, 'signal.reason should be error'); 1411cb0ef41Sopenharmony_ci assert_equals(ws.events.length, 4, 'only chunk "a" should have been written'); 1421cb0ef41Sopenharmony_ci assert_array_equals(ws.events.slice(0, 3), ['write', 'a', 'abort'], 'events should match'); 1431cb0ef41Sopenharmony_ci assert_equals(ws.events[3], error, 'abort reason should be error'); 1441cb0ef41Sopenharmony_ci }, `(reason: '${reason}') abort should prevent further reads`); 1451cb0ef41Sopenharmony_ci} 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_cifor (const reason of [null, undefined, error1]) { 1481cb0ef41Sopenharmony_ci promise_test(async t => { 1491cb0ef41Sopenharmony_ci let readController; 1501cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 1511cb0ef41Sopenharmony_ci start(c) { 1521cb0ef41Sopenharmony_ci readController = c; 1531cb0ef41Sopenharmony_ci c.enqueue('a'); 1541cb0ef41Sopenharmony_ci c.enqueue('b'); 1551cb0ef41Sopenharmony_ci } 1561cb0ef41Sopenharmony_ci }); 1571cb0ef41Sopenharmony_ci const abortController = new AbortController(); 1581cb0ef41Sopenharmony_ci const signal = abortController.signal; 1591cb0ef41Sopenharmony_ci let resolveWrite; 1601cb0ef41Sopenharmony_ci const writePromise = new Promise(resolve => { 1611cb0ef41Sopenharmony_ci resolveWrite = resolve; 1621cb0ef41Sopenharmony_ci }); 1631cb0ef41Sopenharmony_ci const ws = recordingWritableStream({ 1641cb0ef41Sopenharmony_ci write() { 1651cb0ef41Sopenharmony_ci return writePromise; 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci }, new CountQueuingStrategy({ highWaterMark: Infinity })); 1681cb0ef41Sopenharmony_ci const pipeToPromise = rs.pipeTo(ws, { signal }); 1691cb0ef41Sopenharmony_ci await delay(0); 1701cb0ef41Sopenharmony_ci await abortController.abort(reason); 1711cb0ef41Sopenharmony_ci await readController.close(); // Make sure the test terminates when signal is not implemented. 1721cb0ef41Sopenharmony_ci await resolveWrite(); 1731cb0ef41Sopenharmony_ci if (reason !== undefined) { 1741cb0ef41Sopenharmony_ci await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason'); 1751cb0ef41Sopenharmony_ci } else { 1761cb0ef41Sopenharmony_ci await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError'); 1771cb0ef41Sopenharmony_ci } 1781cb0ef41Sopenharmony_ci const error = await pipeToPromise.catch(e => e); 1791cb0ef41Sopenharmony_ci assert_equals(signal.reason, error, 'signal.reason should be error'); 1801cb0ef41Sopenharmony_ci assert_equals(ws.events.length, 6, 'chunks "a" and "b" should have been written'); 1811cb0ef41Sopenharmony_ci assert_array_equals(ws.events.slice(0, 5), ['write', 'a', 'write', 'b', 'abort'], 'events should match'); 1821cb0ef41Sopenharmony_ci assert_equals(ws.events[5], error, 'abort reason should be error'); 1831cb0ef41Sopenharmony_ci }, `(reason: '${reason}') all pending writes should complete on abort`); 1841cb0ef41Sopenharmony_ci} 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_cipromise_test(t => { 1871cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 1881cb0ef41Sopenharmony_ci pull(controller) { 1891cb0ef41Sopenharmony_ci controller.error('failed to abort'); 1901cb0ef41Sopenharmony_ci }, 1911cb0ef41Sopenharmony_ci cancel() { 1921cb0ef41Sopenharmony_ci return Promise.reject(error1); 1931cb0ef41Sopenharmony_ci } 1941cb0ef41Sopenharmony_ci }, hwm0); 1951cb0ef41Sopenharmony_ci const ws = new WritableStream(); 1961cb0ef41Sopenharmony_ci const abortController = new AbortController(); 1971cb0ef41Sopenharmony_ci const signal = abortController.signal; 1981cb0ef41Sopenharmony_ci abortController.abort(); 1991cb0ef41Sopenharmony_ci return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { signal }), 'pipeTo should reject'); 2001cb0ef41Sopenharmony_ci}, 'a rejection from underlyingSource.cancel() should be returned by pipeTo()'); 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_cipromise_test(t => { 2031cb0ef41Sopenharmony_ci const rs = new ReadableStream(errorOnPull, hwm0); 2041cb0ef41Sopenharmony_ci const ws = new WritableStream({ 2051cb0ef41Sopenharmony_ci abort() { 2061cb0ef41Sopenharmony_ci return Promise.reject(error1); 2071cb0ef41Sopenharmony_ci } 2081cb0ef41Sopenharmony_ci }); 2091cb0ef41Sopenharmony_ci const abortController = new AbortController(); 2101cb0ef41Sopenharmony_ci const signal = abortController.signal; 2111cb0ef41Sopenharmony_ci abortController.abort(); 2121cb0ef41Sopenharmony_ci return promise_rejects_exactly(t, error1, rs.pipeTo(ws, { signal }), 'pipeTo should reject'); 2131cb0ef41Sopenharmony_ci}, 'a rejection from underlyingSink.abort() should be returned by pipeTo()'); 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_cipromise_test(t => { 2161cb0ef41Sopenharmony_ci const events = []; 2171cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 2181cb0ef41Sopenharmony_ci pull(controller) { 2191cb0ef41Sopenharmony_ci controller.error('failed to abort'); 2201cb0ef41Sopenharmony_ci }, 2211cb0ef41Sopenharmony_ci cancel() { 2221cb0ef41Sopenharmony_ci events.push('cancel'); 2231cb0ef41Sopenharmony_ci return Promise.reject(error1); 2241cb0ef41Sopenharmony_ci } 2251cb0ef41Sopenharmony_ci }, hwm0); 2261cb0ef41Sopenharmony_ci const ws = new WritableStream({ 2271cb0ef41Sopenharmony_ci abort() { 2281cb0ef41Sopenharmony_ci events.push('abort'); 2291cb0ef41Sopenharmony_ci return Promise.reject(error2); 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci }); 2321cb0ef41Sopenharmony_ci const abortController = new AbortController(); 2331cb0ef41Sopenharmony_ci const signal = abortController.signal; 2341cb0ef41Sopenharmony_ci abortController.abort(); 2351cb0ef41Sopenharmony_ci return promise_rejects_exactly(t, error2, rs.pipeTo(ws, { signal }), 'pipeTo should reject') 2361cb0ef41Sopenharmony_ci .then(() => assert_array_equals(events, ['abort', 'cancel'], 'abort() should be called before cancel()')); 2371cb0ef41Sopenharmony_ci}, 'a rejection from underlyingSink.abort() should be preferred to one from underlyingSource.cancel()'); 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_cipromise_test(t => { 2401cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 2411cb0ef41Sopenharmony_ci start(controller) { 2421cb0ef41Sopenharmony_ci controller.close(); 2431cb0ef41Sopenharmony_ci } 2441cb0ef41Sopenharmony_ci }); 2451cb0ef41Sopenharmony_ci const ws = new WritableStream(); 2461cb0ef41Sopenharmony_ci const abortController = new AbortController(); 2471cb0ef41Sopenharmony_ci const signal = abortController.signal; 2481cb0ef41Sopenharmony_ci abortController.abort(); 2491cb0ef41Sopenharmony_ci return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject'); 2501cb0ef41Sopenharmony_ci}, 'abort signal takes priority over closed readable'); 2511cb0ef41Sopenharmony_ci 2521cb0ef41Sopenharmony_cipromise_test(t => { 2531cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 2541cb0ef41Sopenharmony_ci start(controller) { 2551cb0ef41Sopenharmony_ci controller.error(error1); 2561cb0ef41Sopenharmony_ci } 2571cb0ef41Sopenharmony_ci }); 2581cb0ef41Sopenharmony_ci const ws = new WritableStream(); 2591cb0ef41Sopenharmony_ci const abortController = new AbortController(); 2601cb0ef41Sopenharmony_ci const signal = abortController.signal; 2611cb0ef41Sopenharmony_ci abortController.abort(); 2621cb0ef41Sopenharmony_ci return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject'); 2631cb0ef41Sopenharmony_ci}, 'abort signal takes priority over errored readable'); 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_cipromise_test(t => { 2661cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 2671cb0ef41Sopenharmony_ci pull(controller) { 2681cb0ef41Sopenharmony_ci controller.error('failed to abort'); 2691cb0ef41Sopenharmony_ci } 2701cb0ef41Sopenharmony_ci }, hwm0); 2711cb0ef41Sopenharmony_ci const ws = new WritableStream(); 2721cb0ef41Sopenharmony_ci const abortController = new AbortController(); 2731cb0ef41Sopenharmony_ci const signal = abortController.signal; 2741cb0ef41Sopenharmony_ci abortController.abort(); 2751cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 2761cb0ef41Sopenharmony_ci return writer.close().then(() => { 2771cb0ef41Sopenharmony_ci writer.releaseLock(); 2781cb0ef41Sopenharmony_ci return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject'); 2791cb0ef41Sopenharmony_ci }); 2801cb0ef41Sopenharmony_ci}, 'abort signal takes priority over closed writable'); 2811cb0ef41Sopenharmony_ci 2821cb0ef41Sopenharmony_cipromise_test(t => { 2831cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 2841cb0ef41Sopenharmony_ci pull(controller) { 2851cb0ef41Sopenharmony_ci controller.error('failed to abort'); 2861cb0ef41Sopenharmony_ci } 2871cb0ef41Sopenharmony_ci }, hwm0); 2881cb0ef41Sopenharmony_ci const ws = new WritableStream({ 2891cb0ef41Sopenharmony_ci start(controller) { 2901cb0ef41Sopenharmony_ci controller.error(error1); 2911cb0ef41Sopenharmony_ci } 2921cb0ef41Sopenharmony_ci }); 2931cb0ef41Sopenharmony_ci const abortController = new AbortController(); 2941cb0ef41Sopenharmony_ci const signal = abortController.signal; 2951cb0ef41Sopenharmony_ci abortController.abort(); 2961cb0ef41Sopenharmony_ci return promise_rejects_dom(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject'); 2971cb0ef41Sopenharmony_ci}, 'abort signal takes priority over errored writable'); 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_cipromise_test(() => { 3001cb0ef41Sopenharmony_ci let readController; 3011cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 3021cb0ef41Sopenharmony_ci start(c) { 3031cb0ef41Sopenharmony_ci readController = c; 3041cb0ef41Sopenharmony_ci } 3051cb0ef41Sopenharmony_ci }); 3061cb0ef41Sopenharmony_ci const ws = new WritableStream(); 3071cb0ef41Sopenharmony_ci const abortController = new AbortController(); 3081cb0ef41Sopenharmony_ci const signal = abortController.signal; 3091cb0ef41Sopenharmony_ci const pipeToPromise = rs.pipeTo(ws, { signal, preventClose: true }); 3101cb0ef41Sopenharmony_ci readController.close(); 3111cb0ef41Sopenharmony_ci return Promise.resolve().then(() => { 3121cb0ef41Sopenharmony_ci abortController.abort(); 3131cb0ef41Sopenharmony_ci return pipeToPromise; 3141cb0ef41Sopenharmony_ci }).then(() => ws.getWriter().write('this should succeed')); 3151cb0ef41Sopenharmony_ci}, 'abort should do nothing after the readable is closed'); 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_cipromise_test(t => { 3181cb0ef41Sopenharmony_ci let readController; 3191cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 3201cb0ef41Sopenharmony_ci start(c) { 3211cb0ef41Sopenharmony_ci readController = c; 3221cb0ef41Sopenharmony_ci } 3231cb0ef41Sopenharmony_ci }); 3241cb0ef41Sopenharmony_ci const ws = new WritableStream(); 3251cb0ef41Sopenharmony_ci const abortController = new AbortController(); 3261cb0ef41Sopenharmony_ci const signal = abortController.signal; 3271cb0ef41Sopenharmony_ci const pipeToPromise = rs.pipeTo(ws, { signal, preventAbort: true }); 3281cb0ef41Sopenharmony_ci readController.error(error1); 3291cb0ef41Sopenharmony_ci return Promise.resolve().then(() => { 3301cb0ef41Sopenharmony_ci abortController.abort(); 3311cb0ef41Sopenharmony_ci return promise_rejects_exactly(t, error1, pipeToPromise, 'pipeTo should reject'); 3321cb0ef41Sopenharmony_ci }).then(() => ws.getWriter().write('this should succeed')); 3331cb0ef41Sopenharmony_ci}, 'abort should do nothing after the readable is errored'); 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_cipromise_test(t => { 3361cb0ef41Sopenharmony_ci let readController; 3371cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 3381cb0ef41Sopenharmony_ci start(c) { 3391cb0ef41Sopenharmony_ci readController = c; 3401cb0ef41Sopenharmony_ci } 3411cb0ef41Sopenharmony_ci }); 3421cb0ef41Sopenharmony_ci let resolveWrite; 3431cb0ef41Sopenharmony_ci const writePromise = new Promise(resolve => { 3441cb0ef41Sopenharmony_ci resolveWrite = resolve; 3451cb0ef41Sopenharmony_ci }); 3461cb0ef41Sopenharmony_ci const ws = new WritableStream({ 3471cb0ef41Sopenharmony_ci write() { 3481cb0ef41Sopenharmony_ci readController.error(error1); 3491cb0ef41Sopenharmony_ci return writePromise; 3501cb0ef41Sopenharmony_ci } 3511cb0ef41Sopenharmony_ci }); 3521cb0ef41Sopenharmony_ci const abortController = new AbortController(); 3531cb0ef41Sopenharmony_ci const signal = abortController.signal; 3541cb0ef41Sopenharmony_ci const pipeToPromise = rs.pipeTo(ws, { signal, preventAbort: true }); 3551cb0ef41Sopenharmony_ci readController.enqueue('a'); 3561cb0ef41Sopenharmony_ci return delay(0).then(() => { 3571cb0ef41Sopenharmony_ci abortController.abort(); 3581cb0ef41Sopenharmony_ci resolveWrite(); 3591cb0ef41Sopenharmony_ci return promise_rejects_exactly(t, error1, pipeToPromise, 'pipeTo should reject'); 3601cb0ef41Sopenharmony_ci }).then(() => ws.getWriter().write('this should succeed')); 3611cb0ef41Sopenharmony_ci}, 'abort should do nothing after the readable is errored, even with pending writes'); 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_cipromise_test(t => { 3641cb0ef41Sopenharmony_ci const rs = recordingReadableStream({ 3651cb0ef41Sopenharmony_ci pull(controller) { 3661cb0ef41Sopenharmony_ci return delay(0).then(() => controller.close()); 3671cb0ef41Sopenharmony_ci } 3681cb0ef41Sopenharmony_ci }); 3691cb0ef41Sopenharmony_ci let writeController; 3701cb0ef41Sopenharmony_ci const ws = new WritableStream({ 3711cb0ef41Sopenharmony_ci start(c) { 3721cb0ef41Sopenharmony_ci writeController = c; 3731cb0ef41Sopenharmony_ci } 3741cb0ef41Sopenharmony_ci }); 3751cb0ef41Sopenharmony_ci const abortController = new AbortController(); 3761cb0ef41Sopenharmony_ci const signal = abortController.signal; 3771cb0ef41Sopenharmony_ci const pipeToPromise = rs.pipeTo(ws, { signal, preventCancel: true }); 3781cb0ef41Sopenharmony_ci return Promise.resolve().then(() => { 3791cb0ef41Sopenharmony_ci writeController.error(error1); 3801cb0ef41Sopenharmony_ci return Promise.resolve(); 3811cb0ef41Sopenharmony_ci }).then(() => { 3821cb0ef41Sopenharmony_ci abortController.abort(); 3831cb0ef41Sopenharmony_ci return promise_rejects_exactly(t, error1, pipeToPromise, 'pipeTo should reject'); 3841cb0ef41Sopenharmony_ci }).then(() => { 3851cb0ef41Sopenharmony_ci assert_array_equals(rs.events, ['pull'], 'cancel should not have been called'); 3861cb0ef41Sopenharmony_ci }); 3871cb0ef41Sopenharmony_ci}, 'abort should do nothing after the writable is errored'); 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_cipromise_test(async t => { 3901cb0ef41Sopenharmony_ci const rs = new ReadableStream({ 3911cb0ef41Sopenharmony_ci pull(c) { 3921cb0ef41Sopenharmony_ci c.enqueue(new Uint8Array([])); 3931cb0ef41Sopenharmony_ci }, 3941cb0ef41Sopenharmony_ci type: "bytes", 3951cb0ef41Sopenharmony_ci }); 3961cb0ef41Sopenharmony_ci const ws = new WritableStream(); 3971cb0ef41Sopenharmony_ci const [first, second] = rs.tee(); 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci let aborted = false; 4001cb0ef41Sopenharmony_ci first.pipeTo(ws, { signal: AbortSignal.abort() }).catch(() => { 4011cb0ef41Sopenharmony_ci aborted = true; 4021cb0ef41Sopenharmony_ci }); 4031cb0ef41Sopenharmony_ci await delay(0); 4041cb0ef41Sopenharmony_ci assert_true(!aborted, "pipeTo should not resolve yet"); 4051cb0ef41Sopenharmony_ci await second.cancel(); 4061cb0ef41Sopenharmony_ci await delay(0); 4071cb0ef41Sopenharmony_ci assert_true(aborted, "pipeTo should be aborted now"); 4081cb0ef41Sopenharmony_ci}, "pipeTo on a teed readable byte stream should only be aborted when both branches are aborted"); 409