Index: third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/reentrant-strategy.js |
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/reentrant-strategy.js b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/reentrant-strategy.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4ef9957f96651223f889caf855d1e768d3c6d866 |
--- /dev/null |
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/reentrant-strategy.js |
@@ -0,0 +1,179 @@ |
+'use strict'; |
+ |
+// These tests exercise the pathological case of calling WritableStream* methods from within the strategy.size() |
+// callback. This is not something any real code should ever do. Failures here indicate subtle deviations from the |
+// standard that may affect real, non-pathological code. |
+ |
+if (self.importScripts) { |
+ self.importScripts('/resources/testharness.js'); |
+ self.importScripts('../resources/test-utils.js'); |
+ self.importScripts('../resources/recording-streams.js'); |
+} |
+ |
+const error1 = { name: 'error1' }; |
+ |
+promise_test(() => { |
+ let writer; |
+ const strategy = { |
+ size(chunk) { |
+ if (chunk > 0) { |
+ writer.write(chunk - 1); |
+ } |
+ return chunk; |
+ } |
+ }; |
+ |
+ const ws = recordingWritableStream({}, strategy); |
+ writer = ws.getWriter(); |
+ return writer.write(2) |
+ .then(() => { |
+ assert_array_equals(ws.events, ['write', 0, 'write', 1, 'write', 2], 'writes should appear in order'); |
+ }); |
+}, 'writes should be written in the standard order'); |
+ |
+promise_test(() => { |
+ let writer; |
+ const events = []; |
+ const strategy = { |
+ size(chunk) { |
+ events.push('size', chunk); |
+ if (chunk > 0) { |
+ writer.write(chunk - 1) |
+ .then(() => events.push('writer.write done', chunk - 1)); |
+ } |
+ return chunk; |
+ } |
+ }; |
+ const ws = new WritableStream({ |
+ write(chunk) { |
+ events.push('sink.write', chunk); |
+ } |
+ }, strategy); |
+ writer = ws.getWriter(); |
+ return writer.write(2) |
+ .then(() => events.push('writer.write done', 2)) |
+ .then(() => flushAsyncEvents()) |
+ .then(() => { |
+ assert_array_equals(events, ['size', 2, 'size', 1, 'size', 0, |
+ 'sink.write', 0, 'sink.write', 1, 'writer.write done', 0, |
+ 'sink.write', 2, 'writer.write done', 1, |
+ 'writer.write done', 2], |
+ 'events should happen in standard order'); |
+ }); |
+}, 'writer.write() promises should resolve in the standard order'); |
+ |
+promise_test(t => { |
+ let controller; |
+ const strategy = { |
+ size() { |
+ controller.error(error1); |
+ return 1; |
+ } |
+ }; |
+ const ws = recordingWritableStream({ |
+ start(c) { |
+ controller = c; |
+ } |
+ }, strategy); |
+ const resolved = []; |
+ const writer = ws.getWriter(); |
+ const readyPromise1 = writer.ready.then(() => resolved.push('ready1')); |
+ const writePromise = promise_rejects(t, new TypeError(), writer.write(), |
+ 'write() should reject with a TypeError') |
+ .then(() => resolved.push('write')); |
+ const readyPromise2 = promise_rejects(t, error1, writer.ready, 'ready should reject with error1') |
+ .then(() => resolved.push('ready2')); |
+ const closedPromise = promise_rejects(t, error1, writer.closed, 'closed should reject with error1') |
+ .then(() => resolved.push('closed')); |
+ return Promise.all([readyPromise1, writePromise, readyPromise2, closedPromise]) |
+ .then(() => { |
+ assert_array_equals(resolved, ['ready1', 'write', 'ready2', 'closed'], |
+ 'promises should resolve in standard order'); |
+ assert_array_equals(ws.events, [], 'underlying sink write should not be called'); |
+ }); |
+}, 'controller.error() should work when called from within strategy.size()'); |
+ |
+promise_test(t => { |
+ let writer; |
+ const strategy = { |
+ size() { |
+ writer.close(); |
+ return 1; |
+ } |
+ }; |
+ |
+ const ws = recordingWritableStream({}, strategy); |
+ writer = ws.getWriter(); |
+ return promise_rejects(t, new TypeError(), writer.write('a'), 'write() promise should reject') |
+ .then(() => { |
+ assert_array_equals(ws.events, ['close'], 'sink.write() should not be called'); |
+ }); |
+}, 'close() should work when called from within strategy.size()'); |
+ |
+promise_test(t => { |
+ let writer; |
+ const strategy = { |
+ size() { |
+ writer.abort('nice'); |
+ return 1; |
+ } |
+ }; |
+ |
+ const ws = recordingWritableStream({}, strategy); |
+ writer = ws.getWriter(); |
+ return promise_rejects(t, new TypeError(), writer.write('a'), 'write() promise should reject') |
+ .then(() => { |
+ assert_array_equals(ws.events, ['abort', 'nice'], 'sink.write() should not be called'); |
+ }); |
+}, 'abort() should work when called from within strategy.size()'); |
+ |
+promise_test(t => { |
+ let writer; |
+ const strategy = { |
+ size() { |
+ writer.releaseLock(); |
+ return 1; |
+ } |
+ }; |
+ |
+ const ws = recordingWritableStream({}, strategy); |
+ writer = ws.getWriter(); |
+ const writePromise = promise_rejects(t, new TypeError(), writer.write('a'), 'write() promise should reject'); |
+ const readyPromise = promise_rejects(t, new TypeError(), writer.ready, 'ready promise should reject'); |
+ const closedPromise = promise_rejects(t, new TypeError(), writer.closed, 'closed promise should reject'); |
+ return Promise.all([writePromise, readyPromise, closedPromise]) |
+ .then(() => { |
+ assert_array_equals(ws.events, [], 'sink.write() should not be called'); |
+ }); |
+}, 'releaseLock() should abort the write() when called within strategy.size()'); |
+ |
+promise_test(t => { |
+ let writer1; |
+ let ws; |
+ let writePromise2; |
+ let closePromise; |
+ let closedPromise2; |
+ const strategy = { |
+ size(chunk) { |
+ if (chunk > 0) { |
+ writer1.releaseLock(); |
+ const writer2 = ws.getWriter(); |
+ writePromise2 = writer2.write(0); |
+ closePromise = writer2.close(); |
+ closedPromise2 = writer2.closed; |
+ } |
+ return 1; |
+ } |
+ }; |
+ ws = recordingWritableStream({}, strategy); |
+ writer1 = ws.getWriter(); |
+ const writePromise1 = promise_rejects(t, new TypeError(), writer1.write(1), 'write() promise should reject'); |
+ const readyPromise = promise_rejects(t, new TypeError(), writer1.ready, 'ready promise should reject'); |
+ const closedPromise1 = promise_rejects(t, new TypeError(), writer1.closed, 'closed promise should reject'); |
+ return Promise.all([writePromise1, readyPromise, closedPromise1, writePromise2, closePromise, closedPromise2]) |
+ .then(() => { |
+ assert_array_equals(ws.events, ['write', 0, 'close'], 'sink.write() should only be called once'); |
+ }); |
+}, 'original reader should error when new reader is created within strategy.size()'); |
+ |
+done(); |