Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(915)

Side by Side Diff: third_party/WebKit/LayoutTests/imported/wpt/IndexedDB/support-promises.js

Issue 2624663003: Import wpt@dc3eba22286488a5acd2653763d8ce4b8c77f99c (Closed)
Patch Set: Modify TestExpectations or download new baselines for tests. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Returns an IndexedDB database name likely to be unique to the test case. 1 'use strict';
2 const databaseName = (testCase) => { 2
3 // Returns an IndexedDB database name that is unique to the test case.
4 function databaseName(testCase) {
3 return 'db' + self.location.pathname + '-' + testCase.name; 5 return 'db' + self.location.pathname + '-' + testCase.name;
4 }; 6 }
5 7
6 // Creates an EventWatcher covering all the events that can be issued by 8 // Creates an EventWatcher covering all the events that can be issued by
7 // IndexedDB requests and transactions. 9 // IndexedDB requests and transactions.
8 const requestWatcher = (testCase, request) => { 10 function requestWatcher(testCase, request) {
9 return new EventWatcher(testCase, request, 11 return new EventWatcher(testCase, request,
10 ['error', 'success', 'upgradeneeded']); 12 ['abort', 'blocked', 'complete', 'error', 'success', 'upgradeneeded']);
11 }; 13 }
12 14
13 // Migrates an IndexedDB database whose name is unique for the test case. 15 // Migrates an IndexedDB database whose name is unique for the test case.
14 // 16 //
15 // newVersion must be greater than the database's current version. 17 // newVersion must be greater than the database's current version.
16 // 18 //
17 // migrationCallback will be called during a versionchange transaction and will 19 // migrationCallback will be called during a versionchange transaction and will
18 // be given the created database and the versionchange transaction. 20 // given the created database, the versionchange transaction, and the database
21 // open request.
19 // 22 //
20 // Returns a promise. If the versionchange transaction goes through, the promise 23 // Returns a promise. If the versionchange transaction goes through, the promise
21 // resolves to an IndexedDB database that must be closed by the caller. If the 24 // resolves to an IndexedDB database that must be closed by the caller. If the
22 // versionchange transaction is aborted, the promise resolves to an error. 25 // versionchange transaction is aborted, the promise resolves to an error.
23 const migrateDatabase = (testCase, newVersion, migrationCallback) => { 26 function migrateDatabase(testCase, newVersion, migrationCallback) {
24 return migrateNamedDatabase( 27 return migrateNamedDatabase(
25 testCase, databaseName(testCase), newVersion, migrationCallback); 28 testCase, databaseName(testCase), newVersion, migrationCallback);
26 }; 29 }
27 30
28 // Migrates an IndexedDB database. 31 // Migrates an IndexedDB database.
29 // 32 //
30 // newVersion must be greater than the database's current version. 33 // newVersion must be greater than the database's current version.
31 // 34 //
32 // migrationCallback will be called during a versionchange transaction and will 35 // migrationCallback will be called during a versionchange transaction and will
33 // be given the created database and the versionchange transaction. 36 // given the created database, the versionchange transaction, and the database
37 // open request.
34 // 38 //
35 // Returns a promise. If the versionchange transaction goes through, the promise 39 // Returns a promise. If the versionchange transaction goes through, the promise
36 // resolves to an IndexedDB database that must be closed by the caller. If the 40 // resolves to an IndexedDB database that must be closed by the caller. If the
37 // versionchange transaction is aborted, the promise resolves to an error. 41 // versionchange transaction is aborted, the promise resolves to an error.
38 const migrateNamedDatabase = 42 function migrateNamedDatabase(
39 (testCase, databaseName, newVersion, migrationCallback) => { 43 testCase, databaseName, newVersion, migrationCallback) {
40 // We cannot use eventWatcher.wait_for('upgradeneeded') here, because 44 // We cannot use eventWatcher.wait_for('upgradeneeded') here, because
41 // the versionchange transaction auto-commits before the Promise's then 45 // the versionchange transaction auto-commits before the Promise's then
42 // callback gets called. 46 // callback gets called.
43 return new Promise((resolve, reject) => { 47 return new Promise((resolve, reject) => {
44 const request = indexedDB.open(databaseName, newVersion); 48 const request = indexedDB.open(databaseName, newVersion);
45 request.onupgradeneeded = testCase.step_func(event => { 49 request.onupgradeneeded = testCase.step_func(event => {
46 const database = event.target.result; 50 const database = event.target.result;
47 const transaction = event.target.transaction; 51 const transaction = event.target.transaction;
48 let abortCalled = false; 52 let shouldBeAborted = false;
53 let requestEventPromise = null;
49 54
50 // We wrap IDBTransaction.abort so we can set up the correct event 55 // We wrap IDBTransaction.abort so we can set up the correct event
51 // listeners and expectations if the test chooses to abort the 56 // listeners and expectations if the test chooses to abort the
52 // versionchange transaction. 57 // versionchange transaction.
53 const transactionAbort = transaction.abort.bind(transaction); 58 const transactionAbort = transaction.abort.bind(transaction);
54 transaction.abort = () => { 59 transaction.abort = () => {
55 request.onerror = event => { 60 transaction._willBeAborted();
56 event.preventDefault();
57 resolve(event);
58 };
59 request.onsuccess = () => reject(new Error(
60 'indexedDB.open should not succeed after the versionchange ' +
61 'transaction is aborted'));
62 transactionAbort(); 61 transactionAbort();
63 abortCalled = true; 62 }
63 transaction._willBeAborted = () => {
64 requestEventPromise = new Promise((resolve, reject) => {
65 request.onerror = event => {
66 event.preventDefault();
67 resolve(event);
68 };
69 request.onsuccess = () => reject(new Error(
70 'indexedDB.open should not succeed for an aborted ' +
71 'versionchange transaction'));
72 });
73 shouldBeAborted = true;
64 } 74 }
65 75
66 migrationCallback(database, transaction); 76 // If migration callback returns a promise, we'll wait for it to resolve.
67 if (!abortCalled) { 77 // This simplifies some tests.
78 const callbackResult = migrationCallback(database, transaction, request);
79 if (!shouldBeAborted) {
80 request.onerror = null;
68 request.onsuccess = null; 81 request.onsuccess = null;
69 resolve(requestWatcher(testCase, request).wait_for('success')); 82 requestEventPromise =
83 requestWatcher(testCase, request).wait_for('success');
70 } 84 }
85
86 // requestEventPromise needs to be the last promise in the chain, because
87 // we want the event that it resolves to.
88 resolve(Promise.resolve(callbackResult).then(() => requestEventPromise));
71 }); 89 });
72 request.onerror = event => reject(event.target.error); 90 request.onerror = event => reject(event.target.error);
73 request.onsuccess = () => reject(new Error( 91 request.onsuccess = () => reject(new Error(
74 'indexedDB.open should not succeed without creating a ' + 92 'indexedDB.open should not succeed without creating a ' +
75 'versionchange transaction')); 93 'versionchange transaction'));
76 }).then(event => event.target.result || event.target.error); 94 }).then(event => event.target.result || event.target.error);
77 }; 95 }
78 96
79 // Creates an IndexedDB database whose name is unique for the test case. 97 // Creates an IndexedDB database whose name is unique for the test case.
80 // 98 //
81 // setupCallback will be called during a versionchange transaction, and will be 99 // setupCallback will be called during a versionchange transaction, and will be
82 // given the created database and the versionchange transaction. 100 // given the created database, the versionchange transaction, and the database
101 // open request.
83 // 102 //
84 // Returns a promise that resolves to an IndexedDB database. The caller must 103 // Returns a promise that resolves to an IndexedDB database. The caller must
85 // close the database. 104 // close the database.
86 const createDatabase = (testCase, setupCallback) => { 105 function createDatabase(testCase, setupCallback) {
87 return createNamedDatabase(testCase, databaseName(testCase), setupCallback); 106 return createNamedDatabase(testCase, databaseName(testCase), setupCallback);
88 }; 107 }
89 108
90 // Creates an IndexedDB database. 109 // Creates an IndexedDB database.
91 // 110 //
92 // setupCallback will be called during a versionchange transaction, and will be 111 // setupCallback will be called during a versionchange transaction, and will be
93 // given the created database and the versionchange transaction. 112 // given the created database, the versionchange transaction, and the database
113 // open request.
94 // 114 //
95 // Returns a promise that resolves to an IndexedDB database. The caller must 115 // Returns a promise that resolves to an IndexedDB database. The caller must
96 // close the database. 116 // close the database.
97 const createNamedDatabase = (testCase, databaseName, setupCallback) => { 117 function createNamedDatabase(testCase, databaseName, setupCallback) {
98 const request = indexedDB.deleteDatabase(databaseName); 118 const request = indexedDB.deleteDatabase(databaseName);
99 const eventWatcher = requestWatcher(testCase, request); 119 const eventWatcher = requestWatcher(testCase, request);
100 120
101 return eventWatcher.wait_for('success').then(event => 121 return eventWatcher.wait_for('success').then(event =>
102 migrateNamedDatabase(testCase, databaseName, 1, setupCallback)); 122 migrateNamedDatabase(testCase, databaseName, 1, setupCallback));
103 }; 123 }
104 124
105 // Opens an IndexedDB database without performing schema changes. 125 // Opens an IndexedDB database without performing schema changes.
106 // 126 //
107 // The given version number must match the database's current version. 127 // The given version number must match the database's current version.
108 // 128 //
109 // Returns a promise that resolves to an IndexedDB database. The caller must 129 // Returns a promise that resolves to an IndexedDB database. The caller must
110 // close the database. 130 // close the database.
111 const openDatabase = (testCase, version) => { 131 function openDatabase(testCase, version) {
112 return openNamedDatabase(testCase, databaseName(testCase), version); 132 return openNamedDatabase(testCase, databaseName(testCase), version);
113 } 133 }
114 134
115 // Opens an IndexedDB database without performing schema changes. 135 // Opens an IndexedDB database without performing schema changes.
116 // 136 //
117 // The given version number must match the database's current version. 137 // The given version number must match the database's current version.
118 // 138 //
119 // Returns a promise that resolves to an IndexedDB database. The caller must 139 // Returns a promise that resolves to an IndexedDB database. The caller must
120 // close the database. 140 // close the database.
121 const openNamedDatabase = (testCase, databaseName, version) => { 141 function openNamedDatabase(testCase, databaseName, version) {
122 const request = indexedDB.open(databaseName, version); 142 const request = indexedDB.open(databaseName, version);
123 const eventWatcher = requestWatcher(testCase, request); 143 const eventWatcher = requestWatcher(testCase, request);
124 return eventWatcher.wait_for('success').then(event => event.target.result); 144 return eventWatcher.wait_for('success').then(event => event.target.result);
125 } 145 }
126 146
127 // The data in the 'books' object store records in the first example of the 147 // The data in the 'books' object store records in the first example of the
128 // IndexedDB specification. 148 // IndexedDB specification.
129 const BOOKS_RECORD_DATA = [ 149 const BOOKS_RECORD_DATA = [
130 { title: 'Quarry Memories', author: 'Fred', isbn: 123456 }, 150 { title: 'Quarry Memories', author: 'Fred', isbn: 123456 },
131 { title: 'Water Buffaloes', author: 'Fred', isbn: 234567 }, 151 { title: 'Water Buffaloes', author: 'Fred', isbn: 234567 },
132 { title: 'Bedrock Nights', author: 'Barney', isbn: 345678 }, 152 { title: 'Bedrock Nights', author: 'Barney', isbn: 345678 },
133 ]; 153 ];
134 154
135 // Creates a 'books' object store whose contents closely resembles the first 155 // Creates a 'books' object store whose contents closely resembles the first
136 // example in the IndexedDB specification. 156 // example in the IndexedDB specification.
137 const createBooksStore = (testCase, database) => { 157 const createBooksStore = (testCase, database) => {
138 const store = database.createObjectStore('books', 158 const store = database.createObjectStore('books',
139 { keyPath: 'isbn', autoIncrement: true }); 159 { keyPath: 'isbn', autoIncrement: true });
140 store.createIndex('by_author', 'author'); 160 store.createIndex('by_author', 'author');
141 store.createIndex('by_title', 'title', { unique: true }); 161 store.createIndex('by_title', 'title', { unique: true });
142 for (let record of BOOKS_RECORD_DATA) 162 for (let record of BOOKS_RECORD_DATA)
143 store.put(record); 163 store.put(record);
144 return store; 164 return store;
145 }; 165 }
146 166
147 // Creates a 'not_books' object store used to test renaming into existing or 167 // Creates a 'not_books' object store used to test renaming into existing or
148 // deleted store names. 168 // deleted store names.
149 const createNotBooksStore = (testCase, database) => { 169 function createNotBooksStore(testCase, database) {
150 const store = database.createObjectStore('not_books'); 170 const store = database.createObjectStore('not_books');
151 store.createIndex('not_by_author', 'author'); 171 store.createIndex('not_by_author', 'author');
152 store.createIndex('not_by_title', 'title', { unique: true }); 172 store.createIndex('not_by_title', 'title', { unique: true });
153 return store; 173 return store;
154 }; 174 }
155 175
156 // Verifies that an object store's indexes match the indexes used to create the 176 // Verifies that an object store's indexes match the indexes used to create the
157 // books store in the test database's version 1. 177 // books store in the test database's version 1.
158 // 178 //
159 // The errorMessage is used if the assertions fail. It can state that the 179 // The errorMessage is used if the assertions fail. It can state that the
160 // IndexedDB implementation being tested is incorrect, or that the testing code 180 // IndexedDB implementation being tested is incorrect, or that the testing code
161 // is using it incorrectly. 181 // is using it incorrectly.
162 const checkStoreIndexes = (testCase, store, errorMessage) => { 182 function checkStoreIndexes (testCase, store, errorMessage) {
163 assert_array_equals( 183 assert_array_equals(
164 store.indexNames, ['by_author', 'by_title'], errorMessage); 184 store.indexNames, ['by_author', 'by_title'], errorMessage);
165 const authorIndex = store.index('by_author'); 185 const authorIndex = store.index('by_author');
166 const titleIndex = store.index('by_title'); 186 const titleIndex = store.index('by_title');
167 return Promise.all([ 187 return Promise.all([
168 checkAuthorIndexContents(testCase, authorIndex, errorMessage), 188 checkAuthorIndexContents(testCase, authorIndex, errorMessage),
169 checkTitleIndexContents(testCase, titleIndex, errorMessage), 189 checkTitleIndexContents(testCase, titleIndex, errorMessage),
170 ]); 190 ]);
171 }; 191 }
172 192
173 // Verifies that an object store's key generator is in the same state as the 193 // Verifies that an object store's key generator is in the same state as the
174 // key generator created for the books store in the test database's version 1. 194 // key generator created for the books store in the test database's version 1.
175 // 195 //
176 // The errorMessage is used if the assertions fail. It can state that the 196 // The errorMessage is used if the assertions fail. It can state that the
177 // IndexedDB implementation being tested is incorrect, or that the testing code 197 // IndexedDB implementation being tested is incorrect, or that the testing code
178 // is using it incorrectly. 198 // is using it incorrectly.
179 const checkStoreGenerator = (testCase, store, expectedKey, errorMessage) => { 199 function checkStoreGenerator(testCase, store, expectedKey, errorMessage) {
180 const request = store.put( 200 const request = store.put(
181 { title: 'Bedrock Nights ' + expectedKey, author: 'Barney' }); 201 { title: 'Bedrock Nights ' + expectedKey, author: 'Barney' });
182 const eventWatcher = requestWatcher(testCase, request); 202 const eventWatcher = requestWatcher(testCase, request);
183 return eventWatcher.wait_for('success').then(() => { 203 return eventWatcher.wait_for('success').then(() => {
184 const result = request.result; 204 const result = request.result;
185 assert_equals(result, expectedKey, errorMessage); 205 assert_equals(result, expectedKey, errorMessage);
186 }); 206 });
187 }; 207 }
188 208
189 // Verifies that an object store's contents matches the contents used to create 209 // Verifies that an object store's contents matches the contents used to create
190 // the books store in the test database's version 1. 210 // the books store in the test database's version 1.
191 // 211 //
192 // The errorMessage is used if the assertions fail. It can state that the 212 // The errorMessage is used if the assertions fail. It can state that the
193 // IndexedDB implementation being tested is incorrect, or that the testing code 213 // IndexedDB implementation being tested is incorrect, or that the testing code
194 // is using it incorrectly. 214 // is using it incorrectly.
195 const checkStoreContents = (testCase, store, errorMessage) => { 215 function checkStoreContents(testCase, store, errorMessage) {
196 const request = store.get(123456); 216 const request = store.get(123456);
197 const eventWatcher = requestWatcher(testCase, request); 217 const eventWatcher = requestWatcher(testCase, request);
198 return eventWatcher.wait_for('success').then(() => { 218 return eventWatcher.wait_for('success').then(() => {
199 const result = request.result; 219 const result = request.result;
200 assert_equals(result.isbn, BOOKS_RECORD_DATA[0].isbn, errorMessage); 220 assert_equals(result.isbn, BOOKS_RECORD_DATA[0].isbn, errorMessage);
201 assert_equals(result.author, BOOKS_RECORD_DATA[0].author, errorMessage); 221 assert_equals(result.author, BOOKS_RECORD_DATA[0].author, errorMessage);
202 assert_equals(result.title, BOOKS_RECORD_DATA[0].title, errorMessage); 222 assert_equals(result.title, BOOKS_RECORD_DATA[0].title, errorMessage);
203 }); 223 });
204 }; 224 }
205 225
206 // Verifies that index matches the 'by_author' index used to create the 226 // Verifies that index matches the 'by_author' index used to create the
207 // by_author books store in the test database's version 1. 227 // by_author books store in the test database's version 1.
208 // 228 //
209 // The errorMessage is used if the assertions fail. It can state that the 229 // The errorMessage is used if the assertions fail. It can state that the
210 // IndexedDB implementation being tested is incorrect, or that the testing code 230 // IndexedDB implementation being tested is incorrect, or that the testing code
211 // is using it incorrectly. 231 // is using it incorrectly.
212 const checkAuthorIndexContents = (testCase, index, errorMessage) => { 232 function checkAuthorIndexContents(testCase, index, errorMessage) {
213 const request = index.get(BOOKS_RECORD_DATA[2].author); 233 const request = index.get(BOOKS_RECORD_DATA[2].author);
214 const eventWatcher = requestWatcher(testCase, request); 234 const eventWatcher = requestWatcher(testCase, request);
215 return eventWatcher.wait_for('success').then(() => { 235 return eventWatcher.wait_for('success').then(() => {
216 const result = request.result; 236 const result = request.result;
217 assert_equals(result.isbn, BOOKS_RECORD_DATA[2].isbn, errorMessage); 237 assert_equals(result.isbn, BOOKS_RECORD_DATA[2].isbn, errorMessage);
218 assert_equals(result.title, BOOKS_RECORD_DATA[2].title, errorMessage); 238 assert_equals(result.title, BOOKS_RECORD_DATA[2].title, errorMessage);
219 }); 239 });
220 }; 240 }
221 241
222 // Verifies that an index matches the 'by_title' index used to create the books 242 // Verifies that an index matches the 'by_title' index used to create the books
223 // store in the test database's version 1. 243 // store in the test database's version 1.
224 // 244 //
225 // The errorMessage is used if the assertions fail. It can state that the 245 // The errorMessage is used if the assertions fail. It can state that the
226 // IndexedDB implementation being tested is incorrect, or that the testing code 246 // IndexedDB implementation being tested is incorrect, or that the testing code
227 // is using it incorrectly. 247 // is using it incorrectly.
228 const checkTitleIndexContents = (testCase, index, errorMessage) => { 248 function checkTitleIndexContents(testCase, index, errorMessage) {
229 const request = index.get(BOOKS_RECORD_DATA[2].title); 249 const request = index.get(BOOKS_RECORD_DATA[2].title);
230 const eventWatcher = requestWatcher(testCase, request); 250 const eventWatcher = requestWatcher(testCase, request);
231 return eventWatcher.wait_for('success').then(() => { 251 return eventWatcher.wait_for('success').then(() => {
232 const result = request.result; 252 const result = request.result;
233 assert_equals(result.isbn, BOOKS_RECORD_DATA[2].isbn, errorMessage); 253 assert_equals(result.isbn, BOOKS_RECORD_DATA[2].isbn, errorMessage);
234 assert_equals(result.author, BOOKS_RECORD_DATA[2].author, errorMessage); 254 assert_equals(result.author, BOOKS_RECORD_DATA[2].author, errorMessage);
235 }); 255 });
236 }; 256 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698