| library IndexedDB1Test; |
| import 'package:unittest/unittest.dart'; |
| import 'package:unittest/html_individual_config.dart'; |
| import 'dart:async'; |
| import 'dart:html' as html; |
| import 'dart:math' as math; |
| import 'dart:indexed_db' as idb; |
| |
| const String STORE_NAME = 'TEST'; |
| const int VERSION = 1; |
| |
| var databaseNameIndex = 0; |
| String nextDatabaseName() { |
| return 'Test1_${databaseNameIndex++}'; |
| } |
| |
| Future testUpgrade() { |
| var dbName = nextDatabaseName(); |
| var upgraded = false; |
| |
| // Delete any existing DBs. |
| return html.window.indexedDB.deleteDatabase(dbName).then((_) { |
| |
| return html.window.indexedDB.open(dbName, version: 1, |
| onUpgradeNeeded: (e) {}); |
| }).then((db) { |
| db.close(); |
| }).then((_) { |
| return html.window.indexedDB.open(dbName, version: 2, |
| onUpgradeNeeded: (e) { |
| expect(e.oldVersion, 1); |
| expect(e.newVersion, 2); |
| upgraded = true; |
| }); |
| }).then((_) { |
| expect(upgraded, isTrue); |
| }); |
| } |
| |
| testReadWrite(key, value, matcher, |
| [dbName, storeName = STORE_NAME, version = VERSION, |
| stringifyResult = false]) => () { |
| if (dbName == null) { |
| dbName = nextDatabaseName(); |
| } |
| createObjectStore(e) { |
| var store = e.target.result.createObjectStore(storeName); |
| expect(store, isNotNull); |
| } |
| |
| var db; |
| return html.window.indexedDB.deleteDatabase(dbName).then((_) { |
| return html.window.indexedDB.open(dbName, version: version, |
| onUpgradeNeeded: createObjectStore); |
| }).then((result) { |
| db = result; |
| var transaction = db.transactionList([storeName], 'readwrite'); |
| transaction.objectStore(storeName).put(value, key); |
| return transaction.completed; |
| }).then((_) { |
| var transaction = db.transaction(storeName, 'readonly'); |
| return transaction.objectStore(storeName).getObject(key); |
| }).then((object) { |
| db.close(); |
| if (stringifyResult) { |
| // Stringify the numbers to verify that we're correctly returning ints |
| // as ints vs doubles. |
| expect(object.toString(), matcher); |
| } else { |
| expect(object, matcher); |
| } |
| }).whenComplete(() { |
| if (db != null) { |
| db.close(); |
| } |
| return html.window.indexedDB.deleteDatabase(dbName); |
| }); |
| }; |
| |
| testReadWriteTyped(key, value, matcher, |
| [dbName, String storeName = STORE_NAME, version = VERSION, |
| stringifyResult = false]) => () { |
| if (dbName == null) { |
| dbName = nextDatabaseName(); |
| } |
| void createObjectStore(e) { |
| var store = e.target.result.createObjectStore(storeName); |
| expect(store, isNotNull); |
| } |
| |
| idb.Database db; |
| // Delete any existing DBs. |
| return html.window.indexedDB.deleteDatabase(dbName).then((_) { |
| return html.window.indexedDB.open(dbName, version: version, |
| onUpgradeNeeded: createObjectStore); |
| }).then((idb.Database result) { |
| db = result; |
| idb.Transaction transaction = db.transactionList([storeName], 'readwrite'); |
| transaction.objectStore(storeName).put(value, key); |
| |
| return transaction.completed; |
| }).then((idb.Database result) { |
| idb.Transaction transaction = db.transaction(storeName, 'readonly'); |
| return transaction.objectStore(storeName).getObject(key); |
| }).then((object) { |
| db.close(); |
| if (stringifyResult) { |
| // Stringify the numbers to verify that we're correctly returning ints |
| // as ints vs doubles. |
| expect(object.toString(), matcher); |
| } else { |
| expect(object, matcher); |
| } |
| }).whenComplete(() { |
| if (db != null) { |
| db.close(); |
| } |
| return html.window.indexedDB.deleteDatabase(dbName); |
| }); |
| }; |
| |
| void testTypes(testFunction) { |
| test('String', testFunction(123, 'Hoot!', equals('Hoot!'))); |
| test('int', testFunction(123, 12345, equals(12345))); |
| test('List', testFunction(123, [1, 2, 3], equals([1, 2, 3]))); |
| test('List 2', testFunction(123, [2, 3, 4], equals([2, 3, 4]))); |
| test('bool', testFunction(123, [true, false], equals([true, false]))); |
| test('largeInt', testFunction(123, 1371854424211, |
| equals("1371854424211"), null, STORE_NAME, VERSION, true)); |
| test('largeDoubleConvertedToInt', testFunction(123, 1371854424211.0, |
| equals("1371854424211"), null, STORE_NAME, VERSION, true)); |
| test('largeIntInMap', testFunction(123, {'time': 4503599627370492}, |
| equals("{time: 4503599627370492}"), null, STORE_NAME, VERSION, true)); |
| var now = new DateTime.now(); |
| test('DateTime', testFunction(123, now, |
| predicate((date) => |
| date.millisecondsSinceEpoch == now.millisecondsSinceEpoch))); |
| } |
| |
| main() { |
| useHtmlIndividualConfiguration(); |
| |
| // Test that indexed_db is properly flagged as supported or not. |
| // Note that the rest of the indexed_db tests assume that this has been |
| // checked. |
| group('supported', () { |
| test('supported', () { |
| expect(idb.IdbFactory.supported, true); |
| }); |
| }); |
| |
| group('supportsDatabaseNames', () { |
| test('supported', () { |
| expect(html.window.indexedDB.supportsDatabaseNames, isTrue); |
| }); |
| }); |
| |
| group('functional', () { |
| test('throws when unsupported', () { |
| var expectation = idb.IdbFactory.supported ? returnsNormally : throws; |
| |
| expect(() { |
| var db = html.window.indexedDB; |
| db.open('random_db'); |
| }, expectation); |
| }); |
| |
| // Don't bother with these tests if it's unsupported. |
| if (idb.IdbFactory.supported) { |
| test('upgrade', testUpgrade); |
| group('dynamic', () { |
| testTypes(testReadWrite); |
| }); |
| group('typed', () { |
| testTypes(testReadWriteTyped); |
| }); |
| } |
| }); |
| } |