OLD | NEW |
(Empty) | |
| 1 <!DOCTYPE html> |
| 2 <title>IndexedDB: index renaming support</title> |
| 3 <script src='../../resources/testharness.js'></script> |
| 4 <link rel="help" |
| 5 href="https://w3c.github.io/IndexedDB/#dom-idbindex-name"> |
| 6 <link rel="author" href="pwnall@chromium.org" title="Victor Costan"> |
| 7 <script src='../../resources/testharnessreport.js'></script> |
| 8 <script src='resources/rename-common.js'></script> |
| 9 <script> |
| 10 |
| 11 promise_test(testCase => { |
| 12 let authorIndex = null, authorIndex2 = null; |
| 13 let renamedAuthorIndex = null, renamedAuthorIndex2 = null; |
| 14 return createDatabase(testCase, (database, transaction) => { |
| 15 const store = createBooksStore(testCase, database); |
| 16 authorIndex = store.index('by_author'); |
| 17 }).then(database => { |
| 18 const transaction = database.transaction('books', 'readonly'); |
| 19 const store = transaction.objectStore('books'); |
| 20 assert_array_equals( |
| 21 store.indexNames, ['by_author', 'by_title'], |
| 22 'Test setup should have created two indexes'); |
| 23 authorIndex2 = store.index('by_author'); |
| 24 return checkAuthorIndexContents( |
| 25 testCase, authorIndex2, |
| 26 'The index should have the expected contents before any renaming'). |
| 27 then(() => database.close()); |
| 28 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 29 const store = transaction.objectStore('books'); |
| 30 renamedAuthorIndex = store.index('by_author'); |
| 31 renamedAuthorIndex.name = 'renamed_by_author'; |
| 32 |
| 33 assert_equals( |
| 34 renamedAuthorIndex.name, 'renamed_by_author', |
| 35 'IDBIndex name should change immediately after a rename'); |
| 36 assert_array_equals( |
| 37 store.indexNames, ['by_title', 'renamed_by_author'], |
| 38 'IDBObjectStore.indexNames should immediately reflect the rename'); |
| 39 assert_equals( |
| 40 store.index('renamed_by_author'), renamedAuthorIndex, |
| 41 'IDBObjectStore.index should return the renamed index store when ' + |
| 42 'queried using the new name immediately after the rename'); |
| 43 assert_throws( |
| 44 'NotFoundError', () => store.index('by_author'), |
| 45 'IDBObjectStore.index should throw when queried using the ' + |
| 46 "renamed index's old name immediately after the rename"); |
| 47 })).then(database => { |
| 48 const transaction = database.transaction('books', 'readonly'); |
| 49 const store = transaction.objectStore('books'); |
| 50 assert_array_equals( |
| 51 store.indexNames, ['by_title', 'renamed_by_author'], |
| 52 'IDBObjectStore.indexNames should still reflect the rename after ' + |
| 53 'the versionchange transaction commits'); |
| 54 renamedAuthorIndex2 = store.index('renamed_by_author'); |
| 55 return checkAuthorIndexContents( |
| 56 testCase, renamedAuthorIndex2, |
| 57 'Renaming an index should not change its contents').then( |
| 58 () => database.close()); |
| 59 }).then(() => { |
| 60 assert_equals( |
| 61 authorIndex.name, 'by_author', |
| 62 'IDBIndex obtained before the rename transaction should not ' + |
| 63 'reflect the rename'); |
| 64 assert_equals( |
| 65 authorIndex2.name, 'by_author', |
| 66 'IDBIndex obtained before the rename transaction should not ' + |
| 67 'reflect the rename'); |
| 68 assert_equals( |
| 69 renamedAuthorIndex.name, 'renamed_by_author', |
| 70 'IDBIndex used in the rename transaction should keep reflecting ' + |
| 71 'the new name after the transaction is committed'); |
| 72 assert_equals( |
| 73 renamedAuthorIndex2.name, 'renamed_by_author', |
| 74 'IDBIndex obtained after the rename transaction should reflect ' + |
| 75 'the new name'); |
| 76 }); |
| 77 }, 'IndexedDB index rename in new transaction'); |
| 78 |
| 79 promise_test(testCase => { |
| 80 let renamedAuthorIndex = null, renamedAuthorIndex2 = null; |
| 81 return createDatabase(testCase, (database, transaction) => { |
| 82 const store = createBooksStore(testCase, database); |
| 83 renamedAuthorIndex = store.index('by_author'); |
| 84 renamedAuthorIndex.name = 'renamed_by_author'; |
| 85 |
| 86 assert_equals( |
| 87 renamedAuthorIndex.name, 'renamed_by_author', |
| 88 'IDBIndex name should change immediately after a rename'); |
| 89 assert_array_equals( |
| 90 store.indexNames, ['by_title', 'renamed_by_author'], |
| 91 'IDBObjectStore.indexNames should immediately reflect the rename'); |
| 92 assert_equals( |
| 93 store.index('renamed_by_author'), renamedAuthorIndex, |
| 94 'IDBObjectStore.index should return the renamed index store when ' + |
| 95 'queried using the new name immediately after the rename'); |
| 96 assert_throws( |
| 97 'NotFoundError', () => store.index('by_author'), |
| 98 'IDBObjectStore.index should throw when queried using the ' + |
| 99 "renamed index's old name immediately after the rename"); |
| 100 }).then(database => { |
| 101 const transaction = database.transaction('books', 'readonly'); |
| 102 const store = transaction.objectStore('books'); |
| 103 assert_array_equals( |
| 104 store.indexNames, ['by_title', 'renamed_by_author'], |
| 105 'IDBObjectStore.indexNames should still reflect the rename after ' + |
| 106 'the versionchange transaction commits'); |
| 107 renamedAuthorIndex2 = store.index('renamed_by_author'); |
| 108 return checkAuthorIndexContents( |
| 109 testCase, renamedAuthorIndex2, |
| 110 'Renaming an index should not change its contents').then( |
| 111 () => database.close()); |
| 112 }).then(() => { |
| 113 assert_equals( |
| 114 renamedAuthorIndex.name, 'renamed_by_author', |
| 115 'IDBIndex used in the rename transaction should keep reflecting ' + |
| 116 'the new name after the transaction is committed'); |
| 117 assert_equals( |
| 118 renamedAuthorIndex2.name, 'renamed_by_author', |
| 119 'IDBIndex obtained after the rename transaction should reflect ' + |
| 120 'the new name'); |
| 121 }); |
| 122 }, 'IndexedDB index rename in the transaction where it is created'); |
| 123 |
| 124 promise_test(testCase => { |
| 125 return createDatabase(testCase, (database, transaction) => { |
| 126 createBooksStore(testCase, database); |
| 127 }).then(database => { |
| 128 database.close(); |
| 129 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 130 const store = transaction.objectStore('books'); |
| 131 const index = store.index('by_author'); |
| 132 index.name = 'by_author'; |
| 133 assert_array_equals( |
| 134 store.indexNames, ['by_author', 'by_title'], |
| 135 'Renaming an index to the same name should not change the ' + |
| 136 "index's IDBObjectStore.indexNames"); |
| 137 })).then(database => { |
| 138 const transaction = database.transaction('books', 'readonly'); |
| 139 const store = transaction.objectStore('books'); |
| 140 assert_array_equals( |
| 141 store.indexNames, ['by_author', 'by_title'], |
| 142 'Committing a transaction that renames a store to the same name ' + |
| 143 "should not change the index's IDBObjectStore.indexNames"); |
| 144 const index = store.index('by_author'); |
| 145 return checkAuthorIndexContents( |
| 146 testCase, index, |
| 147 'Committing a transaction that renames an index to the same name ' + |
| 148 "should not change the index's contents").then( |
| 149 () => database.close()); |
| 150 }); |
| 151 }, 'IndexedDB index rename to the same name succeeds'); |
| 152 |
| 153 promise_test(testCase => { |
| 154 return createDatabase(testCase, (database, transaction) => { |
| 155 createBooksStore(testCase, database); |
| 156 }).then(database => { |
| 157 database.close(); |
| 158 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 159 const store = transaction.objectStore('books'); |
| 160 const index = store.index('by_author'); |
| 161 store.deleteIndex('by_title'); |
| 162 index.name = 'by_title'; |
| 163 assert_array_equals( |
| 164 store.indexNames, ['by_title'], |
| 165 'IDBObjectStore.indexNames should immediately reflect the rename'); |
| 166 })).then(database => { |
| 167 const transaction = database.transaction('books', 'readonly'); |
| 168 const store = transaction.objectStore('books'); |
| 169 assert_array_equals( |
| 170 store.indexNames, ['by_title'], |
| 171 'IDBObjectStore.indexNames should still reflect the rename after ' + |
| 172 'the versionchange transaction commits'); |
| 173 const index = store.index('by_title'); |
| 174 return checkAuthorIndexContents( |
| 175 testCase, index, |
| 176 'Renaming an index should not change its contents').then( |
| 177 () => database.close()); |
| 178 }); |
| 179 }, 'IndexedDB index rename to the name of a deleted index succeeds'); |
| 180 |
| 181 promise_test(testCase => { |
| 182 return createDatabase(testCase, (database, transaction) => { |
| 183 createBooksStore(testCase, database); |
| 184 }).then(database => { |
| 185 database.close(); |
| 186 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 187 const store = transaction.objectStore('books'); |
| 188 store.index('by_author').name = 'tmp'; |
| 189 store.index('by_title').name = 'by_author'; |
| 190 store.index('tmp').name = 'by_title'; |
| 191 assert_array_equals( |
| 192 store.indexNames, ['by_author', 'by_title'], |
| 193 'IDBObjectStore.indexNames should reflect the swap immediately ' + |
| 194 'after the renames'); |
| 195 return checkTitleIndexContents( |
| 196 testCase, store.index('by_author'), |
| 197 'Renaming an index should not change its contents'); |
| 198 })).then(database => { |
| 199 const transaction = database.transaction('books', 'readonly'); |
| 200 const store = transaction.objectStore('books'); |
| 201 assert_array_equals( |
| 202 store.indexNames, ['by_author', 'by_title'], |
| 203 'IDBObjectStore.indexNames should still reflect the swap after ' + |
| 204 'the versionchange transaction commits'); |
| 205 const index = store.index('by_title'); |
| 206 return checkAuthorIndexContents( |
| 207 testCase, index, |
| 208 'Renaming an index should not change its contents').then( |
| 209 () => database.close()); |
| 210 }); |
| 211 }, 'IndexedDB index swapping via renames succeeds'); |
| 212 |
| 213 promise_test(testCase => { |
| 214 return createDatabase(testCase, (database, transaction) => { |
| 215 createBooksStore(testCase, database); |
| 216 }).then(database => { |
| 217 database.close(); |
| 218 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 219 const store = transaction.objectStore('books'); |
| 220 const index = store.index('by_author'); |
| 221 |
| 222 index.name = 42; |
| 223 assert_equals(index.name, '42', |
| 224 'IDBIndex name should change immediately after a rename to a ' + |
| 225 'number'); |
| 226 assert_array_equals( |
| 227 store.indexNames, ['42', 'by_title'], |
| 228 'IDBObjectStore.indexNames should immediately reflect the ' + |
| 229 'stringifying rename'); |
| 230 |
| 231 index.name = true; |
| 232 assert_equals(index.name, 'true', |
| 233 'IDBIndex name should change immediately after a rename to a ' + |
| 234 'boolean'); |
| 235 |
| 236 index.name = {}; |
| 237 assert_equals(index.name, '[object Object]', |
| 238 'IDBIndex name should change immediately after a rename to an ' + |
| 239 'object'); |
| 240 |
| 241 index.name = () => null; |
| 242 assert_equals(index.name, '() => null', |
| 243 'IDBIndex name should change immediately after a rename to a ' + |
| 244 'function'); |
| 245 |
| 246 index.name = undefined; |
| 247 assert_equals(index.name, 'undefined', |
| 248 'IDBIndex name should change immediately after a rename to ' + |
| 249 'undefined'); |
| 250 })).then(database => { |
| 251 const transaction = database.transaction('books', 'readonly'); |
| 252 const store = transaction.objectStore('books'); |
| 253 assert_array_equals( |
| 254 store.indexNames, ['by_title', 'undefined'], |
| 255 'IDBObjectStore.indexNames should reflect the last rename ' + |
| 256 'after the versionchange transaction commits'); |
| 257 const index = store.index('undefined'); |
| 258 return checkAuthorIndexContents( |
| 259 testCase, index, |
| 260 'Renaming an index should not change its contents').then( |
| 261 () => database.close()); |
| 262 }); |
| 263 }, 'IndexedDB index rename stringifies non-string names'); |
| 264 |
| 265 for (let escapedName of ['', '\\u0000', '\\uDC00\\uD800']) ((escapedName) => { |
| 266 const name = JSON.parse('"' + escapedName + '"'); |
| 267 promise_test(testCase => { |
| 268 return createDatabase(testCase, (database, transaction) => { |
| 269 createBooksStore(testCase, database); |
| 270 }).then(database => { |
| 271 database.close(); |
| 272 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 273 const store = transaction.objectStore('books'); |
| 274 const index = store.index('by_author'); |
| 275 |
| 276 index.name = name; |
| 277 assert_equals(index.name, name, |
| 278 'IDBIndex name should change immediately after the rename'); |
| 279 assert_array_equals( |
| 280 store.indexNames, [name, 'by_title'].sort(), |
| 281 'IDBObjectStore.indexNames should immediately reflect the rename'); |
| 282 })).then(database => { |
| 283 const transaction = database.transaction('books', 'readonly'); |
| 284 const store = transaction.objectStore('books'); |
| 285 assert_array_equals( |
| 286 store.indexNames, [name, 'by_title'].sort(), |
| 287 'IDBObjectStore.indexNames should reflect the rename ' + |
| 288 'after the versionchange transaction commits'); |
| 289 const index = store.index(name); |
| 290 return checkAuthorIndexContents( |
| 291 testCase, index, |
| 292 'Renaming an index should not change its contents').then( |
| 293 () => database.close()); |
| 294 }); |
| 295 }, 'IndexedDB index can be renamed to "' + escapedName + '"'); |
| 296 })(escapedName); |
| 297 |
| 298 </script> |
OLD | NEW |