diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index a4a7f17925a18e..e5565462a12029 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -27,7 +27,7 @@ Last update: - performance-timeline: https://github.com/web-platform-tests/wpt/tree/17ebc3aea0/performance-timeline - resource-timing: https://github.com/web-platform-tests/wpt/tree/22d38586d0/resource-timing - resources: https://github.com/web-platform-tests/wpt/tree/1e140d63ec/resources -- streams: https://github.com/web-platform-tests/wpt/tree/9b03282a99/streams +- streams: https://github.com/web-platform-tests/wpt/tree/2bd26e124c/streams - url: https://github.com/web-platform-tests/wpt/tree/6a39784534/url - user-timing: https://github.com/web-platform-tests/wpt/tree/5ae85bf826/user-timing - wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/cde25e7e3c/wasm/jsapi diff --git a/test/fixtures/wpt/streams/piping/abort.any.js b/test/fixtures/wpt/streams/piping/abort.any.js index c9929df91cf688..e813b017769c68 100644 --- a/test/fixtures/wpt/streams/piping/abort.any.js +++ b/test/fixtures/wpt/streams/piping/abort.any.js @@ -183,6 +183,46 @@ for (const reason of [null, undefined, error1]) { }, `(reason: '${reason}') all pending writes should complete on abort`); } +for (const reason of [null, undefined, error1]) { + promise_test(async t => { + let rejectPull; + const pullPromise = new Promise((_, reject) => { + rejectPull = reject; + }); + let rejectCancel; + const cancelPromise = new Promise((_, reject) => { + rejectCancel = reject; + }); + const rs = recordingReadableStream({ + async pull() { + await Promise.race([ + pullPromise, + cancelPromise, + ]); + }, + cancel(reason) { + rejectCancel(reason); + }, + }); + const ws = new WritableStream(); + const abortController = new AbortController(); + const signal = abortController.signal; + const pipeToPromise = rs.pipeTo(ws, { signal }); + pipeToPromise.catch(() => {}); // Prevent unhandled rejection. + await delay(0); + abortController.abort(reason); + rejectPull('should not catch pull rejection'); + await delay(0); + assert_equals(rs.eventsWithoutPulls.length, 2, 'cancel should have been called'); + assert_equals(rs.eventsWithoutPulls[0], 'cancel', 'first event should be cancel'); + if (reason !== undefined) { + await promise_rejects_exactly(t, reason, pipeToPromise, 'pipeTo rejects with abort reason'); + } else { + await promise_rejects_dom(t, 'AbortError', pipeToPromise, 'pipeTo rejects with AbortError'); + } + }, `(reason: '${reason}') underlyingSource.cancel() should called when abort, even with pending pull`); +} + promise_test(t => { const rs = new ReadableStream({ pull(controller) { diff --git a/test/fixtures/wpt/streams/piping/detached-context-crash.html b/test/fixtures/wpt/streams/piping/detached-context-crash.html deleted file mode 100644 index 56271f12c3ae76..00000000000000 --- a/test/fixtures/wpt/streams/piping/detached-context-crash.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - diff --git a/test/fixtures/wpt/streams/readable-streams/cancel.any.js b/test/fixtures/wpt/streams/readable-streams/cancel.any.js index 9915c1fb6330c1..d44222f1497f0a 100644 --- a/test/fixtures/wpt/streams/readable-streams/cancel.any.js +++ b/test/fixtures/wpt/streams/readable-streams/cancel.any.js @@ -234,3 +234,28 @@ promise_test(() => { return Promise.all([rs.cancel(), rs.getReader().closed]); }, 'ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called'); + +promise_test(async () => { + + const events = []; + + const pendingPromise = new Promise(() => {}); + + const rs = new ReadableStream({ + pull() { + events.push('pull'); + return pendingPromise; + }, + cancel() { + events.push('cancel'); + } + }); + + const reader = rs.getReader(); + reader.read().catch(() => {}); // No await. + await delay(0); + await Promise.all([reader.cancel(), reader.closed]); + + assert_array_equals(events, ['pull', 'cancel'], 'cancel should have been called'); + +}, 'ReadableStream cancellation: underlyingSource.cancel() should called, even with pending pull'); diff --git a/test/fixtures/wpt/streams/readable-streams/from.any.js b/test/fixtures/wpt/streams/readable-streams/from.any.js index 58ad4d4add127d..2a4212ab890606 100644 --- a/test/fixtures/wpt/streams/readable-streams/from.any.js +++ b/test/fixtures/wpt/streams/readable-streams/from.any.js @@ -51,44 +51,50 @@ const iterableFactories = [ ['a sync iterable of values', () => { const chunks = ['a', 'b']; - const it = { + const iterator = { next() { return { done: chunks.length === 0, value: chunks.shift() }; - }, - [Symbol.iterator]: () => it + } + }; + const iterable = { + [Symbol.iterator]: () => iterator }; - return it; + return iterable; }], ['a sync iterable of promises', () => { const chunks = ['a', 'b']; - const it = { + const iterator = { next() { return chunks.length === 0 ? { done: true } : { done: false, value: Promise.resolve(chunks.shift()) }; - }, - [Symbol.iterator]: () => it + } + }; + const iterable = { + [Symbol.iterator]: () => iterator }; - return it; + return iterable; }], ['an async iterable', () => { const chunks = ['a', 'b']; - const it = { + const asyncIterator = { next() { return Promise.resolve({ done: chunks.length === 0, value: chunks.shift() }) - }, - [Symbol.asyncIterator]: () => it + } + }; + const asyncIterable = { + [Symbol.asyncIterator]: () => asyncIterator }; - return it; + return asyncIterable; }], ['a ReadableStream', () => { @@ -186,6 +192,18 @@ test(t => { assert_throws_exactly(theError, () => ReadableStream.from(iterable), 'from() should re-throw the error'); }, `ReadableStream.from ignores @@iterator if @@asyncIterator exists`); +test(() => { + const theError = new Error('a unique string'); + const iterable = { + [Symbol.asyncIterator]: null, + [Symbol.iterator]() { + throw theError + } + }; + + assert_throws_exactly(theError, () => ReadableStream.from(iterable), 'from() should re-throw the error'); +}, `ReadableStream.from ignores a null @@asyncIterator`); + promise_test(async () => { const iterable = { diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index 19ec205edca829..c9320269a28f2a 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -68,7 +68,7 @@ "path": "resources" }, "streams": { - "commit": "9b03282a99ef2314c1c2d5050a105a74a2940019", + "commit": "2bd26e124cf17b2f0a25c150794d640b07b2a870", "path": "streams" }, "url": { diff --git a/test/wpt/status/streams.json b/test/wpt/status/streams.json index 3b6e0ce6429f9d..5425c86bba8507 100644 --- a/test/wpt/status/streams.json +++ b/test/wpt/status/streams.json @@ -16,6 +16,13 @@ "readable-streams/cross-realm-crash.window.js": { "skip": "Browser-specific test" }, + "readable-streams/from.any.js": { + "fail": { + "expected": [ + "ReadableStream.from ignores a null @@asyncIterator" + ] + } + }, "readable-streams/owning-type-message-port.any.js": { "fail": { "note": "Readable streams with type owning are not yet supported", @@ -40,6 +47,9 @@ ] } }, + "readable-streams/read-task-handling.window.js": { + "skip": "Browser-specific test" + }, "transferable/deserialize-error.window.js": { "skip": "Browser-specific test" }, @@ -56,8 +66,5 @@ }, "transform-streams/invalid-realm.tentative.window.js": { "skip": "Browser-specific test" - }, - "readable-streams/read-task-handling.window.js": { - "skip": "Browser-specific test" } }