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_ciconst error1 = new Error('error1'); 71cb0ef41Sopenharmony_cierror1.name = 'error1'; 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciconst error2 = new Error('error2'); 101cb0ef41Sopenharmony_cierror2.name = 'error2'; 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cipromise_test(() => { 131cb0ef41Sopenharmony_ci const ws = new WritableStream({ 141cb0ef41Sopenharmony_ci close() { 151cb0ef41Sopenharmony_ci return 'Hello'; 161cb0ef41Sopenharmony_ci } 171cb0ef41Sopenharmony_ci }); 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci const closePromise = writer.close(); 221cb0ef41Sopenharmony_ci return closePromise.then(value => assert_equals(value, undefined, 'fulfillment value must be undefined')); 231cb0ef41Sopenharmony_ci}, 'fulfillment value of writer.close() call must be undefined even if the underlying sink returns a non-undefined ' + 241cb0ef41Sopenharmony_ci 'value'); 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_cipromise_test(() => { 271cb0ef41Sopenharmony_ci let controller; 281cb0ef41Sopenharmony_ci let resolveClose; 291cb0ef41Sopenharmony_ci const ws = new WritableStream({ 301cb0ef41Sopenharmony_ci start(c) { 311cb0ef41Sopenharmony_ci controller = c; 321cb0ef41Sopenharmony_ci }, 331cb0ef41Sopenharmony_ci close() { 341cb0ef41Sopenharmony_ci return new Promise(resolve => { 351cb0ef41Sopenharmony_ci resolveClose = resolve; 361cb0ef41Sopenharmony_ci }); 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci }); 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci const closePromise = writer.close(); 431cb0ef41Sopenharmony_ci return flushAsyncEvents().then(() => { 441cb0ef41Sopenharmony_ci controller.error(error1); 451cb0ef41Sopenharmony_ci return flushAsyncEvents(); 461cb0ef41Sopenharmony_ci }).then(() => { 471cb0ef41Sopenharmony_ci resolveClose(); 481cb0ef41Sopenharmony_ci return Promise.all([ 491cb0ef41Sopenharmony_ci closePromise, 501cb0ef41Sopenharmony_ci writer.closed, 511cb0ef41Sopenharmony_ci flushAsyncEvents().then(() => writer.closed)]); 521cb0ef41Sopenharmony_ci }); 531cb0ef41Sopenharmony_ci}, 'when sink calls error asynchronously while sink close is in-flight, the stream should not become errored'); 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_cipromise_test(() => { 561cb0ef41Sopenharmony_ci let controller; 571cb0ef41Sopenharmony_ci const passedError = new Error('error me'); 581cb0ef41Sopenharmony_ci const ws = new WritableStream({ 591cb0ef41Sopenharmony_ci start(c) { 601cb0ef41Sopenharmony_ci controller = c; 611cb0ef41Sopenharmony_ci }, 621cb0ef41Sopenharmony_ci close() { 631cb0ef41Sopenharmony_ci controller.error(passedError); 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci }); 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci return writer.close().then(() => writer.closed); 701cb0ef41Sopenharmony_ci}, 'when sink calls error synchronously while closing, the stream should not become errored'); 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_cipromise_test(t => { 731cb0ef41Sopenharmony_ci const ws = new WritableStream({ 741cb0ef41Sopenharmony_ci close() { 751cb0ef41Sopenharmony_ci throw error1; 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci }); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci return Promise.all([ 821cb0ef41Sopenharmony_ci writer.write('y'), 831cb0ef41Sopenharmony_ci promise_rejects_exactly(t, error1, writer.close(), 'close() must reject with the error'), 841cb0ef41Sopenharmony_ci promise_rejects_exactly(t, error1, writer.closed, 'closed must reject with the error') 851cb0ef41Sopenharmony_ci ]); 861cb0ef41Sopenharmony_ci}, 'when the sink throws during close, and the close is requested while a write is still in-flight, the stream should ' + 871cb0ef41Sopenharmony_ci 'become errored during the close'); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_cipromise_test(() => { 901cb0ef41Sopenharmony_ci const ws = new WritableStream({ 911cb0ef41Sopenharmony_ci write(chunk, controller) { 921cb0ef41Sopenharmony_ci controller.error(error1); 931cb0ef41Sopenharmony_ci return new Promise(() => {}); 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci }); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 981cb0ef41Sopenharmony_ci writer.write('a'); 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci return delay(0).then(() => { 1011cb0ef41Sopenharmony_ci writer.releaseLock(); 1021cb0ef41Sopenharmony_ci }); 1031cb0ef41Sopenharmony_ci}, 'releaseLock on a stream with a pending write in which the stream has been errored'); 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_cipromise_test(() => { 1061cb0ef41Sopenharmony_ci let controller; 1071cb0ef41Sopenharmony_ci const ws = new WritableStream({ 1081cb0ef41Sopenharmony_ci start(c) { 1091cb0ef41Sopenharmony_ci controller = c; 1101cb0ef41Sopenharmony_ci }, 1111cb0ef41Sopenharmony_ci close() { 1121cb0ef41Sopenharmony_ci controller.error(error1); 1131cb0ef41Sopenharmony_ci return new Promise(() => {}); 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci }); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 1181cb0ef41Sopenharmony_ci writer.close(); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci return delay(0).then(() => { 1211cb0ef41Sopenharmony_ci writer.releaseLock(); 1221cb0ef41Sopenharmony_ci }); 1231cb0ef41Sopenharmony_ci}, 'releaseLock on a stream with a pending close in which controller.error() was called'); 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_cipromise_test(() => { 1261cb0ef41Sopenharmony_ci const ws = recordingWritableStream(); 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci return writer.ready.then(() => { 1311cb0ef41Sopenharmony_ci assert_equals(writer.desiredSize, 1, 'desiredSize should be 1'); 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci writer.close(); 1341cb0ef41Sopenharmony_ci assert_equals(writer.desiredSize, 1, 'desiredSize should be still 1'); 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci return writer.ready.then(v => { 1371cb0ef41Sopenharmony_ci assert_equals(v, undefined, 'ready promise should be fulfilled with undefined'); 1381cb0ef41Sopenharmony_ci assert_array_equals(ws.events, ['close'], 'write and abort should not be called'); 1391cb0ef41Sopenharmony_ci }); 1401cb0ef41Sopenharmony_ci }); 1411cb0ef41Sopenharmony_ci}, 'when close is called on a WritableStream in writable state, ready should return a fulfilled promise'); 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_cipromise_test(() => { 1441cb0ef41Sopenharmony_ci const ws = recordingWritableStream({ 1451cb0ef41Sopenharmony_ci write() { 1461cb0ef41Sopenharmony_ci return new Promise(() => {}); 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci }); 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci return writer.ready.then(() => { 1531cb0ef41Sopenharmony_ci writer.write('a'); 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci assert_equals(writer.desiredSize, 0, 'desiredSize should be 0'); 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci let calledClose = false; 1581cb0ef41Sopenharmony_ci return Promise.all([ 1591cb0ef41Sopenharmony_ci writer.ready.then(v => { 1601cb0ef41Sopenharmony_ci assert_equals(v, undefined, 'ready promise should be fulfilled with undefined'); 1611cb0ef41Sopenharmony_ci assert_true(calledClose, 'ready should not be fulfilled before writer.close() is called'); 1621cb0ef41Sopenharmony_ci assert_array_equals(ws.events, ['write', 'a'], 'sink abort() should not be called'); 1631cb0ef41Sopenharmony_ci }), 1641cb0ef41Sopenharmony_ci flushAsyncEvents().then(() => { 1651cb0ef41Sopenharmony_ci writer.close(); 1661cb0ef41Sopenharmony_ci calledClose = true; 1671cb0ef41Sopenharmony_ci }) 1681cb0ef41Sopenharmony_ci ]); 1691cb0ef41Sopenharmony_ci }); 1701cb0ef41Sopenharmony_ci}, 'when close is called on a WritableStream in waiting state, ready promise should be fulfilled'); 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_cipromise_test(() => { 1731cb0ef41Sopenharmony_ci let asyncCloseFinished = false; 1741cb0ef41Sopenharmony_ci const ws = recordingWritableStream({ 1751cb0ef41Sopenharmony_ci close() { 1761cb0ef41Sopenharmony_ci return flushAsyncEvents().then(() => { 1771cb0ef41Sopenharmony_ci asyncCloseFinished = true; 1781cb0ef41Sopenharmony_ci }); 1791cb0ef41Sopenharmony_ci } 1801cb0ef41Sopenharmony_ci }); 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 1831cb0ef41Sopenharmony_ci return writer.ready.then(() => { 1841cb0ef41Sopenharmony_ci writer.write('a'); 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci writer.close(); 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci return writer.ready.then(v => { 1891cb0ef41Sopenharmony_ci assert_false(asyncCloseFinished, 'ready promise should be fulfilled before async close completes'); 1901cb0ef41Sopenharmony_ci assert_equals(v, undefined, 'ready promise should be fulfilled with undefined'); 1911cb0ef41Sopenharmony_ci assert_array_equals(ws.events, ['write', 'a', 'close'], 'sink abort() should not be called'); 1921cb0ef41Sopenharmony_ci }); 1931cb0ef41Sopenharmony_ci }); 1941cb0ef41Sopenharmony_ci}, 'when close is called on a WritableStream in waiting state, ready should be fulfilled immediately even if close ' + 1951cb0ef41Sopenharmony_ci 'takes a long time'); 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_cipromise_test(t => { 1981cb0ef41Sopenharmony_ci const rejection = { name: 'letter' }; 1991cb0ef41Sopenharmony_ci const ws = new WritableStream({ 2001cb0ef41Sopenharmony_ci close() { 2011cb0ef41Sopenharmony_ci return { 2021cb0ef41Sopenharmony_ci then(onFulfilled, onRejected) { onRejected(rejection); } 2031cb0ef41Sopenharmony_ci }; 2041cb0ef41Sopenharmony_ci } 2051cb0ef41Sopenharmony_ci }); 2061cb0ef41Sopenharmony_ci return promise_rejects_exactly(t, rejection, ws.getWriter().close(), 'close() should return a rejection'); 2071cb0ef41Sopenharmony_ci}, 'returning a thenable from close() should work'); 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_cipromise_test(t => { 2101cb0ef41Sopenharmony_ci const ws = new WritableStream(); 2111cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 2121cb0ef41Sopenharmony_ci return writer.ready.then(() => { 2131cb0ef41Sopenharmony_ci const closePromise = writer.close(); 2141cb0ef41Sopenharmony_ci const closedPromise = writer.closed; 2151cb0ef41Sopenharmony_ci writer.releaseLock(); 2161cb0ef41Sopenharmony_ci return Promise.all([ 2171cb0ef41Sopenharmony_ci closePromise, 2181cb0ef41Sopenharmony_ci promise_rejects_js(t, TypeError, closedPromise, '.closed promise should be rejected') 2191cb0ef41Sopenharmony_ci ]); 2201cb0ef41Sopenharmony_ci }); 2211cb0ef41Sopenharmony_ci}, 'releaseLock() should not change the result of sync close()'); 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_cipromise_test(t => { 2241cb0ef41Sopenharmony_ci const ws = new WritableStream({ 2251cb0ef41Sopenharmony_ci close() { 2261cb0ef41Sopenharmony_ci return flushAsyncEvents(); 2271cb0ef41Sopenharmony_ci } 2281cb0ef41Sopenharmony_ci }); 2291cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 2301cb0ef41Sopenharmony_ci return writer.ready.then(() => { 2311cb0ef41Sopenharmony_ci const closePromise = writer.close(); 2321cb0ef41Sopenharmony_ci const closedPromise = writer.closed; 2331cb0ef41Sopenharmony_ci writer.releaseLock(); 2341cb0ef41Sopenharmony_ci return Promise.all([ 2351cb0ef41Sopenharmony_ci closePromise, 2361cb0ef41Sopenharmony_ci promise_rejects_js(t, TypeError, closedPromise, '.closed promise should be rejected') 2371cb0ef41Sopenharmony_ci ]); 2381cb0ef41Sopenharmony_ci }); 2391cb0ef41Sopenharmony_ci}, 'releaseLock() should not change the result of async close()'); 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_cipromise_test(() => { 2421cb0ef41Sopenharmony_ci let resolveClose; 2431cb0ef41Sopenharmony_ci const ws = new WritableStream({ 2441cb0ef41Sopenharmony_ci close() { 2451cb0ef41Sopenharmony_ci const promise = new Promise(resolve => { 2461cb0ef41Sopenharmony_ci resolveClose = resolve; 2471cb0ef41Sopenharmony_ci }); 2481cb0ef41Sopenharmony_ci return promise; 2491cb0ef41Sopenharmony_ci } 2501cb0ef41Sopenharmony_ci }); 2511cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 2521cb0ef41Sopenharmony_ci const closePromise = writer.close(); 2531cb0ef41Sopenharmony_ci writer.releaseLock(); 2541cb0ef41Sopenharmony_ci return delay(0).then(() => { 2551cb0ef41Sopenharmony_ci resolveClose(); 2561cb0ef41Sopenharmony_ci return closePromise.then(() => { 2571cb0ef41Sopenharmony_ci assert_equals(ws.getWriter().desiredSize, 0, 'desiredSize should be 0'); 2581cb0ef41Sopenharmony_ci }); 2591cb0ef41Sopenharmony_ci }); 2601cb0ef41Sopenharmony_ci}, 'close() should set state to CLOSED even if writer has detached'); 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_cipromise_test(() => { 2631cb0ef41Sopenharmony_ci let resolveClose; 2641cb0ef41Sopenharmony_ci const ws = new WritableStream({ 2651cb0ef41Sopenharmony_ci close() { 2661cb0ef41Sopenharmony_ci const promise = new Promise(resolve => { 2671cb0ef41Sopenharmony_ci resolveClose = resolve; 2681cb0ef41Sopenharmony_ci }); 2691cb0ef41Sopenharmony_ci return promise; 2701cb0ef41Sopenharmony_ci } 2711cb0ef41Sopenharmony_ci }); 2721cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 2731cb0ef41Sopenharmony_ci writer.close(); 2741cb0ef41Sopenharmony_ci writer.releaseLock(); 2751cb0ef41Sopenharmony_ci return delay(0).then(() => { 2761cb0ef41Sopenharmony_ci const abortingWriter = ws.getWriter(); 2771cb0ef41Sopenharmony_ci const abortPromise = abortingWriter.abort(); 2781cb0ef41Sopenharmony_ci abortingWriter.releaseLock(); 2791cb0ef41Sopenharmony_ci resolveClose(); 2801cb0ef41Sopenharmony_ci return abortPromise; 2811cb0ef41Sopenharmony_ci }); 2821cb0ef41Sopenharmony_ci}, 'the promise returned by async abort during close should resolve'); 2831cb0ef41Sopenharmony_ci 2841cb0ef41Sopenharmony_ci// Though the order in which the promises are fulfilled or rejected is arbitrary, we're checking it for 2851cb0ef41Sopenharmony_ci// interoperability. We can change the order as long as we file bugs on all implementers to update to the latest tests 2861cb0ef41Sopenharmony_ci// to keep them interoperable. 2871cb0ef41Sopenharmony_ci 2881cb0ef41Sopenharmony_cipromise_test(() => { 2891cb0ef41Sopenharmony_ci const ws = new WritableStream({}); 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ci const closePromise = writer.close(); 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci const events = []; 2961cb0ef41Sopenharmony_ci return Promise.all([ 2971cb0ef41Sopenharmony_ci closePromise.then(() => { 2981cb0ef41Sopenharmony_ci events.push('closePromise'); 2991cb0ef41Sopenharmony_ci }), 3001cb0ef41Sopenharmony_ci writer.closed.then(() => { 3011cb0ef41Sopenharmony_ci events.push('closed'); 3021cb0ef41Sopenharmony_ci }) 3031cb0ef41Sopenharmony_ci ]).then(() => { 3041cb0ef41Sopenharmony_ci assert_array_equals(events, ['closePromise', 'closed'], 3051cb0ef41Sopenharmony_ci 'promises must fulfill/reject in the expected order'); 3061cb0ef41Sopenharmony_ci }); 3071cb0ef41Sopenharmony_ci}, 'promises must fulfill/reject in the expected order on closure'); 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_cipromise_test(() => { 3101cb0ef41Sopenharmony_ci const ws = new WritableStream({}); 3111cb0ef41Sopenharmony_ci 3121cb0ef41Sopenharmony_ci // Wait until the WritableStream starts so that the close() call gets processed. Otherwise, abort() will be 3131cb0ef41Sopenharmony_ci // processed without waiting for completion of the close(). 3141cb0ef41Sopenharmony_ci return delay(0).then(() => { 3151cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci const closePromise = writer.close(); 3181cb0ef41Sopenharmony_ci const abortPromise = writer.abort(error1); 3191cb0ef41Sopenharmony_ci 3201cb0ef41Sopenharmony_ci const events = []; 3211cb0ef41Sopenharmony_ci return Promise.all([ 3221cb0ef41Sopenharmony_ci closePromise.then(() => { 3231cb0ef41Sopenharmony_ci events.push('closePromise'); 3241cb0ef41Sopenharmony_ci }), 3251cb0ef41Sopenharmony_ci abortPromise.then(() => { 3261cb0ef41Sopenharmony_ci events.push('abortPromise'); 3271cb0ef41Sopenharmony_ci }), 3281cb0ef41Sopenharmony_ci writer.closed.then(() => { 3291cb0ef41Sopenharmony_ci events.push('closed'); 3301cb0ef41Sopenharmony_ci }) 3311cb0ef41Sopenharmony_ci ]).then(() => { 3321cb0ef41Sopenharmony_ci assert_array_equals(events, ['closePromise', 'abortPromise', 'closed'], 3331cb0ef41Sopenharmony_ci 'promises must fulfill/reject in the expected order'); 3341cb0ef41Sopenharmony_ci }); 3351cb0ef41Sopenharmony_ci }); 3361cb0ef41Sopenharmony_ci}, 'promises must fulfill/reject in the expected order on aborted closure'); 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_cipromise_test(t => { 3391cb0ef41Sopenharmony_ci const ws = new WritableStream({ 3401cb0ef41Sopenharmony_ci close() { 3411cb0ef41Sopenharmony_ci return Promise.reject(error1); 3421cb0ef41Sopenharmony_ci } 3431cb0ef41Sopenharmony_ci }); 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci // Wait until the WritableStream starts so that the close() call gets processed. 3461cb0ef41Sopenharmony_ci return delay(0).then(() => { 3471cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_ci const closePromise = writer.close(); 3501cb0ef41Sopenharmony_ci const abortPromise = writer.abort(error2); 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci const events = []; 3531cb0ef41Sopenharmony_ci closePromise.catch(() => events.push('closePromise')); 3541cb0ef41Sopenharmony_ci abortPromise.catch(() => events.push('abortPromise')); 3551cb0ef41Sopenharmony_ci writer.closed.catch(() => events.push('closed')); 3561cb0ef41Sopenharmony_ci return Promise.all([ 3571cb0ef41Sopenharmony_ci promise_rejects_exactly(t, error1, closePromise, 3581cb0ef41Sopenharmony_ci 'closePromise must reject with the error returned from the sink\'s close method'), 3591cb0ef41Sopenharmony_ci promise_rejects_exactly(t, error1, abortPromise, 3601cb0ef41Sopenharmony_ci 'abortPromise must reject with the error returned from the sink\'s close method'), 3611cb0ef41Sopenharmony_ci promise_rejects_exactly(t, error2, writer.closed, 3621cb0ef41Sopenharmony_ci 'writer.closed must reject with error2') 3631cb0ef41Sopenharmony_ci ]).then(() => { 3641cb0ef41Sopenharmony_ci assert_array_equals(events, ['closePromise', 'abortPromise', 'closed'], 3651cb0ef41Sopenharmony_ci 'promises must fulfill/reject in the expected order'); 3661cb0ef41Sopenharmony_ci }); 3671cb0ef41Sopenharmony_ci }); 3681cb0ef41Sopenharmony_ci}, 'promises must fulfill/reject in the expected order on aborted and errored closure'); 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_cipromise_test(t => { 3711cb0ef41Sopenharmony_ci let resolveWrite; 3721cb0ef41Sopenharmony_ci let controller; 3731cb0ef41Sopenharmony_ci const ws = new WritableStream({ 3741cb0ef41Sopenharmony_ci write(chunk, c) { 3751cb0ef41Sopenharmony_ci controller = c; 3761cb0ef41Sopenharmony_ci return new Promise(resolve => { 3771cb0ef41Sopenharmony_ci resolveWrite = resolve; 3781cb0ef41Sopenharmony_ci }); 3791cb0ef41Sopenharmony_ci } 3801cb0ef41Sopenharmony_ci }); 3811cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 3821cb0ef41Sopenharmony_ci return writer.ready.then(() => { 3831cb0ef41Sopenharmony_ci const writePromise = writer.write('c'); 3841cb0ef41Sopenharmony_ci controller.error(error1); 3851cb0ef41Sopenharmony_ci const closePromise = writer.close(); 3861cb0ef41Sopenharmony_ci let closeRejected = false; 3871cb0ef41Sopenharmony_ci closePromise.catch(() => { 3881cb0ef41Sopenharmony_ci closeRejected = true; 3891cb0ef41Sopenharmony_ci }); 3901cb0ef41Sopenharmony_ci return flushAsyncEvents().then(() => { 3911cb0ef41Sopenharmony_ci assert_false(closeRejected); 3921cb0ef41Sopenharmony_ci resolveWrite(); 3931cb0ef41Sopenharmony_ci return Promise.all([ 3941cb0ef41Sopenharmony_ci writePromise, 3951cb0ef41Sopenharmony_ci promise_rejects_exactly(t, error1, closePromise, 'close() should reject') 3961cb0ef41Sopenharmony_ci ]).then(() => { 3971cb0ef41Sopenharmony_ci assert_true(closeRejected); 3981cb0ef41Sopenharmony_ci }); 3991cb0ef41Sopenharmony_ci }); 4001cb0ef41Sopenharmony_ci }); 4011cb0ef41Sopenharmony_ci}, 'close() should not reject until no sink methods are in flight'); 4021cb0ef41Sopenharmony_ci 4031cb0ef41Sopenharmony_cipromise_test(() => { 4041cb0ef41Sopenharmony_ci const ws = new WritableStream(); 4051cb0ef41Sopenharmony_ci const writer1 = ws.getWriter(); 4061cb0ef41Sopenharmony_ci return writer1.close().then(() => { 4071cb0ef41Sopenharmony_ci writer1.releaseLock(); 4081cb0ef41Sopenharmony_ci const writer2 = ws.getWriter(); 4091cb0ef41Sopenharmony_ci const ready = writer2.ready; 4101cb0ef41Sopenharmony_ci assert_equals(ready.constructor, Promise); 4111cb0ef41Sopenharmony_ci return ready; 4121cb0ef41Sopenharmony_ci }); 4131cb0ef41Sopenharmony_ci}, 'ready promise should be initialised as fulfilled for a writer on a closed stream'); 4141cb0ef41Sopenharmony_ci 4151cb0ef41Sopenharmony_cipromise_test(() => { 4161cb0ef41Sopenharmony_ci const ws = new WritableStream(); 4171cb0ef41Sopenharmony_ci ws.close(); 4181cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 4191cb0ef41Sopenharmony_ci return writer.closed; 4201cb0ef41Sopenharmony_ci}, 'close() on a writable stream should work'); 4211cb0ef41Sopenharmony_ci 4221cb0ef41Sopenharmony_cipromise_test(t => { 4231cb0ef41Sopenharmony_ci const ws = new WritableStream(); 4241cb0ef41Sopenharmony_ci ws.getWriter(); 4251cb0ef41Sopenharmony_ci return promise_rejects_js(t, TypeError, ws.close(), 'close should reject'); 4261cb0ef41Sopenharmony_ci}, 'close() on a locked stream should reject'); 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_cipromise_test(t => { 4291cb0ef41Sopenharmony_ci const ws = new WritableStream({ 4301cb0ef41Sopenharmony_ci start(controller) { 4311cb0ef41Sopenharmony_ci controller.error(error1); 4321cb0ef41Sopenharmony_ci } 4331cb0ef41Sopenharmony_ci }); 4341cb0ef41Sopenharmony_ci return promise_rejects_exactly(t, error1, ws.close(), 'close should reject with error1'); 4351cb0ef41Sopenharmony_ci}, 'close() on an erroring stream should reject'); 4361cb0ef41Sopenharmony_ci 4371cb0ef41Sopenharmony_cipromise_test(t => { 4381cb0ef41Sopenharmony_ci const ws = new WritableStream({ 4391cb0ef41Sopenharmony_ci start(controller) { 4401cb0ef41Sopenharmony_ci controller.error(error1); 4411cb0ef41Sopenharmony_ci } 4421cb0ef41Sopenharmony_ci }); 4431cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 4441cb0ef41Sopenharmony_ci return promise_rejects_exactly(t, error1, writer.closed, 'closed should reject with the error').then(() => { 4451cb0ef41Sopenharmony_ci writer.releaseLock(); 4461cb0ef41Sopenharmony_ci return promise_rejects_js(t, TypeError, ws.close(), 'close should reject'); 4471cb0ef41Sopenharmony_ci }); 4481cb0ef41Sopenharmony_ci}, 'close() on an errored stream should reject'); 4491cb0ef41Sopenharmony_ci 4501cb0ef41Sopenharmony_cipromise_test(t => { 4511cb0ef41Sopenharmony_ci const ws = new WritableStream(); 4521cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 4531cb0ef41Sopenharmony_ci return writer.close().then(() => { 4541cb0ef41Sopenharmony_ci return promise_rejects_js(t, TypeError, ws.close(), 'close should reject'); 4551cb0ef41Sopenharmony_ci }); 4561cb0ef41Sopenharmony_ci}, 'close() on an closed stream should reject'); 4571cb0ef41Sopenharmony_ci 4581cb0ef41Sopenharmony_cipromise_test(t => { 4591cb0ef41Sopenharmony_ci const ws = new WritableStream({ 4601cb0ef41Sopenharmony_ci close() { 4611cb0ef41Sopenharmony_ci return new Promise(() => {}); 4621cb0ef41Sopenharmony_ci } 4631cb0ef41Sopenharmony_ci }); 4641cb0ef41Sopenharmony_ci 4651cb0ef41Sopenharmony_ci const writer = ws.getWriter(); 4661cb0ef41Sopenharmony_ci writer.close(); 4671cb0ef41Sopenharmony_ci writer.releaseLock(); 4681cb0ef41Sopenharmony_ci 4691cb0ef41Sopenharmony_ci return promise_rejects_js(t, TypeError, ws.close(), 'close should reject'); 4701cb0ef41Sopenharmony_ci}, 'close() on a stream with a pending close should reject'); 471