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> | |
9 | |
10 // Returns an IndexedDB database name likely to be unique to the test case. | |
11 const databaseName = function(testCase) { | |
12 return 'db' + self.location.pathname + '-' + testCase.name; | |
13 }; | |
14 | |
15 // Creates an EventWatcher covering all the events that can be issued by | |
16 // IndexedDB requests and transactions. | |
17 const requestWatcher = function(testCase, request) { | |
18 return new EventWatcher(testCase, request, | |
19 ['error', 'success', 'upgradeneeded']); | |
20 }; | |
21 | |
22 // Migrates an IndexedDB database whose name is unique for the test case. | |
23 // | |
24 // setupCallback will be called during a versionchange transaction, and will be | |
25 // given the created database and the versionchange transaction. | |
26 // | |
27 // Returns a promise that resolves to an IndexedDB database. The caller must | |
28 // close the database. | |
29 const migrateDatabase = function(testCase, newVersion, setupCallback) { | |
30 // We cannot use eventWatcher.wait_for('upgradeneeded') here, because | |
31 // the versionchange transaction auto-commits before the Promise's then | |
32 // callback gets called. | |
33 return new Promise((resolve, reject) => { | |
34 const request = indexedDB.open(databaseName(testCase), newVersion); | |
35 request.onupgradeneeded = event => { | |
36 const eventWatcher = requestWatcher(testCase, request); | |
37 const database = event.target.result; | |
38 const transaction = event.target.transaction; | |
39 setupCallback(database, transaction); | |
40 resolve(eventWatcher.wait_for('success')); | |
41 }; | |
42 request.onerror = event => reject(event.target.error); | |
43 }).then(event => event.target.result); | |
44 }; | |
45 | |
46 // Creates an IndexedDB database whose name is unique for the test case. | |
47 // | |
48 // setupCallback will be called during a versionchange transaction, and will be | |
49 // given the created database and the versionchange transaction. | |
50 // | |
51 // Returns a promise that resolves to an IndexedDB database. The caller must | |
52 // close the database. | |
53 const createDatabase = function(testCase, setupCallback) { | |
54 const request = indexedDB.deleteDatabase(databaseName(testCase)); | |
55 const eventWatcher = requestWatcher(testCase, request); | |
56 | |
57 return eventWatcher.wait_for('success').then(event => | |
58 migrateDatabase(testCase, 1, setupCallback)); | |
59 }; | |
60 | |
61 // Creates a 'books' object store whose contents closely resembles the first | |
62 // example in the IndexedDB specification. | |
63 const createBooksStore = function(testCase, database) { | |
64 const store = database.createObjectStore('books', | |
65 { keyPath: 'isbn', autoIncrement: true }); | |
66 store.createIndex('by_author', 'author'); | |
67 store.createIndex('by_title', 'title', { unique: true }); | |
68 store.put({ title: 'Quarry Memories', author: 'Fred', isbn: 123456 }); | |
jsbell
2016/09/02 22:57:36
Maybe make a global `const SAMPLE_DATA = [ ... ]`
pwnall
2016/09/03 06:01:19
Done.
I called it BOOKS_RECORD_DATA. Please let m
| |
69 store.put({ title: 'Water Buffaloes', author: 'Fred', isbn: 234567 }); | |
70 store.put({ title: 'Bedrock Nights', author: 'Barney', isbn: 345678 }); | |
71 return store; | |
72 }; | |
73 | |
74 // Verifies that an object store's index matches the index used to create the | |
75 // by_author books store in the test database's version 1. | |
76 // | |
77 // The errorMessage is used if the assertions fail. It can state that the | |
78 // IndexedDB implementation being tested is incorrect, or that the testing code | |
79 // is using it incorrectly. | |
80 const checkAuthorIndexContents = function(testCase, index, errorMessage) { | |
81 const request = index.get('Barney'); | |
jsbell
2016/09/02 22:57:36
... and then use the SAMPLE_DATA[0]'s values rathe
pwnall
2016/09/03 06:01:19
Done.
| |
82 const eventWatcher = requestWatcher(testCase, request); | |
83 return eventWatcher.wait_for('success').then(() => { | |
84 const result = request.result; | |
85 assert_equals(result.isbn, 345678, errorMessage); | |
86 assert_equals(result.title, 'Bedrock Nights', errorMessage); | |
87 }); | |
88 }; | |
89 | |
90 // Verifies that an object store's index matches the index used to create the | |
91 // by_title books store in the test database's version 1. | |
92 // | |
93 // The errorMessage is used if the assertions fail. It can state that the | |
94 // IndexedDB implementation being tested is incorrect, or that the testing code | |
95 // is using it incorrectly. | |
96 const checkTitleIndexContents = function(testCase, index, errorMessage) { | |
97 const request = index.get('Bedrock Nights'); | |
jsbell
2016/09/02 22:57:36
ditto
pwnall
2016/09/03 06:01:19
Done.
| |
98 const eventWatcher = requestWatcher(testCase, request); | |
99 return eventWatcher.wait_for('success').then(() => { | |
100 const result = request.result; | |
101 assert_equals(result.author, 'Barney', errorMessage); | |
102 assert_equals(result.isbn, 345678, errorMessage); | |
103 }); | |
104 }; | |
105 | |
106 promise_test(testCase => { | |
107 let authorIndex = null, authorIndex2 = null; | |
108 let renamedAuthorIndex = null, renamedAuthorIndex2 = null; | |
109 return createDatabase(testCase, (database, transaction) => { | |
110 const store = createBooksStore(testCase, database); | |
111 authorIndex = store.index('by_author'); | |
112 }).then(database => { | |
113 const transaction = database.transaction('books', 'readonly'); | |
114 const store = transaction.objectStore('books'); | |
115 assert_array_equals( | |
116 store.indexNames, ['by_author', 'by_title'], | |
117 'Test setup should have created two indexes'); | |
118 authorIndex2 = store.index('by_author'); | |
119 return checkAuthorIndexContents( | |
120 testCase, authorIndex2, | |
121 'The index content checks should pass before any renaming').then( | |
122 () => database.close()); | |
123 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
124 const store = transaction.objectStore('books'); | |
125 renamedAuthorIndex = store.index('by_author'); | |
126 renamedAuthorIndex.name = 'renamed_by_author'; | |
127 | |
128 assert_equals( | |
129 renamedAuthorIndex.name, 'renamed_by_author', | |
130 'IDBIndex name should change immediately after a rename'); | |
131 assert_array_equals( | |
132 store.indexNames, ['by_title', 'renamed_by_author'], | |
133 'IDBObjectStore.indexNames should immediately reflect the rename'); | |
134 assert_equals( | |
135 store.index('renamed_by_author'), renamedAuthorIndex, | |
136 'IDBObjectStore.index should return the renamed index store when ' + | |
137 'queried using the new name immediately after the rename'); | |
138 assert_throws( | |
139 'NotFoundError', () => store.index('by_author'), | |
140 'IDBObjectStore.index should throw when queried using the renamed' + | |
141 "index's old name immediately after the rename"); | |
142 })).then(database => { | |
143 const transaction = database.transaction('books', 'readonly'); | |
144 const store = transaction.objectStore('books'); | |
145 assert_array_equals( | |
146 store.indexNames, ['by_title', 'renamed_by_author'], | |
147 'IDBObjectStore.indexNames should still reflect the rename after ' + | |
148 'the versionchange transaction commits'); | |
149 renamedAuthorIndex2 = store.index('renamed_by_author'); | |
150 return checkAuthorIndexContents( | |
151 testCase, renamedAuthorIndex2, | |
152 'Renaming an index should not change its contents').then( | |
153 () => database.close()); | |
154 }).then(() => { | |
155 assert_equals( | |
156 authorIndex.name, 'by_author', | |
157 'IDBIndex obtained before the rename transaction should not ' + | |
158 'reflect the rename'); | |
159 assert_equals( | |
160 authorIndex2.name, 'by_author', | |
161 'IDBIndex obtained before the rename transaction should not ' + | |
162 'reflect the rename'); | |
163 assert_equals( | |
164 renamedAuthorIndex.name, 'renamed_by_author', | |
165 'IDBIndex used in the rename transaction should keep reflecting ' + | |
166 'the new name after the transaction is committed'); | |
167 assert_equals( | |
168 renamedAuthorIndex2.name, 'renamed_by_author', | |
169 'IDBIndex obtained after the rename transaction should reflect ' + | |
170 'the new name'); | |
171 }); | |
172 }, 'IndexedDB index rename in new transaction'); | |
173 | |
174 promise_test(testCase => { | |
175 let renamedAuthorIndex = null, renamedAuthorIndex2 = null; | |
176 return createDatabase(testCase, (database, transaction) => { | |
177 const store = createBooksStore(testCase, database); | |
178 renamedAuthorIndex = store.index('by_author'); | |
179 renamedAuthorIndex.name = 'renamed_by_author'; | |
180 | |
181 assert_equals( | |
182 renamedAuthorIndex.name, 'renamed_by_author', | |
183 'IDBIndex name should change immediately after a rename'); | |
184 assert_array_equals( | |
185 store.indexNames, ['by_title', 'renamed_by_author'], | |
186 'IDBObjectStore.indexNames should immediately reflect the rename'); | |
187 assert_equals( | |
188 store.index('renamed_by_author'), renamedAuthorIndex, | |
189 'IDBObjectStore.index should return the renamed index store when ' + | |
190 'queried using the new name immediately after the rename'); | |
191 assert_throws( | |
192 'NotFoundError', () => store.index('by_author'), | |
193 'IDBObjectStore.index should throw when queried using the renamed' + | |
194 "index's old name immediately after the rename"); | |
195 }).then(database => { | |
196 const transaction = database.transaction('books', 'readonly'); | |
197 const store = transaction.objectStore('books'); | |
198 assert_array_equals( | |
199 store.indexNames, ['by_title', 'renamed_by_author'], | |
200 'IDBObjectStore.indexNames should still reflect the rename after ' + | |
201 'the versionchange transaction commits'); | |
202 renamedAuthorIndex2 = store.index('renamed_by_author'); | |
203 return checkAuthorIndexContents( | |
204 testCase, renamedAuthorIndex2, | |
205 'Renaming an index should not change its contents').then( | |
206 () => database.close()); | |
207 }).then(() => { | |
208 assert_equals( | |
209 renamedAuthorIndex.name, 'renamed_by_author', | |
210 'IDBIndex used in the rename transaction should keep reflecting ' + | |
211 'the new name after the transaction is committed'); | |
212 assert_equals( | |
213 renamedAuthorIndex2.name, 'renamed_by_author', | |
214 'IDBIndex obtained after the rename transaction should reflect ' + | |
215 'the new name'); | |
216 }); | |
217 }, 'IndexedDB index rename in the transaction where it is created'); | |
218 | |
219 promise_test(testCase => { | |
220 return createDatabase(testCase, (database, transaction) => { | |
221 createBooksStore(testCase, database); | |
222 }).then(database => { | |
223 database.close(); | |
224 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
225 const store = transaction.objectStore('books'); | |
226 const index = store.index('by_author'); | |
227 store.deleteIndex('by_author'); | |
228 assert_throws( | |
229 'InvalidStateError', () => index.name = 'renamed_by_author'); | |
230 })).then(database => database.close()); | |
231 }, 'IndexedDB deleted index rename throws'); | |
232 | |
233 promise_test(testCase => { | |
234 return createDatabase(testCase, (database, transaction) => { | |
235 createBooksStore(testCase, database); | |
236 }).then(database => { | |
237 const transaction = database.transaction('books', 'readonly'); | |
238 const store = transaction.objectStore('books'); | |
239 const index = store.index('by_author'); | |
240 | |
241 assert_throws( | |
242 'InvalidStateError', () => index.name = 'renamed_by_author'); | |
243 database.close(); | |
244 }); | |
245 }, 'IndexedDB index rename throws in a readonly transaction'); | |
246 | |
247 promise_test(testCase => { | |
248 return createDatabase(testCase, (database, transaction) => { | |
249 createBooksStore(testCase, database); | |
250 }).then(database => { | |
251 const transaction = database.transaction('books', 'readwrite'); | |
252 const store = transaction.objectStore('books'); | |
253 const index = store.index('by_author'); | |
254 | |
255 assert_throws( | |
256 'InvalidStateError', () => index.name = 'renamed_by_author'); | |
257 database.close(); | |
258 }); | |
259 }, 'IndexedDB index rename throws in a readwrite transaction'); | |
260 | |
261 promise_test(testCase => { | |
262 let authorIndex = null; | |
263 return createDatabase(testCase, (database, transaction) => { | |
264 const store = createBooksStore(testCase, database); | |
265 authorIndex = store.index('by_author'); | |
266 }).then(database => { | |
267 assert_throws( | |
268 'TransactionInactiveError', | |
269 () => authorIndex.name = 'renamed_by_author'); | |
270 database.close(); | |
271 }); | |
272 }, 'IndexedDB index rename throws in an inactive transaction'); | |
273 | |
274 promise_test(testCase => { | |
275 return createDatabase(testCase, (database, transaction) => { | |
276 createBooksStore(testCase, database); | |
277 }).then(database => { | |
278 database.close(); | |
279 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
280 const store = transaction.objectStore('books'); | |
281 const index = store.index('by_author'); | |
282 index.name = 'by_author'; | |
283 assert_array_equals( | |
284 store.indexNames, ['by_author', 'by_title'], | |
285 'Renaming an index to the same name should not change the ' + | |
286 "index's IDBObjectStore.indexNames"); | |
287 })).then(database => { | |
288 const transaction = database.transaction('books', 'readonly'); | |
289 const store = transaction.objectStore('books'); | |
290 assert_array_equals( | |
291 store.indexNames, ['by_author', 'by_title'], | |
292 'Committing a transaction that renames a store to the same name ' + | |
293 "should not change the index's IDBObjectStore.indexNames"); | |
294 const index = store.index('by_author'); | |
295 return checkAuthorIndexContents( | |
296 testCase, index, | |
297 'Committing a transaction that renames an index to the same name ' + | |
298 "should not change the index's contents").then( | |
299 () => database.close()); | |
300 }); | |
301 }, 'IndexedDB index rename to the same name succeeds'); | |
302 | |
303 promise_test(testCase => { | |
304 return createDatabase(testCase, (database, transaction) => { | |
305 createBooksStore(testCase, database); | |
306 }).then(database => { | |
307 database.close(); | |
308 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
309 const store = transaction.objectStore('books'); | |
310 const index = store.index('by_author'); | |
311 | |
312 assert_throws('ConstraintError', () => index.name = 'by_title'); | |
313 assert_array_equals( | |
314 store.indexNames, ['by_author', 'by_title'], | |
315 'An index rename that throws an exception should not change the ' + | |
316 "index's IDBObjectStore.indexNames"); | |
317 })).then(database => { | |
318 const transaction = database.transaction('books', 'readonly'); | |
319 const store = transaction.objectStore('books'); | |
320 assert_array_equals( | |
321 store.indexNames, ['by_author', 'by_title'], | |
322 'Committing a transaction with a failed store rename attempt ' + | |
323 "should not change the index's IDBObjectStore.indexNames"); | |
324 const index = store.index('by_author'); | |
325 return checkAuthorIndexContents( | |
326 testCase, index, | |
327 'Committing a transaction with a failed rename attempt should not' + | |
328 "change the index's contents").then(() => database.close()); | |
329 }); | |
330 }, 'IndexedDB index rename to the name of another index throws'); | |
331 | |
332 promise_test(testCase => { | |
333 return createDatabase(testCase, (database, transaction) => { | |
334 createBooksStore(testCase, database); | |
335 }).then(database => { | |
336 database.close(); | |
337 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
338 const store = transaction.objectStore('books'); | |
339 const index = store.index('by_author'); | |
340 store.deleteIndex('by_title'); | |
341 index.name = 'by_title'; | |
342 assert_array_equals( | |
343 store.indexNames, ['by_title'], | |
344 'IDBObjectStore.indexNames should immediately reflect the rename'); | |
345 })).then(database => { | |
346 const transaction = database.transaction('books', 'readonly'); | |
347 const store = transaction.objectStore('books'); | |
348 assert_array_equals( | |
349 store.indexNames, ['by_title'], | |
350 'IDBObjectStore.indexNames should still reflect the rename after ' + | |
351 'the versionchange transaction commits'); | |
352 const index = store.index('by_title'); | |
353 return checkAuthorIndexContents( | |
354 testCase, index, | |
355 'Renaming an index should not change its contents').then( | |
356 () => database.close()); | |
357 }); | |
358 }, 'IndexedDB index rename to the name of a deleted index succeeds'); | |
359 | |
360 promise_test(testCase => { | |
361 return createDatabase(testCase, (database, transaction) => { | |
362 createBooksStore(testCase, database); | |
363 }).then(database => { | |
364 database.close(); | |
365 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
366 const store = transaction.objectStore('books'); | |
367 store.index('by_author').name = 'tmp'; | |
368 store.index('by_title').name = 'by_author'; | |
369 store.index('tmp').name = 'by_title'; | |
370 assert_array_equals( | |
371 store.indexNames, ['by_author', 'by_title'], | |
372 'IDBObjectStore.indexNames should reflect the swap immediately ' + | |
373 'after the renames'); | |
374 return checkTitleIndexContents( | |
375 testCase, store.index('by_title'), | |
376 'Renaming an index should not change its contents'); | |
377 })).then(database => { | |
378 const transaction = database.transaction('books', 'readonly'); | |
379 const store = transaction.objectStore('books'); | |
380 assert_array_equals( | |
381 store.indexNames, ['by_author', 'by_title'], | |
382 'IDBObjectStore.indexNames should still reflect the swap after ' + | |
383 'the versionchange transaction commits'); | |
384 const index = store.index('by_title'); | |
385 return checkAuthorIndexContents( | |
386 testCase, index, | |
387 'Renaming an index should not change its contents').then( | |
388 () => database.close()); | |
389 }); | |
390 }, 'IndexedDB index swapping via renames succeeds'); | |
391 | |
392 promise_test(testCase => { | |
393 return createDatabase(testCase, (database, transaction) => { | |
394 createBooksStore(testCase, database); | |
395 }).then(database => { | |
396 database.close(); | |
397 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
398 const store = transaction.objectStore('books'); | |
399 const index = store.index('by_author'); | |
400 | |
401 index.name = 42; | |
402 assert_equals(index.name, '42', | |
403 'IDBIndex name should change immediately after a rename to a ' + | |
404 'number'); | |
405 assert_array_equals( | |
406 store.indexNames, ['42', 'by_title'], | |
407 'IDBObjectStore.indexNames should immediately reflect the ' + | |
408 'stringifying rename'); | |
409 | |
410 index.name = true; | |
411 assert_equals(index.name, 'true', | |
412 'IDBIndex name should change immediately after a rename to a ' + | |
413 'boolean'); | |
414 | |
415 index.name = {}; | |
416 assert_equals(index.name, '[object Object]', | |
417 'IDBIndex name should change immediately after a rename to an ' + | |
418 'object'); | |
419 | |
420 index.name = () => null; | |
421 assert_equals(index.name, '() => null', | |
422 'IDBIndex name should change immediately after a rename to a ' + | |
423 'function'); | |
424 | |
425 index.name = undefined; | |
426 assert_equals(index.name, 'undefined', | |
427 'IDBIndex name should change immediately after a rename to ' + | |
428 'undefined'); | |
429 })).then(database => { | |
430 const transaction = database.transaction('books', 'readonly'); | |
431 const store = transaction.objectStore('books'); | |
432 assert_array_equals( | |
433 store.indexNames, ['by_title', 'undefined'], | |
434 'IDBObjectStore.indexNames should reflect the last rename ' + | |
435 'after the versionchange transaction commits'); | |
436 const index = store.index('undefined'); | |
437 return checkAuthorIndexContents( | |
438 testCase, index, | |
439 'Renaming an index should not change its contents').then( | |
440 () => database.close()); | |
441 }); | |
442 }, 'IndexedDB object store rename stringifies non-string names'); | |
443 | |
444 promise_test(testCase => { | |
445 return createDatabase(testCase, (database, transaction) => { | |
446 createBooksStore(testCase, database); | |
447 }).then(database => { | |
448 database.close(); | |
449 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
450 const store = transaction.objectStore('books'); | |
451 const index = store.index('by_author'); | |
452 | |
453 assert_throws( | |
454 { name: 'Custom stringifying error'}, | |
455 () => { | |
456 index.name = { | |
457 toString: () => { throw { name: 'Custom stringifying error'}; } | |
458 }; | |
459 }, 'IDBObjectStore rename should re-raise toString() exception'); | |
460 assert_array_equals( | |
461 store.indexNames, ['by_author', 'by_title'], | |
462 'An index rename that throws an exception should not change the ' + | |
463 "index's IDBObjectStore.indexNames"); | |
464 })).then(database => { | |
465 const transaction = database.transaction('books', 'readonly'); | |
466 const store = transaction.objectStore('books'); | |
467 assert_array_equals( | |
468 store.indexNames, ['by_author', 'by_title'], | |
469 'Committing a transaction with a failed store rename attempt ' + | |
470 "should not change the index's IDBObjectStore.indexNames"); | |
471 const index = store.index('by_author'); | |
472 return checkAuthorIndexContents( | |
473 testCase, index, | |
474 'Committing a transaction with a failed rename attempt should not' + | |
475 "change the index's contents").then(() => database.close()); | |
476 }); | |
477 }, 'IndexedDB object store rename handles exceptions when stringifying names'); | |
478 | |
479 for (let escapedName of ['', '\\u0000', '\\uDC00\\uD800']) ((escapedName) => { | |
480 const name = JSON.parse('"' + escapedName + '"'); | |
481 promise_test(testCase => { | |
482 return createDatabase(testCase, (database, transaction) => { | |
483 createBooksStore(testCase, database); | |
484 }).then(database => { | |
485 database.close(); | |
486 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { | |
487 const store = transaction.objectStore('books'); | |
488 const index = store.index('by_author'); | |
489 | |
490 index.name = name; | |
491 assert_equals(index.name, name, | |
492 'IDBIndex name should change immediately after the rename'); | |
493 assert_array_equals( | |
494 store.indexNames, [name, 'by_title'].sort(), | |
495 'IDBObjectStore.indexNames should immediately reflect the rename'); | |
496 })).then(database => { | |
497 const transaction = database.transaction('books', 'readonly'); | |
498 const store = transaction.objectStore('books'); | |
499 assert_array_equals( | |
500 store.indexNames, [name, 'by_title'].sort(), | |
501 'IDBObjectStore.indexNames should reflect the rename ' + | |
502 'after the versionchange transaction commits'); | |
503 const index = store.index(name); | |
504 return checkAuthorIndexContents( | |
505 testCase, index, | |
506 'Renaming an index should not change its contents').then( | |
507 () => database.close()); | |
508 }); | |
509 }, 'IndexedDB object store can be renamed to "' + escapedName + '"'); | |
510 })(escapedName); | |
511 | |
512 promise_test(testCase => { | |
513 const dbName = databaseName(testCase); | |
514 let authorIndex = null, authorIndex2 = null; | |
515 return createDatabase(testCase, (database, transaction) => { | |
516 const store = createBooksStore(testCase, database); | |
517 }).then(database => { | |
518 database.close(); | |
519 }).then(() => new Promise((resolve, reject) => { | |
520 const request = indexedDB.open(dbName, 2); | |
521 request.onupgradeneeded = event => { | |
522 const database = event.target.result; | |
523 const transaction = event.target.transaction; | |
524 const store = transaction.objectStore('books'); | |
525 authorIndex = store.index('by_author'); | |
526 authorIndex.name = 'renamed_by_author'; | |
527 request.onerror = event => { | |
528 event.preventDefault(); | |
529 resolve(event); | |
530 } | |
531 transaction.abort(); | |
532 | |
533 assert_equals( | |
534 authorIndex.name, 'by_author', | |
535 'IDBIndex.name should not reflect the rename anymore ' + | |
536 'immediately after transaction.abort() returns'); | |
537 assert_array_equals( | |
538 store.indexNames, ['by_author', 'by_title'], | |
539 'IDBObjectStore.indexNames should not reflect the rename ' + | |
540 'anymore immediately after transaction.abort() returns'); | |
541 }; | |
542 request.onerror = event => reject(event.target.error); | |
543 request.onsuccess = () => reject(new Error( | |
544 'indexedDB.open was not supposed to succeed')); | |
545 })).then(event => { | |
546 assert_equals(authorIndex.name, 'by_author', | |
547 'IDBIndex.name should not reflect the rename anymore ' + | |
548 'after the versionchange transaction is aborted'); | |
549 | |
550 const request = indexedDB.open(dbName, 1); | |
551 return requestWatcher(testCase, request).wait_for('success'); | |
552 }).then(event => { | |
553 const database = event.target.result; | |
554 const transaction = database.transaction('books', 'readonly'); | |
555 const store = transaction.objectStore('books'); | |
556 assert_array_equals( | |
557 store.indexNames, ['by_author', 'by_title'], | |
558 'IDBDatabase.objectStoreNames should not reflect the rename ' + | |
559 'after the versionchange transaction is aborted'); | |
560 | |
561 authorIndex2 = store.index('by_author'); | |
562 return checkAuthorIndexContents( | |
563 testCase, authorIndex2, | |
564 'Aborting an index rename transaction should not change the ' + | |
565 "index's records").then(() => database.close()); | |
566 }).then(() => { | |
567 assert_equals( | |
568 authorIndex.name, 'by_author', | |
569 'IDBIndex used in aborted rename transaction should not reflect ' + | |
570 'the rename after the transaction is aborted'); | |
571 assert_equals(authorIndex2.name, 'by_author', | |
572 'IDBIndex obtained after an aborted rename transaction should ' + | |
573 'not reflect the rename'); | |
574 }); | |
575 }, 'IndexedDB object store rename in aborted transaction'); | |
576 </script> | |
OLD | NEW |