diff options
Diffstat (limited to 'testing/web-platform/tests/IndexedDB/idbobjectstore-rename-store.html')
-rw-r--r-- | testing/web-platform/tests/IndexedDB/idbobjectstore-rename-store.html | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/testing/web-platform/tests/IndexedDB/idbobjectstore-rename-store.html b/testing/web-platform/tests/IndexedDB/idbobjectstore-rename-store.html new file mode 100644 index 0000000000..649f9faef3 --- /dev/null +++ b/testing/web-platform/tests/IndexedDB/idbobjectstore-rename-store.html @@ -0,0 +1,369 @@ +<!doctype html> +<meta charset="utf8"> +<meta name="timeout" content="long"> +<title>IndexedDB: object store renaming support</title> +<link rel="help" + href="https://w3c.github.io/IndexedDB/#dom-idbobjectstore-name"> +<link rel="author" href="pwnall@chromium.org" title="Victor Costan"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/support-promises.js"></script> +<script> +'use strict'; + +// Renames the 'books' store to 'renamed_books'. +// +// Returns a promise that resolves to an IndexedDB database. The caller must +// close the database. +const renameBooksStore = (testCase) => { + return migrateDatabase(testCase, 2, (database, transaction) => { + const store = transaction.objectStore('books'); + store.name = 'renamed_books'; + }); +}; + +promise_test(testCase => { + let bookStore = null, bookStore2 = null; + let renamedBookStore = null, renamedBookStore2 = null; + return createDatabase(testCase, (database, transaction) => { + bookStore = createBooksStore(testCase, database); + }).then(database => { + assert_array_equals( + database.objectStoreNames, ['books'], + 'Test setup should have created a "books" object store'); + const transaction = database.transaction('books', 'readonly', {durability: 'relaxed'}); + bookStore2 = transaction.objectStore('books'); + return checkStoreContents( + testCase, bookStore2, + 'The store should have the expected contents before any renaming'). + then(() => database.close()); + }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { + renamedBookStore = transaction.objectStore('books'); + renamedBookStore.name = 'renamed_books'; + + assert_equals( + renamedBookStore.name, 'renamed_books', + 'IDBObjectStore name should change immediately after a rename'); + assert_array_equals( + database.objectStoreNames, ['renamed_books'], + 'IDBDatabase.objectStoreNames should immediately reflect the ' + + 'rename'); + assert_array_equals( + transaction.objectStoreNames, ['renamed_books'], + 'IDBTransaction.objectStoreNames should immediately reflect the ' + + 'rename'); + assert_equals( + transaction.objectStore('renamed_books'), renamedBookStore, + 'IDBTransaction.objectStore should return the renamed object ' + + 'store when queried using the new name immediately after the ' + + 'rename'); + assert_throws_dom( + 'NotFoundError', () => transaction.objectStore('books'), + 'IDBTransaction.objectStore should throw when queried using the ' + + "renamed object store's old name immediately after the rename"); + })).then(database => { + assert_array_equals( + database.objectStoreNames, ['renamed_books'], + 'IDBDatabase.objectStoreNames should still reflect the rename ' + + 'after the versionchange transaction commits'); + const transaction = database.transaction('renamed_books', 'readonly', {durability: 'relaxed'}); + renamedBookStore2 = transaction.objectStore('renamed_books'); + return checkStoreContents( + testCase, renamedBookStore2, + 'Renaming an object store should not change its records').then( + () => database.close()); + }).then(() => { + assert_equals( + bookStore.name, 'books', + 'IDBObjectStore obtained before the rename transaction should ' + + 'not reflect the rename'); + assert_equals( + bookStore2.name, 'books', + 'IDBObjectStore obtained before the rename transaction should ' + + 'not reflect the rename'); + assert_equals( + renamedBookStore.name, 'renamed_books', + 'IDBObjectStore used in the rename transaction should keep ' + + 'reflecting the new name after the transaction is committed'); + assert_equals( + renamedBookStore2.name, 'renamed_books', + 'IDBObjectStore obtained after the rename transaction should ' + + 'reflect the new name'); + }); +}, 'IndexedDB object store rename in new transaction'); + +promise_test(testCase => { + let renamedBookStore = null, renamedBookStore2 = null; + return createDatabase(testCase, (database, transaction) => { + renamedBookStore = createBooksStore(testCase, database); + renamedBookStore.name = 'renamed_books'; + + assert_equals( + renamedBookStore.name, 'renamed_books', + 'IDBObjectStore name should change immediately after a rename'); + assert_array_equals( + database.objectStoreNames, ['renamed_books'], + 'IDBDatabase.objectStoreNames should immediately reflect the ' + + 'rename'); + assert_array_equals( + transaction.objectStoreNames, ['renamed_books'], + 'IDBTransaction.objectStoreNames should immediately reflect the ' + + 'rename'); + assert_equals( + transaction.objectStore('renamed_books'), renamedBookStore, + 'IDBTransaction.objectStore should return the renamed object ' + + 'store when queried using the new name immediately after the ' + + 'rename'); + assert_throws_dom( + 'NotFoundError', () => transaction.objectStore('books'), + 'IDBTransaction.objectStore should throw when queried using the ' + + "renamed object store's old name immediately after the rename"); + }).then(database => { + assert_array_equals( + database.objectStoreNames, ['renamed_books'], + 'IDBDatabase.objectStoreNames should still reflect the rename ' + + 'after the versionchange transaction commits'); + const transaction = database.transaction('renamed_books', 'readonly', {durability: 'relaxed'}); + renamedBookStore2 = transaction.objectStore('renamed_books'); + return checkStoreContents( + testCase, renamedBookStore2, + 'Renaming an object store should not change its records').then( + () => database.close()); + }).then(() => { + assert_equals( + renamedBookStore.name, 'renamed_books', + 'IDBObjectStore used in the rename transaction should keep ' + + 'reflecting the new name after the transaction is committed'); + assert_equals( + renamedBookStore2.name, 'renamed_books', + 'IDBObjectStore obtained after the rename transaction should ' + + 'reflect the new name'); + }); +}, 'IndexedDB object store rename in the transaction where it is created'); + +promise_test(testCase => { + return createDatabase(testCase, (database, transaction) => { + createBooksStore(testCase, database); + }).then(database => { + const transaction = database.transaction('books', 'readonly', {durability: 'relaxed'}); + const store = transaction.objectStore('books'); + return checkStoreIndexes( + testCase, store, + 'The object store index should have the expected contens before ' + + 'any renaming').then( + () => database.close()); + }).then(() => renameBooksStore(testCase) + ).then(database => { + const transaction = database.transaction('renamed_books', 'readonly', {durability: 'relaxed'}); + const store = transaction.objectStore('renamed_books'); + return checkStoreIndexes( + testCase, store, + 'Renaming an object store should not change its indexes').then( + () => database.close()); + }); +}, 'IndexedDB object store rename covers index'); + +promise_test(testCase => { + return createDatabase(testCase, (database, transaction) => { + createBooksStore(testCase, database); + }).then(database => { + const transaction = database.transaction('books', 'readwrite', {durability: 'relaxed'}); + const store = transaction.objectStore('books'); + return checkStoreGenerator( + testCase, store, 345679, + 'The object store key generator should have the expected state ' + + 'before any renaming').then(() => database.close()); + }).then(() => renameBooksStore(testCase) + ).then(database => { + const transaction = database.transaction('renamed_books', 'readwrite', {durability: 'relaxed'}); + const store = transaction.objectStore('renamed_books'); + return checkStoreGenerator( + testCase, store, 345680, + 'Renaming an object store should not change the state of its key ' + + 'generator').then(() => database.close()); + }); +}, 'IndexedDB object store rename covers key generator'); + +promise_test(testCase => { + return createDatabase(testCase, (database, transaction) => { + createBooksStore(testCase, database); + }).then(database => { + database.close(); + }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { + const store = transaction.objectStore('books'); + store.name = 'books'; + assert_array_equals( + database.objectStoreNames, ['books'], + 'Renaming a store to the same name should not change ' + + "the store's IDBDatabase.objectStoreNames"); + })).then(database => { + assert_array_equals( + database.objectStoreNames, ['books'], + 'Committing a transaction that renames a store to the same name ' + + "should not change the store's IDBDatabase.objectStoreNames"); + const transaction = database.transaction('books', 'readonly', {durability: 'relaxed'}); + const store = transaction.objectStore('books'); + return checkStoreContents( + testCase, store, + 'Committing a transaction that renames a store to the same name ' + + "should not change the store's contents").then( + () => database.close()); + }); +}, 'IndexedDB object store rename to the same name succeeds'); + +promise_test(testCase => { + return createDatabase(testCase, (database, transaction) => { + createBooksStore(testCase, database); + createNotBooksStore(testCase, database); + }).then(database => { + database.close(); + }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { + const store = transaction.objectStore('books'); + database.deleteObjectStore('not_books'); + store.name = 'not_books'; + assert_array_equals( + database.objectStoreNames, ['not_books'], + 'IDBDatabase.objectStoreNames should immediately reflect the ' + + 'rename'); + })).then(database => { + assert_array_equals( + database.objectStoreNames, ['not_books'], + 'IDBDatabase.objectStoreNames should still reflect the rename ' + + 'after the versionchange transaction commits'); + const transaction = database.transaction('not_books', 'readonly', {durability: 'relaxed'}); + const store = transaction.objectStore('not_books'); + return checkStoreContents( + testCase, store, + 'Renaming an object store should not change its records').then( + () => database.close()); + }); +}, 'IndexedDB object store rename to the name of a deleted store succeeds'); + +promise_test(testCase => { + return createDatabase(testCase, (database, transaction) => { + createBooksStore(testCase, database); + createNotBooksStore(testCase, database); + }).then(database => { + database.close(); + }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { + const bookStore = transaction.objectStore('books'); + const notBookStore = transaction.objectStore('not_books'); + + transaction.objectStore('books').name = 'tmp'; + transaction.objectStore('not_books').name = 'books'; + transaction.objectStore('tmp').name = 'not_books'; + + assert_array_equals( + database.objectStoreNames, ['books', 'not_books'], + 'IDBDatabase.objectStoreNames should immediately reflect the swap'); + + assert_equals( + transaction.objectStore('books'), notBookStore, + 'IDBTransaction.objectStore should return the original "books" ' + + 'store when queried with "not_books" after the swap'); + assert_equals( + transaction.objectStore('not_books'), bookStore, + 'IDBTransaction.objectStore should return the original ' + + '"not_books" store when queried with "books" after the swap'); + })).then(database => { + assert_array_equals( + database.objectStoreNames, ['books', 'not_books'], + 'IDBDatabase.objectStoreNames should still reflect the swap ' + + 'after the versionchange transaction commits'); + const transaction = database.transaction('not_books', 'readonly', {durability: 'relaxed'}); + const store = transaction.objectStore('not_books'); + assert_array_equals( + store.indexNames, ['by_author', 'by_title'], + '"not_books" index names should still reflect the swap after the ' + + 'versionchange transaction commits'); + return checkStoreContents( + testCase, store, + 'Swapping two object stores should not change their records').then( + () => database.close()); + }); +}, 'IndexedDB object store swapping via renames succeeds'); + +promise_test(testCase => { + return createDatabase(testCase, (database, transaction) => { + createBooksStore(testCase, database); + }).then(database => { + database.close(); + }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { + const store = transaction.objectStore('books'); + + store.name = 42; + assert_equals(store.name, '42', + 'IDBObjectStore name should change immediately after a ' + + 'rename to a number'); + assert_array_equals( + database.objectStoreNames, ['42'], + 'IDBDatabase.objectStoreNames should immediately reflect the ' + + 'stringifying rename'); + + store.name = true; + assert_equals(store.name, 'true', + 'IDBObjectStore name should change immediately after a ' + + 'rename to a boolean'); + + store.name = {}; + assert_equals(store.name, '[object Object]', + 'IDBObjectStore name should change immediately after a ' + + 'rename to an object'); + + store.name = () => null; + assert_equals(store.name, '() => null', + 'IDBObjectStore name should change immediately after a ' + + 'rename to a function'); + + store.name = undefined; + assert_equals(store.name, 'undefined', + 'IDBObjectStore name should change immediately after a ' + + 'rename to undefined'); + })).then(database => { + assert_array_equals( + database.objectStoreNames, ['undefined'], + 'IDBDatabase.objectStoreNames should reflect the last rename ' + + 'after the versionchange transaction commits'); + const transaction = database.transaction('undefined', 'readonly', {durability: 'relaxed'}); + const store = transaction.objectStore('undefined'); + return checkStoreContents( + testCase, store, + 'Renaming an object store should not change its records').then( + () => database.close()); + }); +}, 'IndexedDB object store rename stringifies non-string names'); + +for (let escapedName of ['', '\\u0000', '\\uDC00\\uD800']) ((escapedName) => { + const name = JSON.parse('"' + escapedName + '"'); + promise_test(testCase => { + return createDatabase(testCase, (database, transaction) => { + createBooksStore(testCase, database); + }).then(database => { + database.close(); + }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { + const store = transaction.objectStore('books'); + + store.name = name; + assert_equals(store.name, name, + 'IDBObjectStore name should change immediately after the ' + + 'rename'); + assert_array_equals( + database.objectStoreNames, [name], + 'IDBDatabase.objectStoreNames should immediately reflect the ' + + 'rename'); + })).then(database => { + assert_array_equals( + database.objectStoreNames, [name], + 'IDBDatabase.objectStoreNames should reflect the rename ' + + 'after the versionchange transaction commits'); + const transaction = database.transaction(name, 'readonly'); + const store = transaction.objectStore(name); + return checkStoreContents( + testCase, store, + 'Renaming an object store should not change its records').then( + () => database.close()); + }); + }, 'IndexedDB object store can be renamed to "' + escapedName + '"'); +})(escapedName); + +</script> |