| // META: global=window,worker |
| // META: title=IndexedDB: The source of requests made against cursors |
| // META: script=resources/support.js |
| |
| // Spec: https://w3c.github.io/IndexedDB/#dom-idbrequest-source |
| |
| 'use strict'; |
| |
| // Setup each test by populating an object store with an index for the cursor to |
| // iterate and manipulate. |
| function initializeDatabase(db) { |
| const store = db.createObjectStore('store', {autoIncrement: true}); |
| store.createIndex('index', /*keypath=*/ 'value'); |
| store.put({value: 'z'}); |
| store.put({value: 'y'}); |
| store.put({value: 'x'}); |
| store.put({value: 'w'}); |
| } |
| |
| function isIndex(cursorSourceType) { |
| return cursorSourceType === 'IDBIndex'; |
| } |
| |
| // Return the object store or index, depending on the test's `cursorSourceType`. |
| function getCursorSource(transaction, cursorSourceType) { |
| let cursorSource = transaction.objectStore('store'); |
| if (isIndex(cursorSourceType)) { |
| cursorSource = cursorSource.index('index'); |
| } |
| return cursorSource; |
| } |
| |
| // Verify the request source after calling delete() or update() on the cursor. |
| function cursor_request_source_test( |
| cursorSourceType, createRequestFunctionName, createRequestFunctionArgs) { |
| indexeddb_test( |
| (t, db) => initializeDatabase(db), |
| (t, db) => { |
| const tx = db.transaction('store', 'readwrite'); |
| const cursorSource = getCursorSource(tx, cursorSourceType); |
| |
| // Open the cursor. |
| const openCursorRequest = cursorSource.openCursor(); |
| openCursorRequest.onerror = |
| t.unreached_func('The cursor must not fail to open.'); |
| |
| openCursorRequest.onsuccess = t.step_func(e => { |
| // Use the cursor to create a new request. |
| const cursor = e.target.result; |
| const request = |
| cursor[createRequestFunctionName](...createRequestFunctionArgs); |
| assert_equals( |
| request.source, cursor, |
| `The request's source must be the cursor itself.`); |
| t.done(); |
| }); |
| }, |
| `The source of the request from ${cursorSourceType}::${ |
| createRequestFunctionName}() is the cursor itself`); |
| } |
| |
| // Verify the request source after calling openCursor() or openKeyCursor() and |
| // then using the cursor to iterate. |
| function open_cursor_request_source_test( |
| cursorSourceType, openCursorFunctionName) { |
| indexeddb_test( |
| (t, db) => initializeDatabase(db), |
| (t, db) => { |
| const tx = db.transaction('store', 'readonly'); |
| const cursorSource = getCursorSource(tx, cursorSourceType); |
| |
| // Open the cursor. |
| const openCursorRequest = cursorSource[openCursorFunctionName](); |
| openCursorRequest.onerror = |
| t.unreached_func('The cursor must not fail to open or iterate.'); |
| |
| assert_equals( |
| openCursorRequest.source, cursorSource, |
| 'The request source must be the opener of the cursor.'); |
| |
| // Verify the cursor's `request.source` after iterating with |
| // `advance()`, `continue()`, and `continuePrimaryKey()`. |
| let iterationCount = 0; |
| openCursorRequest.onsuccess = t.step_func(e => { |
| assert_equals( |
| openCursorRequest.source, cursorSource, |
| 'The request source must be the opener of the cursor after iterating.'); |
| |
| const cursor = e.target.result; |
| ++iterationCount; |
| |
| if (iterationCount == 1) { |
| cursor.advance(1); |
| } else if (iterationCount == 2) { |
| cursor.continue(); |
| } else if (iterationCount == 3 && isIndex(cursorSourceType)) { |
| cursor.continuePrimaryKey('z', 0); |
| } else { |
| t.done(); |
| } |
| }); |
| }, |
| `${cursorSourceType}::${ |
| openCursorFunctionName}'s request source must be the ${ |
| cursorSourceType} instance that opened the cursor`); |
| } |
| |
| open_cursor_request_source_test('IDBObjectStore', 'openCursor'); |
| open_cursor_request_source_test('IDBObjectStore', 'openKeyCursor'); |
| open_cursor_request_source_test('IDBIndex', 'openCursor'); |
| open_cursor_request_source_test('IDBIndex', 'openKeyCursor'); |
| |
| cursor_request_source_test('IDBObjectStore', 'update', /*args=*/[0]); |
| cursor_request_source_test('IDBObjectStore', 'delete', /*args=*/[]); |
| cursor_request_source_test('IDBIndex', 'update', /*args=*/[0]); |
| cursor_request_source_test('IDBIndex', 'delete', /*args=*/[]); |