summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/IndexedDB/clone-before-keypath-eval.html
blob: 6ef36f5fe3e2b5b63abb9e32059aa69727124cc0 (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<!doctype html>
<meta charset=utf-8>
<title>IndexedDB: </title>
<meta name="help" href="https://w3c.github.io/IndexedDB/#dom-idbobjectstore-put">
<meta name="help" href="https://w3c.github.io/IndexedDB/#dom-idbcursor-update">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/support.js"></script>
<script>

function ProbeObject() {
  this.id_count = 0;
  this.invalid_id_count = 0;
  this.prop_count = 0;
  Object.defineProperties(this, {
    id: {
      enumerable: true,
      get() {
        ++this.id_count;
        return 1000 + this.id_count;
      },
    },
    invalid_id: {
      enumerable: true,
      get() {
        ++this.invalid_id_count;
        return {};
      },
    },
    prop: {
      enumerable: true,
      get() {
        ++this.prop_count;
        return 2000 + this.prop_count;
      },
    },
  });
}

indexeddb_test(
  (t, db) => {
    db.createObjectStore('store', {keyPath: 'id', autoIncrement: true});
  },
  (t, db) => {
    const tx = db.transaction('store', 'readwrite', {durability: 'relaxed'});
    const store = tx.objectStore('store');
    const obj = new ProbeObject();
    store.put(obj);
    assert_equals(
        obj.id_count, 1,
        'put() operation should access primary key property once');
    assert_equals(
        obj.prop_count, 1,
        'put() operation should access other properties once');
    t.done();
  }, 'Key generator and key path validity check operates on a clone');

indexeddb_test(
  (t, db) => {
    db.createObjectStore('store', {keyPath: 'invalid_id', autoIncrement: true});
  },
  (t, db) => {
    const tx = db.transaction('store', 'readwrite', {durability: 'relaxed'});
    const store = tx.objectStore('store');
    const obj = new ProbeObject();
    assert_throws_dom('DataError', () => { store.put(obj); },
                      'put() should throw if primary key cannot be injected');
    assert_equals(
        obj.invalid_id_count, 1,
        'put() operation should access primary key property once');
    assert_equals(
        obj.prop_count, 1,
        'put() operation should access other properties once');
    t.done();
  }, 'Failing key path validity check operates on a clone');

indexeddb_test(
  (t, db) => {
    const store = db.createObjectStore('store');
    store.createIndex('index', 'prop');
  },
  (t, db) => {
    const tx = db.transaction('store', 'readwrite', {durability: 'relaxed'});
    const store = tx.objectStore('store');
    const obj = new ProbeObject();
    store.put(obj, 'key');
    assert_equals(
        obj.prop_count, 1, 'put() should access index key property once');
    assert_equals(
        obj.id_count, 1,
        'put() operation should access other properties once');
    t.done();
  }, 'Index key path evaluations operate on a clone');

indexeddb_test(
  (t, db) => {
    const store = db.createObjectStore('store', {keyPath: 'id'});
    store.createIndex('index', 'prop');
  },
  (t, db) => {
    const tx = db.transaction('store', 'readwrite', {durability: 'relaxed'});
    const store = tx.objectStore('store');
    const obj = new ProbeObject();
    store.put(obj);
    assert_equals(
        obj.id_count, 1, 'put() should access primary key property once');
    assert_equals(
        obj.prop_count, 1, 'put() should access index key property once');
    t.done();
  }, 'Store and index key path evaluations operate on the same clone');

indexeddb_test(
  (t, db) => {
    const store = db.createObjectStore('store', {keyPath: 'id'});
    store.createIndex('index', 'prop');
  },
  (t, db) => {
    const tx = db.transaction('store', 'readwrite', {durability: 'relaxed'});
    const store = tx.objectStore('store');
    store.put(new ProbeObject());

    store.openCursor().onsuccess = t.step_func((event) => {
      const cursor = event.target.result;

      const obj = new ProbeObject();
      cursor.update(obj);
      assert_equals(
          obj.id_count, 1, 'put() should access primary key property once');
      assert_equals(
          obj.prop_count, 1, 'put() should access index key property once');

      t.done();
    });
  }, 'Cursor update checks and keypath evaluations operate on a clone');
</script>