169 lines
5.1 KiB
JavaScript
169 lines
5.1 KiB
JavaScript
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])
|
|
);
|
|
}
|
|
});
|