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 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 writeItems(Database db) { Future write(index) { var transaction = db.transaction(STORE_NAME, 'readwrite'); return transaction .objectStore(STORE_NAME) .put({'content': 'Item $index'}, index); } 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 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; cursors.listen((cursor) { lastKey = cursor.key; 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); } }