| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| library IndexedDB1Test; | |
| import 'package:expect/legacy/async_minitest.dart'; // ignore: deprecated_member_use | |
| 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) { | |
| idb.ObjectStore store = e.target.result.createObjectStore(storeName); | |
| expect(store, isNotNull); | |
| } | |
| late idb.Database db; | |
| return html.window.indexedDB! | |
| .deleteDatabase(dbName) | |
| .then((_) { | |
| return html.window.indexedDB!.open( | |
| dbName, | |
| version: version, | |
| onUpgradeNeeded: createObjectStore, | |
| ); | |
| }) | |
| .then((idb.Database 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(() { | |
| 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); | |
| } | |
| late 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(() { | |
| 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() { | |
| // 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('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); | |
| }); | |
| } | |
| }); | |
| } |