1 if (this.importScripts) {
2 importScripts('../../../resources/js-test.js');
3 importScripts('shared.js');
6 description("Test that expected exceptions are thrown per IndexedDB spec.");
8 indexedDBTest(prepareDatabase, testDatabase);
9 function prepareDatabase()
11 db = event.target.result;
13 evalAndLog("store = db.createObjectStore('store')");
14 evalAndLog("index = store.createIndex('index', 'id')");
15 evalAndLog("store.put({id: 'a'}, 1)");
16 evalAndLog("store.put({id: 'b'}, 2)");
17 evalAndLog("store.put({id: 'c'}, 3)");
18 evalAndLog("store.put({id: 'd'}, 4)");
19 evalAndLog("store.put({id: 'e'}, 5)");
20 evalAndLog("store.put({id: 'f'}, 6)");
21 evalAndLog("store.put({id: 'g'}, 7)");
22 evalAndLog("store.put({id: 'h'}, 8)");
23 evalAndLog("store.put({id: 'i'}, 9)");
24 evalAndLog("store.put({id: 'j'}, 10)");
25 evalAndLog("otherStore = db.createObjectStore('otherStore')");
26 evalAndLog("inlineKeyStore = db.createObjectStore('inlineKeyStore', {keyPath: 'id'})");
28 evalAndLog("request = inlineKeyStore.put({id: 0})");
29 shouldBeEqualToString("request.readyState", "pending");
32 debug("3.2.1 The IDBRequest Interface");
35 debug("IDBRequest.error");
36 debug("When the done flag is false, getting this property must throw a DOMException of type InvalidStateError.");
37 evalAndExpectException("request.error", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
40 debug("IDBRequest.result");
41 debug("When the done flag is false, getting this property must throw a DOMException of type InvalidStateError.");
42 evalAndExpectException("request.result", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
45 debug("3.2.3 Opening a database");
48 debug("IDBFactory.cmp()");
49 debug("One of the supplied keys was not a valid key.");
50 evalAndExpectException("indexedDB.cmp(null, 0)", "0", "'DataError'");
53 function testDatabase()
55 evalAndLog("db.close()");
58 debug("3.2.4 Database");
60 request = evalAndLog("indexedDB.open(dbname, 2)");
61 request.onerror = unexpectedErrorCallback;
62 request.onblocked = unexpectedBlockedCallback;
63 request.onsuccess = checkTransactionAndObjectStoreExceptions;
64 request.onupgradeneeded = function() {
66 var trans = request.transaction;
67 trans.onabort = unexpectedAbortCallback;
70 debug("IDBDatabase.createObjectStore()");
71 debug("If an objectStore with the same name already exists, the implementation must throw a DOMException of type ConstraintError.");
72 evalAndExpectException("db.createObjectStore('store')", "0", "'ConstraintError'");
73 debug("If keyPath is not a valid key path then a DOMException of type SyntaxError must be thrown.");
74 evalAndExpectException("db.createObjectStore('fail', {keyPath: '-invalid-'})", "DOMException.SYNTAX_ERR", "'SyntaxError'");
75 debug("If the optionalParameters parameter is specified, and autoIncrement is set to true, and the keyPath parameter is specified to the empty string, or specified to an Array, this function must throw a InvalidAccessError exception.");
76 evalAndExpectException("db.createObjectStore('fail', {autoIncrement: true, keyPath: ''})", "DOMException.INVALID_ACCESS_ERR", "'InvalidAccessError'");
77 evalAndExpectException("db.createObjectStore('fail', {autoIncrement: true, keyPath: ['a']})", "DOMException.INVALID_ACCESS_ERR", "'InvalidAccessError'");
80 debug("IDBDatabase.deleteObjectStore()");
81 debug("There is no object store with the given name, compared in a case-sensitive manner, in the connected database.");
82 evalAndExpectException("db.deleteObjectStore('no-such-store')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
85 debug("IDBDatabase.transaction()");
86 debug('If this method is called on IDBDatabase object for which a "versionchange" transaction is still running, a InvalidStateError exception must be thrown.');
87 evalAndExpectException("db.transaction('store')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
91 function checkTransactionAndObjectStoreExceptions()
93 debug("One of the names provided in the storeNames argument doesn't exist in this database.");
94 evalAndExpectException("db.transaction('no-such-store')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
95 debug("The value for the mode parameter is invalid.");
96 evalAndExpectExceptionClass("db.transaction('store', 'invalid-mode')", "TypeError");
97 debug("The 'versionchange' value for the mode parameter can only be set internally during upgradeneeded.");
98 evalAndExpectExceptionClass("db.transaction('store', 'versionchange')", "TypeError");
99 debug("The function was called with an empty list of store names");
100 evalAndExpectException("db.transaction([])", "DOMException.INVALID_ACCESS_ERR", "'InvalidAccessError'");
103 debug("One more IDBDatabase.createObjectStore() test:");
104 debug('If this function is called from outside a "versionchange" transaction callback ... the implementation must throw a DOMException of type InvalidStateError.');
105 evalAndExpectException("db.createObjectStore('fail')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
108 debug("One more IDBDatabase.deleteObjectStore() test:");
109 debug('If this function is called from outside a "versionchange" transaction callback ... the implementation must throw a DOMException of type InvalidStateError.');
110 evalAndExpectException("db.deleteObjectStore('fail')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
112 prepareStoreAndIndex();
115 function prepareStoreAndIndex()
118 debug("Prepare an object store and index from an inactive transaction for later use.");
119 evalAndLog("finishedTransaction = inactiveTransaction = db.transaction('store')");
120 inactiveTransaction.onabort = unexpectedAbortCallback;
121 evalAndLog("storeFromInactiveTransaction = inactiveTransaction.objectStore('store')");
122 evalAndLog("indexFromInactiveTransaction = storeFromInactiveTransaction.index('index')");
123 evalAndLog("request = storeFromInactiveTransaction.openCursor()");
124 request.onerror = unexpectedErrorCallback;
125 request.onsuccess = function() {
126 evalAndLog("cursorFromInactiveTransaction = request.result");
128 inactiveTransaction.oncomplete = testObjectStore;
131 function testObjectStore()
134 debug("3.2.5 Object Store");
135 evalAndLog("ro_transaction = db.transaction('store', 'readonly')");
136 evalAndLog("storeFromReadOnlyTransaction = ro_transaction.objectStore('store')");
137 evalAndLog("rw_transaction = db.transaction('store', 'readwrite')");
138 evalAndLog("store = rw_transaction.objectStore('store')");
141 debug("IDBObjectStore.add()");
142 debug('This method throws a DOMException of type ReadOnlyError if the transaction which this IDBObjectStore belongs to is has its mode set to "readonly".');
143 evalAndExpectException("storeFromReadOnlyTransaction.add(0, 0)", "0", "'ReadOnlyError'");
144 // "If any of the following conditions are true, this method throws a DOMException of type DataError:" - covered in objectstore-basics.html
145 debug("The transaction this IDBObjectStore belongs to is not active.");
146 evalAndExpectException("storeFromInactiveTransaction.add(0, 0)", "0", "'TransactionInactiveError'");
147 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
148 debug("The data being stored could not be cloned by the internal structured cloning algorithm.");
149 evalAndExpectException("store.add(self, 0)", "DOMException.DATA_CLONE_ERR"); // FIXME: Test 'DataCloneError' name when DOM4 exceptions are used in binding.
152 debug("IDBObjectStore.clear()");
153 debug('This method throws a DOMException of type ReadOnlyError if the transaction which this IDBObjectStore belongs to is has its mode set to "readonly".');
154 evalAndExpectException("storeFromReadOnlyTransaction.clear()", "0", "'ReadOnlyError'");
155 debug("The transaction this IDBObjectStore belongs to is not active.");
156 evalAndExpectException("storeFromInactiveTransaction.clear()", "0", "'TransactionInactiveError'");
157 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
160 debug("IDBObjectStore.count()");
161 debug("If the optional key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.");
162 evalAndExpectException("store.count({})", "0", "'DataError'");
163 debug("The transaction this IDBObjectStore belongs to is not active.");
164 evalAndExpectException("storeFromInactiveTransaction.count()", "0", "'TransactionInactiveError'");
165 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
168 debug("IDBObjectStore.delete()");
169 debug('This method throws a DOMException of type ReadOnlyError if the transaction which this IDBObjectStore belongs to is has its mode set to "readonly".');
170 evalAndExpectException("storeFromReadOnlyTransaction.delete(0)", "0", "'ReadOnlyError'");
171 debug("If the key parameter is not a valid key or a key range this method throws a DOMException of type DataError.");
172 evalAndExpectException("store.delete({})", "0", "'DataError'");
173 debug("The transaction this IDBObjectStore belongs to is not active.");
174 evalAndExpectException("storeFromInactiveTransaction.add(0, 0)", "0", "'TransactionInactiveError'");
175 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
178 debug("IDBObjectStore.get()");
179 debug("If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.");
180 evalAndExpectException("store.get({})", "0", "'DataError'");
181 debug("The transaction this IDBObjectStore belongs to is not active.");
182 evalAndExpectException("storeFromInactiveTransaction.get(0)", "0", "'TransactionInactiveError'");
183 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
186 debug("IDBObjectStore.getAll()");
187 debug("If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.");
188 evalAndExpectException("store.getAll({})", "0", "'DataError'");
189 debug("The transaction this IDBObjectStore belongs to is not active.");
190 evalAndExpectException("storeFromInactiveTransaction.getAll(0)", "0", "'TransactionInactiveError'");
191 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
194 debug("IDBObjectStore.getAllKeys()");
195 debug("If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.");
196 evalAndExpectException("store.getAllKeys({})", "0", "'DataError'");
197 debug("The transaction this IDBObjectStore belongs to is not active.");
198 evalAndExpectException("storeFromInactiveTransaction.getAllKeys(0)", "0", "'TransactionInactiveError'");
199 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
202 debug("IDBObjectStore.index()");
203 debug("There is no index with the given name, compared in a case-sensitive manner, in the connected database.");
204 evalAndExpectException("store.index('no-such-index')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
205 debug("Occurs if a request is made on a source object that has been deleted or removed, or if the transaction the object store belongs to has finished.");
206 evalAndExpectException("storeFromInactiveTransaction.index('index')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
207 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
210 debug("IDBObjectStore.openCursor()");
211 debug("If the range parameter is specified but is not a valid key or a key range, this method throws a DOMException of type DataError.");
212 evalAndExpectException("store.openCursor({})", "0", "'DataError'");
213 debug("The transaction this IDBObjectStore belongs to is not active.");
214 evalAndExpectException("storeFromInactiveTransaction.openCursor()", "0", "'TransactionInactiveError'");
215 debug("The value for the direction parameter is invalid.");
216 evalAndExpectExceptionClass("store.openCursor(0, 'invalid-direction')", "TypeError");
217 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
220 debug("IDBObjectStore.openKeyCursor()");
221 debug("If the range parameter is specified but is not a valid key or a key range, this method throws a DOMException of type DataError.");
222 evalAndExpectException("store.openKeyCursor({})", "0", "'DataError'");
223 debug("The transaction this IDBObjectStore belongs to is not active.");
224 evalAndExpectException("storeFromInactiveTransaction.openKeyCursor()", "0", "'TransactionInactiveError'");
225 debug("The value for the direction parameter is invalid.");
226 evalAndExpectExceptionClass("store.openKeyCursor(0, 'invalid-direction')", "TypeError");
227 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
230 debug("IDBObjectStore.put()");
231 debug('This method throws a DOMException of type ReadOnlyError if the transaction which this IDBObjectStore belongs to is has its mode set to "readonly".');
232 evalAndExpectException("storeFromReadOnlyTransaction.put(0, 0)", "0", "'ReadOnlyError'");
233 // "If any of the following conditions are true, this method throws a DOMException of type DataError:" - covered in objectstore-basics.html
234 debug("The transaction this IDBObjectStore belongs to is not active.");
235 evalAndExpectException("storeFromInactiveTransaction.put(0, 0)", "0", "'TransactionInactiveError'");
236 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
237 debug("The data being stored could not be cloned by the internal structured cloning algorithm.");
238 evalAndExpectException("store.put(self, 0)", "DOMException.DATA_CLONE_ERR"); // FIXME: Test 'DataCloneError' name when DOM4 exceptions are used in binding.
240 evalAndLog("db.close()");
241 evalAndLog("ro_transaction.oncomplete = transactionComplete");
242 evalAndLog("rw_transaction.oncomplete = transactionComplete");
245 var numCompleted = 0;
246 function transactionComplete(evt)
250 if (numCompleted == 1) {
251 debug("First transaction completed");
254 evalAndLog("request = indexedDB.open(dbname, 3)");
255 request.onerror = unexpectedErrorCallback;
256 request.onblocked = unexpectedBlockedCallback;
257 evalAndLog("request.onupgradeneeded = onUpgradeNeeded3");
260 function onUpgradeNeeded3()
263 var trans = request.transaction;
264 trans.onabort = unexpectedAbortCallback;
265 trans.oncomplete = testOutsideVersionChangeTransaction;
266 store = trans.objectStore('store');
269 debug("IDBObjectStore.createIndex()");
270 debug("If an index with the same name already exists, the implementation must throw a DOMException of type ConstraintError. ");
271 evalAndExpectException("store.createIndex('index', 'keyPath')", "0", "'ConstraintError'");
272 debug("If keyPath is not a valid key path then a DOMException of type SyntaxError must be thrown.");
273 evalAndExpectException("store.createIndex('fail', '-invalid-')", "DOMException.SYNTAX_ERR", "'SyntaxError'");
274 debug("If keyPath is an Array and the multiEntry property in the optionalParameters is true, then a DOMException of type InvalidAccessError must be thrown.");
275 evalAndExpectException("store.createIndex('fail', ['a'], {multiEntry: true})", "DOMException.INVALID_ACCESS_ERR", "'InvalidAccessError'");
276 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
279 debug("IDBObjectStore.deleteIndex()");
280 debug("There is no index with the given name, compared in a case-sensitive manner, in the connected database.");
281 evalAndExpectException("store.deleteIndex('no-such-index')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
284 function testOutsideVersionChangeTransaction() {
286 debug("One more IDBObjectStore.createIndex() test:");
287 debug('If this function is called from outside a "versionchange" transaction callback ... the implementation must throw a DOMException of type InvalidStateError.');
288 evalAndExpectException("db.transaction('store').objectStore('store').createIndex('fail', 'keyPath')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
291 debug("One more IDBObjectStore.deleteIndex() test:");
292 debug('If this function is called from outside a "versionchange" transaction callback ... the implementation must throw a DOMException of type InvalidStateError.');
293 evalAndExpectException("db.transaction('store').objectStore('store').deleteIndex('fail', 'keyPath')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
300 debug("3.2.6 Index");
301 evalAndLog("indexFromReadOnlyTransaction = db.transaction('store', 'readonly').objectStore('store').index('index')");
302 evalAndLog("index = db.transaction('store', 'readwrite').objectStore('store').index('index')");
305 debug("IDBIndex.count()");
306 debug("If the optional key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.");
307 evalAndExpectException("index.count({})", "0", "'DataError'");
308 debug("The transaction this IDBIndex belongs to is not active.");
309 evalAndExpectException("indexFromInactiveTransaction.count()", "0", "'TransactionInactiveError'");
310 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
313 debug("IDBIndex.get()");
314 debug("If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.");
315 evalAndExpectException("index.get({})", "0", "'DataError'");
316 debug("The transaction this IDBIndex belongs to is not active.");
317 evalAndExpectException("indexFromInactiveTransaction.get(0)", "0", "'TransactionInactiveError'");
318 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
321 debug("IDBIndex.getAll()");
322 debug("If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.");
323 evalAndExpectException("index.getAll({})", "0", "'DataError'");
324 debug("The transaction this IDBIndex belongs to is not active.");
325 evalAndExpectException("indexFromInactiveTransaction.getAll(0)", "0", "'TransactionInactiveError'");
326 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
329 debug("IDBIndex.getKey()");
330 debug("If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.");
331 evalAndExpectException("index.getKey({})", "0", "'DataError'");
332 debug("The transaction this IDBIndex belongs to is not active.");
333 evalAndExpectException("indexFromInactiveTransaction.getKey(0)", "0", "'TransactionInactiveError'");
334 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
337 debug("IDBIndex.getAllKeys()");
338 debug("If the key parameter is not a valid key or a key range, this method throws a DOMException of type DataError.");
339 evalAndExpectException("index.getAllKeys({})", "0", "'DataError'");
340 debug("The transaction this IDBIndex belongs to is not active.");
341 evalAndExpectException("indexFromInactiveTransaction.getAllKeys(0)", "0", "'TransactionInactiveError'");
342 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
345 debug("IDBIndex.openCursor()");
346 debug("If the range parameter is specified but is not a valid key or a key range, this method throws a DOMException of type DataError.");
347 evalAndExpectException("index.openCursor({})", "0", "'DataError'");
348 debug("The transaction this IDBIndex belongs to is not active.");
349 evalAndExpectException("indexFromInactiveTransaction.openCursor()", "0", "'TransactionInactiveError'");
350 debug("The value for the direction parameter is invalid.");
351 evalAndExpectExceptionClass("index.openCursor(0, 'invalid-direction')", "TypeError");
352 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
355 debug("IDBIndex.openKeyCursor()");
356 debug("If the range parameter is specified but is not a valid key or a key range, this method throws a DOMException of type DataError.");
357 evalAndExpectException("index.openKeyCursor({})", "0", "'DataError'");
358 debug("The transaction this IDBIndex belongs to is not active.");
359 evalAndExpectException("indexFromInactiveTransaction.openKeyCursor()", "0", "'TransactionInactiveError'");
360 debug("The value for the direction parameter is invalid.");
361 evalAndExpectExceptionClass("index.openKeyCursor(0, 'invalid-direction')", "TypeError");
362 // "Occurs if a request is made on a source object that has been deleted or removed." - covered in deleted-objects.html
367 function testCursor()
370 debug("3.2.7 Cursor");
371 evalAndLog("transaction = db.transaction(['store', 'inlineKeyStore'], 'readwrite')");
375 function makeCursor() {
376 evalAndLog("request = transaction.objectStore('store').openCursor()");
377 primaryCursorRequest = request;
378 request.onerror = unexpectedErrorCallback;
379 request.onsuccess = function() {
380 evalAndLog("cursor = request.result");
381 request.onsuccess = null;
386 function makeKeyCursor() {
387 evalAndLog("request = transaction.objectStore('store').index('index').openKeyCursor()");
388 request.onerror = unexpectedErrorCallback;
389 request.onsuccess = function() {
390 evalAndLog("keyCursor = request.result");
391 request.onsuccess = null;
396 function makeReverseCursor() {
397 evalAndLog("request = transaction.objectStore('store').openCursor(IDBKeyRange.lowerBound(-Infinity), 'prev')");
398 request.onerror = unexpectedErrorCallback;
399 request.onsuccess = function() {
400 evalAndLog("reverseCursor = request.result");
401 request.onsuccess = null;
406 function makeInlineCursor() {
407 evalAndLog("request = transaction.objectStore('inlineKeyStore').openCursor()");
408 request.onerror = unexpectedErrorCallback;
409 request.onsuccess = function() {
410 evalAndLog("inlineCursor = request.result");
411 request.onsuccess = null;
416 function testCursorAdvance() {
418 debug("IDBCursor.advance()");
419 debug("Calling this method more than once before new cursor data has been loaded is not allowed and results in a DOMException of type InvalidStateError being thrown.");
420 debug("If the value for count is 0 (zero) or a negative number, this method must throw a JavaScript TypeError exception.");
421 evalAndExpectExceptionClass("cursor.advance(0)", "TypeError");
422 evalAndLog("cursor.advance(1)");
423 evalAndExpectException("cursor.advance(1)", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
424 debug("The transaction this IDBCursor belongs to is not active.");
425 evalAndExpectException("cursorFromInactiveTransaction.advance(1)", "0", "'TransactionInactiveError'");
426 primaryCursorRequest.onsuccess = testCursorContinue;
429 function testCursorContinue() {
431 debug("IDBCursor.continue()");
432 debug("The parameter is not a valid key.");
433 evalAndExpectException("cursor.continue({})", "0", "'DataError'");
434 debug("The parameter is less than or equal to this cursor's position and this cursor's direction is \"next\" or \"nextunique\".");
435 evalAndExpectException("cursor.continue(-Infinity)", "0", "'DataError'");
436 debug("The parameter is greater than or equal to this cursor's position and this cursor's direction is \"prev\" or \"prevunique\".");
437 evalAndExpectException("reverseCursor.continue(100)", "0", "'DataError'");
438 debug("Calling this method more than once before new cursor data has been loaded is not allowed and results in a DOMException of type InvalidStateError being thrown.");
439 evalAndLog("cursor.continue()");
440 evalAndExpectException("cursor.continue()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
441 debug("The transaction this IDBCursor belongs to is not active.");
442 evalAndExpectException("cursorFromInactiveTransaction.continue()", "0", "'TransactionInactiveError'");
446 function testCursorDelete() {
448 debug("IDBCursor.delete()");
449 debug("If this cursor's got value flag is false, or if this cursor was created using openKeyCursor a DOMException of type InvalidStateError is thrown.");
450 evalAndExpectException("keyCursor.delete()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
451 debug("The transaction this IDBCursor belongs to is not active.");
452 evalAndExpectException("cursorFromInactiveTransaction.delete()", "0", "'TransactionInactiveError'");
453 primaryCursorRequest.onsuccess = testCursorUpdate;
456 function testCursorUpdate() {
458 debug("IDBCursor.update()");
459 debug("If this cursor's got value flag is false or if this cursor was created using openKeyCursor. This method throws a DOMException of type InvalidStateError.");
460 evalAndExpectException("keyCursor.update({})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
461 debug("If the effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key, this method throws a DOMException of type DataError.");
462 evalAndExpectException("inlineCursor.update({id: 1})", "0", "'DataError'");
463 debug("If the structured clone algorithm throws an exception, that exception is rethrown.");
464 evalAndExpectException("cursor.update(self)", "DOMException.DATA_CLONE_ERR"); // FIXME: Test 'DataCloneError' name when DOM4 exceptions are used in binding.
465 debug("The transaction this IDBCursor belongs to is not active.");
466 evalAndExpectException("cursorFromInactiveTransaction.update({})", "0", "'TransactionInactiveError'");
468 primaryCursorRequest.onsuccess = null;
469 makeReadOnlyCursor();
472 // Can't have both transactions running at once, so these tests must be separated out.
473 function makeReadOnlyCursor() {
474 evalAndLog("readOnlyTransaction = db.transaction('store', 'readonly')");
475 evalAndLog("request = readOnlyTransaction.objectStore('store').openCursor()");
476 request.onerror = unexpectedErrorCallback;
477 request.onsuccess = function() {
478 evalAndLog("cursorFromReadOnlyTransaction = request.result");
479 doReadOnlyCursorTests();
483 function doReadOnlyCursorTests() {
485 debug("One more IDBCursor.delete() test:");
486 debug('This method throws a DOMException of type ReadOnlyError if the transaction which this IDBCursor belongs to has its mode set to "readonly".');
487 evalAndExpectException("cursorFromReadOnlyTransaction.delete()", "0", "'ReadOnlyError'");
490 debug("One more IDBCursor.update() test:");
491 debug('This method throws a DOMException of type ReadOnlyError if the transaction which this IDBCursor belongs to has its mode set to "readonly".');
492 evalAndExpectException("cursorFromReadOnlyTransaction.update({})", "0", "'ReadOnlyError'");
498 function testTransaction()
501 debug("3.2.8 Transaction");
504 debug("IDBTransaction.abort()");
505 debug("If this transaction is finished, throw a DOMException of type InvalidStateError. ");
506 evalAndExpectException("finishedTransaction.abort()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
507 debug("If the requested object store is not in this transaction's scope.");
508 evalAndExpectException("db.transaction('store').objectStore('otherStore')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");