idbcursor-continuePrimaryKey-exception-order.any.js (10532B)
1 // META: global=window,worker 2 // META: title=IDBCursor.continuePrimaryKey() - Exception Orders 3 // META: script=resources/support.js 4 // META: timeout=long 5 6 // Spec: http://w3c.github.io/IndexedDB/#dom-idbcursor-continueprimarykey 7 8 'use strict'; 9 10 function setup_test_store(db) { 11 const records = [ 12 {iKey: 'A', pKey: 1}, {iKey: 'A', pKey: 2}, {iKey: 'A', pKey: 3}, 13 {iKey: 'A', pKey: 4}, {iKey: 'B', pKey: 5}, {iKey: 'B', pKey: 6}, 14 {iKey: 'B', pKey: 7}, {iKey: 'C', pKey: 8}, {iKey: 'C', pKey: 9}, 15 {iKey: 'D', pKey: 10} 16 ]; 17 18 const store = db.createObjectStore('test', {keyPath: 'pKey'}); 19 store.createIndex('idx', 'iKey'); 20 21 for (let i = 0; i < records.length; i++) { 22 store.add(records[i]); 23 } 24 25 return store; 26 } 27 28 indexeddb_test(function(t, db, txn) { 29 const store = setup_test_store(db); 30 const cursor_rq = store.index('idx').openCursor(); 31 let cursor; 32 33 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 34 cursor_rq.onsuccess = t.step_func((e) => { 35 cursor = e.target.result; 36 assert_true(!!cursor, 'acquire cursor'); 37 38 store.deleteIndex('idx'); 39 }); 40 txn.oncomplete = t.step_func(() => { 41 assert_throws_dom('TransactionInactiveError', () => { 42 cursor.continuePrimaryKey('A', 4); 43 }, 'transaction-state check should precede deletion check'); 44 t.done(); 45 }); 46 }, null, 'TransactionInactiveError v.s. InvalidStateError(deleted index)'); 47 48 indexeddb_test( 49 function(t, db, txn) { 50 const store = setup_test_store(db); 51 const cursor_rq = store.openCursor(); 52 let cursor; 53 54 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 55 cursor_rq.onsuccess = t.step_func((e) => { 56 cursor = e.target.result; 57 assert_true(!!cursor, 'acquire cursor'); 58 59 db.deleteObjectStore('test'); 60 61 assert_throws_dom('InvalidStateError', () => { 62 cursor.continuePrimaryKey('A', 4); 63 }, 'deletion check should precede index source check'); 64 t.done(); 65 }); 66 }, 67 null, 68 'InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect source)'); 69 70 indexeddb_test( 71 function(t, db, txn) { 72 const store = setup_test_store(db); 73 const cursor_rq = store.index('idx').openCursor(null, 'nextunique'); 74 let cursor; 75 76 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 77 cursor_rq.onsuccess = t.step_func((e) => { 78 cursor = e.target.result; 79 assert_true(!!cursor, 'acquire cursor'); 80 81 store.deleteIndex('idx'); 82 83 assert_throws_dom('InvalidStateError', () => { 84 cursor.continuePrimaryKey('A', 4); 85 }, 'deletion check should precede cursor direction check'); 86 t.done(); 87 }); 88 }, 89 null, 90 'InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect direction)'); 91 92 indexeddb_test( 93 function(t, db, txn) { 94 const store = db.createObjectStore('test', {keyPath: 'pKey'}); 95 96 store.add({iKey: 'A', pKey: 1}); 97 98 const cursor_rq = 99 store.createIndex('idx', 'iKey').openCursor(null, 'nextunique'); 100 let cursor; 101 102 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 103 cursor_rq.onsuccess = t.step_func((e) => { 104 if (e.target.result) { 105 cursor = e.target.result; 106 cursor.continue(); 107 return; 108 } 109 110 assert_throws_dom('InvalidAccessError', () => { 111 cursor.continuePrimaryKey('A', 4); 112 }, 'direction check should precede got_value_flag check'); 113 t.done(); 114 }); 115 }, 116 null, 117 'InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration complete)'); 118 119 indexeddb_test( 120 function(t, db, txn) { 121 const store = db.createObjectStore('test', {keyPath: 'pKey'}); 122 123 store.add({iKey: 'A', pKey: 1}); 124 125 const cursor_rq = 126 store.createIndex('idx', 'iKey').openCursor(null, 'nextunique'); 127 let cursor; 128 129 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 130 cursor_rq.onsuccess = t.step_func((e) => { 131 if (!cursor) { 132 cursor = e.target.result; 133 assert_true(!!cursor, 'acquire cursor'); 134 135 cursor.continue(); 136 137 assert_throws_dom('InvalidAccessError', () => { 138 cursor.continuePrimaryKey('A', 4); 139 }, 'direction check should precede iteration ongoing check'); 140 t.done(); 141 } 142 }); 143 }, 144 null, 145 'InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration ongoing)'); 146 147 indexeddb_test( 148 function(t, db, txn) { 149 const store = setup_test_store(db); 150 const cursor_rq = store.openCursor(); 151 let cursor; 152 153 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 154 cursor_rq.onsuccess = t.step_func((e) => { 155 if (!cursor) { 156 cursor = e.target.result; 157 assert_true(!!cursor, 'acquire cursor'); 158 159 cursor.continue(); 160 161 assert_throws_dom('InvalidAccessError', () => { 162 cursor.continuePrimaryKey('A', 4); 163 }, 'index source check should precede iteration ongoing check'); 164 t.done(); 165 } 166 }); 167 }, 168 null, 169 'InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration ongoing)'); 170 171 indexeddb_test( 172 function(t, db, txn) { 173 const store = db.createObjectStore('test', {keyPath: 'pKey'}); 174 175 store.add({iKey: 'A', pKey: 1}); 176 177 const cursor_rq = store.openCursor(); 178 let cursor; 179 180 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 181 cursor_rq.onsuccess = t.step_func((e) => { 182 if (e.target.result) { 183 cursor = e.target.result; 184 cursor.continue(); 185 return; 186 } 187 188 assert_throws_dom('InvalidAccessError', () => { 189 cursor.continuePrimaryKey('A', 4); 190 }, 'index source check should precede got_value_flag check'); 191 t.done(); 192 }); 193 }, 194 null, 195 'InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration complete)'); 196 197 indexeddb_test(function(t, db, txn) { 198 const store = setup_test_store(db); 199 const cursor_rq = store.index('idx').openCursor(); 200 let cursor; 201 202 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 203 cursor_rq.onsuccess = t.step_func((e) => { 204 if (!cursor) { 205 cursor = e.target.result; 206 assert_true(!!cursor, 'acquire cursor'); 207 208 cursor.continue(); 209 210 assert_throws_dom('InvalidStateError', () => { 211 cursor.continuePrimaryKey(null, 4); 212 }, 'iteration ongoing check should precede unset key check'); 213 t.done(); 214 } 215 }); 216 }, null, 'InvalidStateError(iteration ongoing) v.s. DataError(unset key)'); 217 218 indexeddb_test(function(t, db, txn) { 219 const store = db.createObjectStore('test', {keyPath: 'pKey'}); 220 221 store.add({iKey: 'A', pKey: 1}); 222 223 const cursor_rq = store.createIndex('idx', 'iKey').openCursor(); 224 let cursor; 225 226 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 227 cursor_rq.onsuccess = t.step_func((e) => { 228 if (e.target.result) { 229 cursor = e.target.result; 230 cursor.continue(); 231 return; 232 } 233 234 assert_throws_dom('InvalidStateError', () => { 235 cursor.continuePrimaryKey(null, 4); 236 }, 'got_value_flag check should precede unset key check'); 237 t.done(); 238 }); 239 }, null, 'InvalidStateError(iteration complete) v.s. DataError(unset key)'); 240 241 indexeddb_test(function(t, db, txn) { 242 const store = setup_test_store(db); 243 const cursor_rq = store.index('idx').openCursor(); 244 let cursor; 245 246 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 247 cursor_rq.onsuccess = t.step_func((e) => { 248 cursor = e.target.result; 249 assert_true(!!cursor, 'acquire cursor'); 250 251 assert_throws_dom('DataError', () => { 252 cursor.continuePrimaryKey(null, 4); 253 }, 'DataError is expected if key is unset.'); 254 t.done(); 255 }); 256 }, null, 'DataError(unset key)'); 257 258 indexeddb_test(function(t, db, txn) { 259 const store = setup_test_store(db); 260 const cursor_rq = store.index('idx').openCursor(); 261 let cursor; 262 263 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 264 cursor_rq.onsuccess = t.step_func((e) => { 265 cursor = e.target.result; 266 assert_true(!!cursor, 'acquire cursor'); 267 268 assert_throws_dom('DataError', () => { 269 cursor.continuePrimaryKey('A', null); 270 }, 'DataError is expected if primary key is unset.'); 271 t.done(); 272 }); 273 }, null, 'DataError(unset primary key)'); 274 275 indexeddb_test(function(t, db, txn) { 276 const store = setup_test_store(db); 277 const cursor_rq = store.index('idx').openCursor(IDBKeyRange.lowerBound('B')); 278 let cursor; 279 280 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 281 cursor_rq.onsuccess = t.step_func((e) => { 282 cursor = e.target.result; 283 assert_true(!!cursor, 'acquire cursor'); 284 285 assert_equals(cursor.key, 'B', 'expected key'); 286 assert_equals(cursor.primaryKey, 5, 'expected primary key'); 287 288 assert_throws_dom('DataError', () => { 289 cursor.continuePrimaryKey('A', 6); 290 }, 'DataError is expected if key is lower then current one.'); 291 292 assert_throws_dom('DataError', () => { 293 cursor.continuePrimaryKey('B', 5); 294 }, 'DataError is expected if primary key is equal to current one.'); 295 296 assert_throws_dom('DataError', () => { 297 cursor.continuePrimaryKey('B', 4); 298 }, 'DataError is expected if primary key is lower than current one.'); 299 300 t.done(); 301 }); 302 }, null, 'DataError(keys are lower then current one) in \'next\' direction'); 303 304 indexeddb_test(function(t, db, txn) { 305 const store = setup_test_store(db); 306 const cursor_rq = 307 store.index('idx').openCursor(IDBKeyRange.upperBound('B'), 'prev'); 308 let cursor; 309 310 cursor_rq.onerror = t.unreached_func('openCursor should succeed'); 311 cursor_rq.onsuccess = t.step_func(function(e) { 312 cursor = e.target.result; 313 assert_true(!!cursor, 'acquire cursor'); 314 315 assert_equals(cursor.key, 'B', 'expected key'); 316 assert_equals(cursor.primaryKey, 7, 'expected primary key'); 317 318 assert_throws_dom('DataError', () => { 319 cursor.continuePrimaryKey('C', 6); 320 }, 'DataError is expected if key is larger then current one.'); 321 322 assert_throws_dom('DataError', () => { 323 cursor.continuePrimaryKey('B', 7); 324 }, 'DataError is expected if primary key is equal to current one.'); 325 326 assert_throws_dom('DataError', () => { 327 cursor.continuePrimaryKey('B', 8); 328 }, 'DataError is expected if primary key is larger than current one.'); 329 330 t.done(); 331 }); 332 }, null, 'DataError(keys are larger then current one) in \'prev\' direction');