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