tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

structured-clone-battery-of-tests-with-transferables.js (5224B)


      1 structuredCloneBatteryOfTests.push({
      2  description: 'ArrayBuffer',
      3  async f(runner) {
      4    const buffer = new Uint8Array([1]).buffer;
      5    const copy = await runner.structuredClone(buffer, [buffer]);
      6    assert_equals(buffer.byteLength, 0);
      7    assert_equals(copy.byteLength, 1);
      8  }
      9 });
     10 
     11 structuredCloneBatteryOfTests.push({
     12  description: 'MessagePort',
     13  async f(runner) {
     14    const {port1, port2} = new MessageChannel();
     15    const copy = await runner.structuredClone(port2, [port2]);
     16    const msg = new Promise(resolve => port1.onmessage = resolve);
     17    copy.postMessage('ohai');
     18    assert_equals((await msg).data, 'ohai');
     19  }
     20 });
     21 
     22 // TODO: ImageBitmap
     23 
     24 structuredCloneBatteryOfTests.push({
     25  description: 'A detached ArrayBuffer cannot be transferred',
     26  async f(runner, t) {
     27    const buffer = new ArrayBuffer();
     28    await runner.structuredClone(buffer, [buffer]);
     29    await promise_rejects_dom(
     30      t,
     31      "DataCloneError",
     32      runner.structuredClone(buffer, [buffer])
     33    );
     34  }
     35 });
     36 
     37 structuredCloneBatteryOfTests.push({
     38  description: 'A detached platform object cannot be transferred',
     39  async f(runner, t) {
     40    const {port1} = new MessageChannel();
     41    await runner.structuredClone(port1, [port1]);
     42    await promise_rejects_dom(
     43      t,
     44      "DataCloneError",
     45      runner.structuredClone(port1, [port1])
     46    );
     47  }
     48 });
     49 
     50 structuredCloneBatteryOfTests.push({
     51  description: 'Transferring a non-transferable platform object fails',
     52  async f(runner, t) {
     53    const blob = new Blob();
     54    await promise_rejects_dom(
     55      t,
     56      "DataCloneError",
     57      runner.structuredClone(blob, [blob])
     58    );
     59  }
     60 });
     61 
     62 structuredCloneBatteryOfTests.push({
     63  description: 'An object whose interface is deleted from the global object must still be received',
     64  async f(runner) {
     65    const {port1} = new MessageChannel();
     66    const messagePortInterface = globalThis.MessagePort;
     67    delete globalThis.MessagePort;
     68    try {
     69      const transfer = await runner.structuredClone(port1, [port1]);
     70      assert_true(transfer instanceof messagePortInterface);
     71    } finally {
     72      globalThis.MessagePort = messagePortInterface;
     73    }
     74  }
     75 });
     76 
     77 structuredCloneBatteryOfTests.push({
     78  description: 'A subclass instance will be received as its closest transferable superclass',
     79  async f(runner) {
     80    // MessagePort doesn't have a constructor, so we must use something else.
     81 
     82    // Make sure that ReadableStream is transferable before we test its subclasses.
     83    try {
     84      const stream = new ReadableStream();
     85      await runner.structuredClone(stream, [stream]);
     86    } catch(err) {
     87      if (err instanceof DOMException && err.code === DOMException.DATA_CLONE_ERR) {
     88        throw new OptionalFeatureUnsupportedError("ReadableStream isn't transferable");
     89      } else {
     90        throw err;
     91      }
     92    }
     93 
     94    class ReadableStreamSubclass extends ReadableStream {}
     95    const original = new ReadableStreamSubclass();
     96    const transfer = await runner.structuredClone(original, [original]);
     97    assert_equals(Object.getPrototypeOf(transfer), ReadableStream.prototype);
     98  }
     99 });
    100 
    101 structuredCloneBatteryOfTests.push({
    102  description: 'Resizable ArrayBuffer is transferable',
    103  async f(runner) {
    104    const buffer = new ArrayBuffer(16, { maxByteLength: 1024 });
    105    const copy = await runner.structuredClone(buffer, [buffer]);
    106    assert_equals(buffer.byteLength, 0);
    107    assert_equals(copy.byteLength, 16);
    108    assert_equals(copy.maxByteLength, 1024);
    109    assert_true(copy.resizable);
    110  }
    111 });
    112 
    113 structuredCloneBatteryOfTests.push({
    114  description: 'Length-tracking TypedArray is transferable',
    115  async f(runner) {
    116    const ab = new ArrayBuffer(16, { maxByteLength: 1024 });
    117    const ta = new Uint8Array(ab);
    118    const copy = await runner.structuredClone(ta, [ab]);
    119    assert_equals(ab.byteLength, 0);
    120    assert_equals(copy.buffer.byteLength, 16);
    121    assert_equals(copy.buffer.maxByteLength, 1024);
    122    assert_true(copy.buffer.resizable);
    123    copy.buffer.resize(32);
    124    assert_equals(copy.byteLength, 32);
    125  }
    126 });
    127 
    128 structuredCloneBatteryOfTests.push({
    129  description: 'Length-tracking DataView is transferable',
    130  async f(runner) {
    131    const ab = new ArrayBuffer(16, { maxByteLength: 1024 });
    132    const dv = new DataView(ab);
    133    const copy = await runner.structuredClone(dv, [ab]);
    134    assert_equals(ab.byteLength, 0);
    135    assert_equals(copy.buffer.byteLength, 16);
    136    assert_equals(copy.buffer.maxByteLength, 1024);
    137    assert_true(copy.buffer.resizable);
    138    copy.buffer.resize(32);
    139    assert_equals(copy.byteLength, 32);
    140  }
    141 });
    142 
    143 structuredCloneBatteryOfTests.push({
    144  description: 'Transferring OOB TypedArray throws',
    145  async f(runner, t) {
    146    const ab = new ArrayBuffer(16, { maxByteLength: 1024 });
    147    const ta = new Uint8Array(ab, 8);
    148    ab.resize(0);
    149    await promise_rejects_dom(
    150      t,
    151      "DataCloneError",
    152      runner.structuredClone(ta, [ab])
    153    );
    154  }
    155 });
    156 
    157 structuredCloneBatteryOfTests.push({
    158  description: 'Transferring OOB DataView throws',
    159  async f(runner, t) {
    160    const ab = new ArrayBuffer(16, { maxByteLength: 1024 });
    161    const dv = new DataView(ab, 8);
    162    ab.resize(0);
    163    await promise_rejects_dom(
    164      t,
    165      "DataCloneError",
    166      runner.structuredClone(dv, [ab])
    167    );
    168  }
    169 });