OLD | NEW |
| (Empty) |
1 <!DOCTYPE html> | |
2 <title>IndexedDB: index renaming support</title> | |
3 <link rel="help" | |
4 href="https://w3c.github.io/IndexedDB/#dom-idbindex-name"> | |
5 <link rel="author" href="pwnall@chromium.org" title="Victor Costan"> | |
6 <script src="/resources/testharness.js"></script> | |
7 <script src="/resources/testharnessreport.js"></script> | |
8 <script src="support-promises.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 |