Update indexeddb tests to work with both methods of upgrading a database.

The 'unpgradeNeeded' method is standard and supported by FireFox and Chrome tip.
The 'setVersions' method will be needed until Chrome Stable is Chrome 24.

The tests work locally for FireFox 15 provided they are run from a http:// URL. Running from a file:// URL disables IndexedDB for security reasons.

Review URL: https://codereview.chromium.org//11052023

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@13271 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
sra@google.com
2012-10-05 04:24:39 +00:00
parent d20462a58b
commit d4bc3be9f9
5 changed files with 215 additions and 119 deletions
+4 -5
View File
@@ -120,7 +120,6 @@ indexeddb_1_test: Fail # indexedDB not in Safari 6.
indexeddb_2_test: Fail # indexedDB not in Safari 6.
indexeddb_3_test: Fail # indexedDB not in Safari 6.
indexeddb_4_test: Fail # indexedDB not in Safari 6.
indexeddb_1_test: Fail # indexedDB not in Safari 6.
fileapi_test: Fail # requestFileSystem not supported in Safari 6.
datalistelement_test: Fail # HTMLDataListElement not yet supported in Safari.
contentelement_test: Fail # Safari 6 does not support content element.
@@ -163,10 +162,10 @@ documentfragment_test: Fail
element_test: Fail
exceptions_test: Fail # Uses webkitotifications, no analogue in moz
fileapi_test: Fail # FF does not support filesystem APIs.
indexeddb_1_test: Fail # Need window.mozIndexedDB instead of window.webkitIndexedDB
indexeddb_2_test: Fail # Need window.mozIndexedDB instead of window.webkitIndexedDB
indexeddb_3_test: Fail # Need window.mozIndexedDB instead of window.webkitIndexedDB
indexeddb_4_test: Fail # Need window.mozIndexedDB instead of window.webkitIndexedDB
indexeddb_1_test: Fail # FF disables indexedDB from file URLs.
indexeddb_2_test: Fail # FF disables indexedDB from file URLs.
indexeddb_3_test: Fail # FF disables indexedDB from file URLs.
indexeddb_4_test: Fail # FF disables indexedDB from file URLs.
# setup code fails. prepare. (DOM callback has errors) Caught [object Event]
inner_frame_test: Skip
# Interfaces not implemented: SVGTests, SVGLangSpace, SVGExternalResourcesRequired, SVGStylable
+59 -26
View File
@@ -5,7 +5,7 @@
const String DB_NAME = 'Test';
const String STORE_NAME = 'TEST';
const String VERSION = '1';
const int VERSION = 1;
testReadWrite(key, value, check,
[dbName = DB_NAME,
@@ -15,13 +15,13 @@ testReadWrite(key, value, check,
fail(e) {
guardAsync(() {
Expect.fail('IndexedDB failure');
throw const Exception('IndexedDB failure');
});
}
createObjectStore() {
createObjectStore(db) {
var store = db.createObjectStore(storeName);
Expect.isNotNull(store);
expect(store, isNotNull);
}
step2(e) {
@@ -29,6 +29,7 @@ testReadWrite(key, value, check,
var request = transaction.objectStore(storeName).getObject(key);
request.on.success.add(expectAsync1((e) {
var object = e.target.result;
db.close();
check(value, object);
}));
request.on.error.add(fail);
@@ -44,14 +45,11 @@ testReadWrite(key, value, check,
initDb(e) {
db = e.target.result;
if (version != db.version) {
// TODO. Some browsers do this the w3 way - passing the version to the
// open call and listening to onversionchange. Can we feature-detect the
// difference and make it work?
var request = db.setVersion(version);
// Legacy 'setVersion' upgrade protocol. Chrome 23 and earlier.
var request = db.setVersion('$version');
request.on.success.add(
expectAsync1((e) {
createObjectStore();
createObjectStore(db);
var transaction = e.target.result;
transaction.on.complete.add(expectAsync1((e) => step1()));
transaction.on.error.add(fail);
@@ -63,10 +61,26 @@ testReadWrite(key, value, check,
}
}
var request = window.indexedDB.open(dbName);
Expect.isNotNull(request);
request.on.success.add(expectAsync1(initDb));
request.on.error.add(fail);
openDb(e) {
var request = window.indexedDB.open(dbName, version);
expect(request, isNotNull);
request.on.success.add(expectAsync1(initDb));
request.on.error.add(fail);
if (request is IDBOpenDBRequest) {
// New upgrade protocol. Old API has no 'upgradeNeeded' and uses
// setVersion instead. This path take by FireFox 15, Chrome 24.
request.on.upgradeNeeded.add((e) {
guardAsync(() {
createObjectStore(e.target.result);
});
});
}
}
// Delete any existing DB.
var deleteRequest = window.indexedDB.deleteDatabase(dbName);
deleteRequest.on.success.add(expectAsync1(openDb));
deleteRequest.on.error.add(fail);
};
testReadWriteTyped(key, value, check,
@@ -77,13 +91,13 @@ testReadWriteTyped(key, value, check,
fail(e) {
guardAsync(() {
Expect.fail('IndexedDB failure');
throw const Exception('IndexedDB failure');
});
}
createObjectStore() {
createObjectStore(db) {
IDBObjectStore store = db.createObjectStore(storeName);
Expect.isNotNull(store);
expect(store, isNotNull);
}
step2(e) {
@@ -91,14 +105,14 @@ testReadWriteTyped(key, value, check,
IDBRequest request = transaction.objectStore(storeName).getObject(key);
request.on.success.add(expectAsync1((e) {
var object = e.target.result;
db.close();
check(value, object);
}));
request.on.error.add(fail);
}
step1() {
IDBTransaction transaction =
db.transaction([storeName], 'readwrite');
IDBTransaction transaction = db.transaction([storeName], 'readwrite');
IDBRequest request = transaction.objectStore(storeName).put(value, key);
request.on.success.add(expectAsync1(step2));
request.on.error.add(fail);
@@ -107,11 +121,14 @@ testReadWriteTyped(key, value, check,
initDb(e) {
db = e.target.result;
if (version != db.version) {
IDBRequest request = db.setVersion(version);
// Legacy 'setVersion' upgrade protocol.
IDBRequest request = db.setVersion('$version');
request.on.success.add(
expectAsync1((e) {
createObjectStore();
step1();
createObjectStore(db);
IDBTransaction transaction = e.target.result;
transaction.on.complete.add(expectAsync1((e) => step1()));
transaction.on.error.add(fail);
})
);
request.on.error.add(fail);
@@ -120,10 +137,26 @@ testReadWriteTyped(key, value, check,
}
}
IDBRequest request = window.indexedDB.open(dbName);
Expect.isNotNull(request);
request.on.success.add(expectAsync1(initDb));
request.on.error.add(fail);
openDb(e) {
IDBRequest request = window.indexedDB.open(dbName, version);
expect(request, isNotNull);
request.on.success.add(expectAsync1(initDb));
request.on.error.add(fail);
if (request is IDBOpenDBRequest) {
// New upgrade protocol. Old API has no 'upgradeNeeded' and uses
// setVersion instead.
request.on.upgradeNeeded.add((e) {
guardAsync(() {
createObjectStore(e.target.result);
});
});
}
}
// Delete any existing DB.
IDBRequest deleteRequest = window.indexedDB.deleteDatabase(dbName);
deleteRequest.on.success.add(expectAsync1(openDb));
deleteRequest.on.error.add(fail);
};
tests_dynamic() {
+32 -20
View File
@@ -9,7 +9,7 @@
const String DB_NAME = 'Test';
const String STORE_NAME = 'TEST';
const String VERSION = '1';
const int VERSION = 1;
testReadWrite(key, value, check,
[dbName = DB_NAME,
@@ -19,23 +19,23 @@ testReadWrite(key, value, check,
fail(e) {
guardAsync(() {
Expect.fail('IndexedDB failure');
throw const Exception('IndexedDB failure');
});
}
createObjectStore() {
createObjectStore(db) {
var store = db.createObjectStore(storeName);
Expect.isNotNull(store);
expect(store, isNotNull);
}
step2(e) {
var transaction = db.transaction(storeName, 'readonly');
var request = transaction.objectStore(storeName).getObject(key);
request.on.success.add(expectAsync1((e) {
var object = e.target.result;
check(value, object);
})
);
var object = e.target.result;
db.close();
check(value, object);
}));
request.on.error.add(fail);
}
@@ -49,14 +49,11 @@ testReadWrite(key, value, check,
initDb(e) {
db = e.target.result;
if (version != db.version) {
// TODO. Some browsers do this the w3 way - passing the version to the
// open call and listening to onversionchange. Can we feature-detect the
// difference and make it work?
var request = db.setVersion(version);
// Legacy 'setVersion' upgrade protocol.
var request = db.setVersion('$version');
request.on.success.add(
expectAsync1((e) {
createObjectStore();
createObjectStore(db);
var transaction = e.target.result;
transaction.on.complete.add(expectAsync1((e) => step1()));
transaction.on.error.add(fail);
@@ -68,10 +65,26 @@ testReadWrite(key, value, check,
}
}
var request = window.indexedDB.open(dbName);
Expect.isNotNull(request);
request.on.success.add(expectAsync1(initDb));
request.on.error.add(fail);
openDb(e) {
var request = window.indexedDB.open(dbName, version);
expect(request, isNotNull);
request.on.success.add(expectAsync1(initDb));
request.on.error.add(fail);
if (request is IDBOpenDBRequest) {
// New upgrade protocol. Old API has no 'upgradeNeeded' and uses
// setVersion instead.
request.on.upgradeNeeded.add((e) {
guardAsync(() {
createObjectStore(e.target.result);
});
});
}
}
// Delete any existing DB.
var deleteRequest = window.indexedDB.deleteDatabase(dbName);
deleteRequest.on.success.add(expectAsync1(openDb));
deleteRequest.on.error.add(fail);
};
@@ -96,7 +109,6 @@ main() {
test('test_verifyGraph', () {
// Nice to know verifyGraph is working before we rely on it.
Expect.mapEquals(obj4, obj4);
verifyGraph(obj4, obj4);
verifyGraph(obj1, new Map.from(obj1));
verifyGraph(obj4, new Map.from(obj4));
@@ -104,7 +116,7 @@ main() {
var l1 = [1,2,3];
var l2 = [const [1, 2, 3], const [1, 2, 3]];
verifyGraph([l1, l1], l2);
Expect.throws(() => verifyGraph([[1, 2, 3], [1, 2, 3]], l2));
expect(() => verifyGraph([[1, 2, 3], [1, 2, 3]], l2), throws);
verifyGraph(cyclic_list, cyclic_list);
});
+59 -32
View File
@@ -7,38 +7,68 @@
const String DB_NAME = 'Test';
const String STORE_NAME = 'TEST';
const String VERSION = '1';
const int VERSION = 1;
class Test {
var db;
fail(message) => (e) {
guardAsync(() {
Expect.fail('IndexedDB failure: $message');
});
};
start() {
var request = window.indexedDB.open(DB_NAME);
Expect.isNotNull(request);
request.on.success.add(expectAsync1(initDb));
request.on.error.add(fail('open'));
_createObjectStore(db) {
try {
// Nuke object store if it already exists.
db.deleteObjectStore(STORE_NAME);
}
on IDBDatabaseException catch(e) { } // Chrome
on DOMException catch(e) { } // Firefox
db.createObjectStore(STORE_NAME);
}
initDb(e) {
db = e.target.result;
// TODO. Some browsers do this the w3 way - passing the VERSION to the
// open call and listening to onversionchange. Can we feature-detect the
// difference and make it work?
var request = db.setVersion(VERSION);
request.on.success.add(
expectAsync1((e) {
try {
// Nuke object store if it already exists.
db.deleteObjectStore(STORE_NAME);
} on IDBDatabaseException catch(e) { }
db.createObjectStore(STORE_NAME);
var db;
var transaction = e.target.result;
transaction.on.complete.add(expectAsync1((e) => writeItems(0)));
transaction.on.error.add(fail);
})
);
request.on.error.add(fail('setVersion error'));
_openDb(afterOpen()) {
var request = window.indexedDB.open(DB_NAME, VERSION);
if (request is IDBOpenDBRequest) {
// New upgrade protocol. FireFox 15, Chrome 24, hopefully IE10.
request.on.success.add(expectAsync1((e) {
db = e.target.result;
afterOpen();
}));
request.on.upgradeNeeded.add((e) {
guardAsync(() {
_createObjectStore(e.target.result);
});
});
request.on.error.add(fail('open'));
} else {
// Legacy setVersion upgrade protocol. Chrome < 23.
request.on.success.add(expectAsync1((e) {
db = e.target.result;
if (db.version != '$VERSION') {
var setRequest = db.setVersion('$VERSION');
setRequest.on.success.add(
expectAsync1((e) {
_createObjectStore(db);
var transaction = e.target.result;
transaction.on.complete.add(
expectAsync1((e) => afterOpen()));
transaction.on.error.add(fail('Upgrade'));
}));
setRequest.on.error.add(fail('setVersion error'));
} else {
afterOpen();
}
}));
request.on.error.add(fail('open'));
}
}
_createAndOpenDb(afterOpen()) {
var request = window.indexedDB.deleteDatabase(DB_NAME);
request.on.success.add(expectAsync1((e) { _openDb(afterOpen); }));
request.on.error.add(fail('delete old Db'));
}
writeItems(int index) {
@@ -54,11 +84,7 @@ class Test {
}
}
fail(message) => (e) {
guardAsync(() {
Expect.fail('IndexedDB failure: $message');
});
};
setupDb() { _createAndOpenDb(() => writeItems(0)); }
readAllViaCursor() {
IDBTransaction txn = db.transaction(STORE_NAME, 'readonly');
@@ -73,6 +99,7 @@ class Test {
lastKey = cursor.key;
itemCount += 1;
sumKeys += cursor.key;
window.console.log('${cursor.key} ${cursor.value}');
Expect.equals('Item ${cursor.key}', cursor.value);
cursor.continueFunction();
} else {
@@ -116,7 +143,7 @@ main() {
useHtmlConfiguration();
var test_ = new Test();
test('prepare', test_.start);
test('prepare', test_.setupDb);
test('readAll1', test_.readAllViaCursor);
test('readAll2', test_.readAllReversedViaCursor);
}
+61 -36
View File
@@ -7,38 +7,68 @@
const String DB_NAME = 'Test';
const String STORE_NAME = 'TEST';
const String VERSION = '1';
const int VERSION = 1;
class Test {
var db;
fail(message) => (e) {
guardAsync(() {
Expect.fail('IndexedDB failure: $message');
});
};
start() {
var request = window.indexedDB.open(DB_NAME);
Expect.isNotNull(request);
request.on.success.add(expectAsync1(initDb));
request.on.error.add(fail('open'));
_createObjectStore(db) {
try {
// Nuke object store if it already exists.
db.deleteObjectStore(STORE_NAME);
}
on IDBDatabaseException catch(e) { } // Chrome
on DOMException catch(e) { } // Firefox
db.createObjectStore(STORE_NAME);
}
initDb(e) {
db = e.target.result;
// TODO. Some browsers do this the w3 way - passing the VERSION to the
// open call and listening to onversionchange. Can we feature-detect the
// difference and make it work?
var request = db.setVersion(VERSION);
request.on.success.add(
expectAsync1((e) {
try {
// Nuke object store if it already exists.
db.deleteObjectStore(STORE_NAME);
} on IDBDatabaseException catch (e) { }
db.createObjectStore(STORE_NAME);
var db;
var transaction = e.target.result;
transaction.on.complete.add(expectAsync1((e) => writeItems(0)));
transaction.on.error.add(fail);
})
);
request.on.error.add(fail('setVersion error'));
_openDb(afterOpen()) {
var request = window.indexedDB.open(DB_NAME, VERSION);
if (request is IDBOpenDBRequest) {
// New upgrade protocol.
request.on.success.add(expectAsync1((e) {
db = e.target.result;
afterOpen();
}));
request.on.upgradeNeeded.add((e) {
guardAsync(() {
_createObjectStore(e.target.result);
});
});
request.on.error.add(fail('open'));
} else {
// Legacy setVersion upgrade protocol.
request.on.success.add(expectAsync1((e) {
db = e.target.result;
if (db.version != '$VERSION') {
var setRequest = db.setVersion('$VERSION');
setRequest.on.success.add(
expectAsync1((e) {
_createObjectStore(db);
var transaction = e.target.result;
transaction.on.complete.add(
expectAsync1((e) => afterOpen()));
transaction.on.error.add(fail('Upgrade'));
}));
setRequest.on.error.add(fail('setVersion error'));
} else {
afterOpen();
}
}));
request.on.error.add(fail('open'));
}
}
_createAndOpenDb(afterOpen()) {
var request = window.indexedDB.deleteDatabase(DB_NAME);
request.on.success.add(expectAsync1((e) { _openDb(afterOpen); }));
request.on.error.add(fail('delete old Db'));
}
writeItems(int index) {
@@ -46,20 +76,15 @@ class Test {
var transaction = db.transaction([STORE_NAME], 'readwrite');
var request = transaction.objectStore(STORE_NAME)
.put('Item $index', index);
request.on.success.add(
expectAsync1((e) {
request.on.success.add(expectAsync1((e) {
writeItems(index + 1);
})
);
}
));
request.on.error.add(fail('put'));
}
}
fail(message) => (e) {
guardAsync(() {
Expect.fail('IndexedDB failure: $message');
});
};
setupDb() { _createAndOpenDb(() => writeItems(0)); }
testRange(range, expectedFirst, expectedLast) {
IDBTransaction txn = db.transaction(STORE_NAME, 'readonly');
@@ -126,7 +151,7 @@ main() {
useHtmlConfiguration();
var test_ = new Test();
test('prepare', test_.start);
test('prepare', test_.setupDb);
test('only1', test_.only1);
test('only2', test_.only2);