OLD | NEW |
(Empty) | |
| 1 <!doctype html> |
| 2 <title>IndexedDB: versionchange transaction lifecycle</title> |
| 3 <!-- These tests cannot yet be upstreamed to WPT because they rely on microtask |
| 4 sequencing, which was not fully specified yet. --> |
| 5 <link rel="help" |
| 6 href="https://w3c.github.io/IndexedDB/#upgrade-transaction-steps"> |
| 7 <link rel="help" |
| 8 href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore"> |
| 9 <link rel="help" |
| 10 href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore"> |
| 11 <link rel="author" href="pwnall@chromium.org" title="Victor Costan"> |
| 12 <script src="../../resources/testharness.js"></script> |
| 13 <script src="../../resources/testharnessreport.js"></script> |
| 14 <script src="resources/support-promises.js"></script> |
| 15 <script> |
| 16 'use strict'; |
| 17 |
| 18 promise_test(t => { |
| 19 let testStepPromise = null, abortPromise = null; |
| 20 return createDatabase(t, database => { |
| 21 createBooksStore(t, database); |
| 22 }).then(database => { |
| 23 database.close(); |
| 24 }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { |
| 25 let abortFired = false; |
| 26 |
| 27 testStepPromise = Promise.resolve().then(() => { |
| 28 assert_false( |
| 29 abortFired, |
| 30 'The abort event should fire after promises are resolved'); |
| 31 assert_equals( |
| 32 request.transaction, transaction, |
| 33 "The open request's transaction should be reset after onabort"); |
| 34 try { |
| 35 database.createObjectStore('books2'); |
| 36 } catch(e) { |
| 37 assert_false( |
| 38 e, |
| 39 'createObjectStore should not throw an exception, because the ' + |
| 40 'transaction is still active'); |
| 41 } |
| 42 try { |
| 43 database.deleteObjectStore('books'); |
| 44 } catch(e) { |
| 45 assert_false( |
| 46 e, |
| 47 'deleteObjectStore should not throw an exception, because the ' + |
| 48 'transaction is still active'); |
| 49 } |
| 50 }); |
| 51 abortPromise = new Promise((resolve, reject) => { |
| 52 transaction.addEventListener('abort', () => { |
| 53 abortFired = true; |
| 54 resolve(); |
| 55 }, false); |
| 56 transaction.objectStore('books').add(BOOKS_RECORD_DATA[0]); |
| 57 transaction._willBeAborted(); |
| 58 }); |
| 59 })).then(() => Promise.all([testStepPromise, abortPromise])); |
| 60 }, 'asynchronously after a failing request is issued, before the abort event ' + |
| 61 'is fired'); |
| 62 |
| 63 promise_test(t => { |
| 64 let testStepPromise = null; |
| 65 return createDatabase(t, database => { |
| 66 createBooksStore(t, database); |
| 67 }).then(database => { |
| 68 database.close(); |
| 69 }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { |
| 70 testStepPromise = new Promise((resolve, reject) => { |
| 71 transaction.addEventListener('abort', () => resolve(), false); |
| 72 transaction.objectStore('books').add(BOOKS_RECORD_DATA[0]); |
| 73 transaction._willBeAborted(); |
| 74 }).then(() => { |
| 75 assert_equals( |
| 76 request.transaction, transaction, |
| 77 "The open request's transaction should be reset after onabort " + |
| 78 'microtasks'); |
| 79 assert_throws( |
| 80 'InvalidStateError', |
| 81 () => { database.createObjectStore('books2'); }, |
| 82 'createObjectStore exception should reflect that the transaction ' + |
| 83 'is no longer running'); |
| 84 assert_throws( |
| 85 'InvalidStateError', |
| 86 () => { database.deleteObjectStore('books'); }, |
| 87 'deleteObjectStore exception should reflect that the transaction ' + |
| 88 'is no longer running'); |
| 89 }); |
| 90 })).then(() => testStepPromise); |
| 91 }, 'after the abort event is fired due to a bad request'); |
| 92 |
| 93 promise_test(t => { |
| 94 let testStepPromise = null; |
| 95 return createDatabase(t, database => { |
| 96 createBooksStore(t, database); |
| 97 }).then(database => { |
| 98 database.close(); |
| 99 }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { |
| 100 testStepPromise = new Promise((resolve, reject) => { |
| 101 transaction.addEventListener('abort', () => resolve(), false); |
| 102 transaction.abort(); |
| 103 }).then(() => { |
| 104 assert_equals( |
| 105 request.transaction, transaction, |
| 106 "The open request's transaction should be reset after onabort " + |
| 107 'microtasks'); |
| 108 assert_throws( |
| 109 'InvalidStateError', |
| 110 () => { database.createObjectStore('books2'); }, |
| 111 'createObjectStore exception should reflect that the transaction ' + |
| 112 'is no longer running'); |
| 113 assert_throws( |
| 114 'InvalidStateError', |
| 115 () => { database.deleteObjectStore('books'); }, |
| 116 'deleteObjectStore exception should reflect that the transaction ' + |
| 117 'is no longer running'); |
| 118 }); |
| 119 })).then(() => testStepPromise); |
| 120 }, 'after the abort event is fired due to an abort() call'); |
| 121 |
| 122 promise_test(t => { |
| 123 let testStepPromise = null, completePromise = null; |
| 124 return createDatabase(t, database => { |
| 125 createBooksStore(t, database); |
| 126 }).then(database => { |
| 127 database.close(); |
| 128 }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { |
| 129 let completeFired = false; |
| 130 completePromise = new Promise((resolve, reject) => { |
| 131 transaction.addEventListener('complete', () => { |
| 132 completeFired = true; |
| 133 resolve(); |
| 134 }, false); |
| 135 }); |
| 136 |
| 137 testStepPromise = Promise.resolve().then(() => { |
| 138 assert_false( |
| 139 completeFired, |
| 140 'The complete event should fire after promises are resolved'); |
| 141 assert_equals( |
| 142 request.transaction, transaction, |
| 143 "The open request's transaction should be reset after oncomplete"); |
| 144 try { |
| 145 database.createObjectStore('books2'); |
| 146 } catch(e) { |
| 147 assert_false( |
| 148 e, |
| 149 'createObjectStore should not throw an exception, because the ' + |
| 150 'transaction is still active'); |
| 151 } |
| 152 |
| 153 try { |
| 154 database.deleteObjectStore('books'); |
| 155 } catch(e) { |
| 156 assert_false( |
| 157 e, |
| 158 'deleteObjectStore should not throw an exception, because the ' + |
| 159 'transaction is still active'); |
| 160 } |
| 161 }); |
| 162 })).then(database => { |
| 163 database.close(); |
| 164 return Promise.all([testStepPromise, completePromise]); |
| 165 }); |
| 166 }, 'in a resolved promise after the transaction requests are performed'); |
| 167 |
| 168 promise_test(t => { |
| 169 let testStepPromise = null, completePromise = null; |
| 170 return createDatabase(t, database => { |
| 171 createBooksStore(t, database); |
| 172 }).then(database => { |
| 173 database.close(); |
| 174 }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { |
| 175 completePromise = new Promise((resolve, reject) => { |
| 176 transaction.addEventListener('complete', () => resolve(), false); |
| 177 }).then(() => { |
| 178 assert_equals( |
| 179 request.transaction, transaction, |
| 180 "The open request's transaction should be reset after oncomplete " + |
| 181 'microtasks'); |
| 182 assert_throws( |
| 183 'InvalidStateError', |
| 184 () => { database.createObjectStore('books2'); }, |
| 185 'createObjectStore exception should reflect that the transaction ' + |
| 186 'is no longer running'); |
| 187 assert_throws( |
| 188 'InvalidStateError', |
| 189 () => { database.deleteObjectStore('books'); }, |
| 190 'deleteObjectStore exception should reflect that the transaction ' + |
| 191 'is no longer running'); |
| 192 }); |
| 193 })).then(database => { |
| 194 database.close(); |
| 195 return Promise.all([testStepPromise, completePromise]); |
| 196 }); |
| 197 }, 'in a resolved promise after the complete event is fired'); |
| 198 |
| 199 </script> |
OLD | NEW |