diff options
Diffstat (limited to 'testing/web-platform/tests/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js')
-rw-r--r-- | testing/web-platform/tests/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js b/testing/web-platform/tests/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js new file mode 100644 index 0000000000..23cf4f651a --- /dev/null +++ b/testing/web-platform/tests/html/webappapis/structured-clone/structured-clone-battery-of-tests-with-transferables.js @@ -0,0 +1,169 @@ +structuredCloneBatteryOfTests.push({ + description: 'ArrayBuffer', + async f(runner) { + const buffer = new Uint8Array([1]).buffer; + const copy = await runner.structuredClone(buffer, [buffer]); + assert_equals(buffer.byteLength, 0); + assert_equals(copy.byteLength, 1); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'MessagePort', + async f(runner) { + const {port1, port2} = new MessageChannel(); + const copy = await runner.structuredClone(port2, [port2]); + const msg = new Promise(resolve => port1.onmessage = resolve); + copy.postMessage('ohai'); + assert_equals((await msg).data, 'ohai'); + } +}); + +// TODO: ImageBitmap + +structuredCloneBatteryOfTests.push({ + description: 'A detached ArrayBuffer cannot be transferred', + async f(runner, t) { + const buffer = new ArrayBuffer(); + await runner.structuredClone(buffer, [buffer]); + await promise_rejects_dom( + t, + "DataCloneError", + runner.structuredClone(buffer, [buffer]) + ); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'A detached platform object cannot be transferred', + async f(runner, t) { + const {port1} = new MessageChannel(); + await runner.structuredClone(port1, [port1]); + await promise_rejects_dom( + t, + "DataCloneError", + runner.structuredClone(port1, [port1]) + ); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Transferring a non-transferable platform object fails', + async f(runner, t) { + const blob = new Blob(); + await promise_rejects_dom( + t, + "DataCloneError", + runner.structuredClone(blob, [blob]) + ); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'An object whose interface is deleted from the global object must still be received', + async f(runner) { + const {port1} = new MessageChannel(); + const messagePortInterface = globalThis.MessagePort; + delete globalThis.MessagePort; + try { + const transfer = await runner.structuredClone(port1, [port1]); + assert_true(transfer instanceof messagePortInterface); + } finally { + globalThis.MessagePort = messagePortInterface; + } + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'A subclass instance will be received as its closest transferable superclass', + async f(runner) { + // MessagePort doesn't have a constructor, so we must use something else. + + // Make sure that ReadableStream is transferable before we test its subclasses. + try { + const stream = new ReadableStream(); + await runner.structuredClone(stream, [stream]); + } catch(err) { + if (err instanceof DOMException && err.code === DOMException.DATA_CLONE_ERR) { + throw new OptionalFeatureUnsupportedError("ReadableStream isn't transferable"); + } else { + throw err; + } + } + + class ReadableStreamSubclass extends ReadableStream {} + const original = new ReadableStreamSubclass(); + const transfer = await runner.structuredClone(original, [original]); + assert_equals(Object.getPrototypeOf(transfer), ReadableStream.prototype); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Resizable ArrayBuffer is transferable', + async f(runner) { + const buffer = new ArrayBuffer(16, { maxByteLength: 1024 }); + const copy = await runner.structuredClone(buffer, [buffer]); + assert_equals(buffer.byteLength, 0); + assert_equals(copy.byteLength, 16); + assert_equals(copy.maxByteLength, 1024); + assert_true(copy.resizable); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Length-tracking TypedArray is transferable', + async f(runner) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const ta = new Uint8Array(ab); + const copy = await runner.structuredClone(ta, [ab]); + assert_equals(ab.byteLength, 0); + assert_equals(copy.buffer.byteLength, 16); + assert_equals(copy.buffer.maxByteLength, 1024); + assert_true(copy.buffer.resizable); + copy.buffer.resize(32); + assert_equals(copy.byteLength, 32); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Length-tracking DataView is transferable', + async f(runner) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const dv = new DataView(ab); + const copy = await runner.structuredClone(dv, [ab]); + assert_equals(ab.byteLength, 0); + assert_equals(copy.buffer.byteLength, 16); + assert_equals(copy.buffer.maxByteLength, 1024); + assert_true(copy.buffer.resizable); + copy.buffer.resize(32); + assert_equals(copy.byteLength, 32); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Transferring OOB TypedArray throws', + async f(runner, t) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const ta = new Uint8Array(ab, 8); + ab.resize(0); + await promise_rejects_dom( + t, + "DataCloneError", + runner.structuredClone(ta, [ab]) + ); + } +}); + +structuredCloneBatteryOfTests.push({ + description: 'Transferring OOB DataView throws', + async f(runner, t) { + const ab = new ArrayBuffer(16, { maxByteLength: 1024 }); + const dv = new DataView(ab, 8); + ab.resize(0); + await promise_rejects_dom( + t, + "DataCloneError", + runner.structuredClone(dv, [ab]) + ); + } +}); |