summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/IndexedDB/idb-binary-key-roundtrip.htm
blob: de3889a71ca08f7a87d65ac1ddfc8ba74e8a2e14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<!doctype html>
<meta charset=utf-8>
<title>IndexedDB: Binary keys written to a database and read back</title>
<meta name=timeout content=long>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/support.js"></script>
<script>

const sample = [0x44, 0x33, 0x22, 0x11, 0xFF, 0xEE, 0xDD, 0xCC];
const buffer = new Uint8Array(sample).buffer;

function assert_key_valid(a, message) {
  assert_equals(indexedDB.cmp(a, a), 0, message);
}

function assert_buffer_equals(a, b, message) {
  assert_array_equals(
      Array.from(new Uint8Array(a)), Array.from(new Uint8Array(b)), message);
}

// Verifies that a JavaScript value round-trips through IndexedDB as a key.
function check_key_roundtrip_and_done(t, db, key, key_buffer) {
  const tx = db.transaction('store', 'readwrite', {durability: 'relaxed'});
  const store = tx.objectStore('store');

  // Verify put with key
  const put_request = store.put('value', key);
  put_request.onerror = t.unreached_func('put should succeed');

  // Verify get with key
  const get_request = store.get(key);
  get_request.onerror = t.unreached_func('get should succeed');
  get_request.onsuccess = t.step_func(() => {
    assert_equals(
        get_request.result, 'value',
        'get should retrieve the value given to put');

    // Verify iteration returning key
    const cursor_request = store.openCursor();
    cursor_request.onerror = t.unreached_func('openCursor should succeed');
    cursor_request.onsuccess = t.step_func(() => {
      assert_not_equals(
          cursor_request.result, null, 'cursor should be present');
      const retrieved_key = cursor_request.result.key;
      assert_true(
          retrieved_key instanceof ArrayBuffer,
          'IndexedDB binary keys should be returned in ArrayBuffer instances');
      assert_key_equals(
          retrieved_key, key,
          'The key returned by IndexedDB should equal the key given to put()');
      assert_buffer_equals(
          retrieved_key, key_buffer,
          'The ArrayBuffer returned by IndexedDB should equal the buffer ' +
          'backing the key given to put()');

      t.done();
    });
  });
}

// Checks that IndexedDB handles the given view type for binary keys correctly.
function view_type_test(type) {
  indexeddb_test(
    (t, db) => { db.createObjectStore('store'); },
    (t, db) => {
      const key = new self[type](buffer);
      assert_key_valid(key, `${type} should be usable as an IndexedDB key`);
      assert_key_equals(key, buffer,
          'Binary keys with the same data but different view types should be ' +
          ' equal');
      check_key_roundtrip_and_done(t, db, key, buffer);
    },
    `Binary keys can be supplied using the view type ${type}`,
  );
}

[
  'Uint8Array',
  'Uint8ClampedArray',
  'Int8Array',
  'Uint16Array',
  'Int16Array',
  'Uint32Array',
  'Int32Array',
  'Float32Array',
  'Float64Array'
].forEach((type) => { view_type_test(type); });

// Checks that IndexedDB
function value_test(value_description, value, value_buffer) {
  indexeddb_test(
    (t, db) => { db.createObjectStore('store'); },
    (t, db) => {
      assert_key_valid(
          value, value_description + ' should be usable as an valid key');
      check_key_roundtrip_and_done(t, db, value, value_buffer);
    },
    `${value_description} can be used to supply a binary key`
  );
}

value_test('ArrayBuffer', buffer, buffer);
value_test('DataView', new DataView(buffer), buffer);
value_test('DataView with explicit offset', new DataView(buffer, 3),
           new Uint8Array([0x11, 0xFF, 0xEE, 0xDD, 0xCC]).buffer);
value_test('DataView with explicit offset and length',
           new DataView(buffer, 3, 4),
           new Uint8Array([0x11, 0xFF, 0xEE, 0xDD]).buffer);
value_test('Uint8Array with explicit offset', new Uint8Array(buffer, 3),
           new Uint8Array([0x11, 0xFF, 0xEE, 0xDD, 0xCC]).buffer);
value_test('Uint8Array with explicit offset and length',
           new Uint8Array(buffer, 3, 4),
           new Uint8Array([0x11, 0xFF, 0xEE, 0xDD]).buffer);

</script>