| // 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 IndexedDB4Test; |
| |
| import 'package:async_helper/async_minitest.dart'; |
| import 'dart:async'; |
| import 'dart:html' as html; |
| import 'dart:indexed_db'; |
| |
| // Test for KeyRange and Cursor. |
| |
| const String DB_NAME = 'Test4'; |
| const String STORE_NAME = 'TEST'; |
| const int VERSION = 1; |
| |
| Future<Database> createAndOpenDb() { |
| return html.window.indexedDB!.deleteDatabase(DB_NAME).then((_) { |
| return html.window.indexedDB!.open(DB_NAME, version: VERSION, |
| onUpgradeNeeded: (e) { |
| var db = e.target.result; |
| db.createObjectStore(STORE_NAME); |
| }); |
| }); |
| } |
| |
| Future<Database> writeItems(Database db) { |
| Future<Object?> write(index) { |
| var transaction = db.transaction(STORE_NAME, 'readwrite'); |
| return transaction |
| .objectStore(STORE_NAME) |
| .put({'content': 'Item $index'}, index) as Future<Object?>; |
| } |
| |
| var future = write(0); |
| for (var i = 1; i < 100; ++i) { |
| future = future.then((_) => write(i)); |
| } |
| |
| // Chain on the DB so we return it at the end. |
| return future.then((_) => db); |
| } |
| |
| Future<Database> setupDb() { |
| return createAndOpenDb().then(writeItems); |
| } |
| |
| testRange(db, range, expectedFirst, expectedLast) { |
| Transaction txn = db.transaction(STORE_NAME, 'readonly'); |
| ObjectStore objectStore = txn.objectStore(STORE_NAME); |
| var cursors = objectStore |
| .openCursor(range: range, autoAdvance: true) |
| .asBroadcastStream(); |
| |
| int lastKey = 0; |
| cursors.listen((cursor) { |
| lastKey = cursor.key as int; |
| var value = cursor.value; |
| expect(value['content'], 'Item ${cursor.key}'); |
| }); |
| |
| if (expectedFirst != null) { |
| cursors.first.then((cursor) { |
| expect(cursor.key, expectedFirst); |
| }); |
| } |
| if (expectedLast != null) { |
| cursors.last.then((cursor) { |
| expect(lastKey, expectedLast); |
| }); |
| } |
| |
| return cursors.length.then((length) { |
| if (expectedFirst == null) { |
| expect(length, 0); |
| } else { |
| expect(length, expectedLast - expectedFirst + 1); |
| } |
| }); |
| } |
| |
| main() async { |
| // Don't bother with these tests if it's unsupported. |
| // Support is tested in indexeddb_1_test |
| if (IdbFactory.supported) { |
| var db = await setupDb(); |
| test('only1', () => testRange(db, new KeyRange.only(55), 55, 55)); |
| test('only2', () => testRange(db, new KeyRange.only(100), null, null)); |
| test('only3', () => testRange(db, new KeyRange.only(-1), null, null)); |
| |
| test('lower1', () => testRange(db, new KeyRange.lowerBound(40), 40, 99)); |
| // OPTIONALS lower2() => testRange(db, new KeyRange.lowerBound(40, open: true), 41, 99); |
| test('lower2', |
| () => testRange(db, new KeyRange.lowerBound(40, true), 41, 99)); |
| // OPTIONALS lower3() => testRange(db, new KeyRange.lowerBound(40, open: false), 40, 99); |
| test('lower3', |
| () => testRange(db, new KeyRange.lowerBound(40, false), 40, 99)); |
| |
| test('upper1', () => testRange(db, new KeyRange.upperBound(40), 0, 40)); |
| // OPTIONALS upper2() => testRange(db, new KeyRange.upperBound(40, open: true), 0, 39); |
| test('upper2', |
| () => testRange(db, new KeyRange.upperBound(40, true), 0, 39)); |
| // upper3() => testRange(db, new KeyRange.upperBound(40, open: false), 0, 40); |
| test('upper3', |
| () => testRange(db, new KeyRange.upperBound(40, false), 0, 40)); |
| |
| test('bound1', () => testRange(db, new KeyRange.bound(20, 30), 20, 30)); |
| |
| test('bound2', () => testRange(db, new KeyRange.bound(-100, 200), 0, 99)); |
| |
| bound3() => |
| // OPTIONALS testRange(db, new KeyRange.bound(20, 30, upperOpen: true), |
| testRange(db, new KeyRange.bound(20, 30, false, true), 20, 29); |
| |
| bound4() => |
| // OPTIONALS testRange(db, new KeyRange.bound(20, 30, lowerOpen: true), |
| testRange(db, new KeyRange.bound(20, 30, true), 21, 30); |
| |
| bound5() => |
| // OPTIONALS testRange(db, new KeyRange.bound(20, 30, lowerOpen: true, upperOpen: true), |
| testRange(db, new KeyRange.bound(20, 30, true, true), 21, 29); |
| } |
| } |