| OLD | NEW |
| 1 library IndexedDB3Test; | 1 library IndexedDB3Test; |
| 2 import '../../pkg/unittest/lib/unittest.dart'; | 2 import '../../pkg/unittest/lib/unittest.dart'; |
| 3 import '../../pkg/unittest/lib/html_config.dart'; | 3 import '../../pkg/unittest/lib/html_config.dart'; |
| 4 import 'dart:html'; | 4 import 'dart:async'; |
| 5 import 'dart:html' as html; |
| 5 import 'dart:indexed_db'; | 6 import 'dart:indexed_db'; |
| 7 import 'utils.dart'; |
| 6 | 8 |
| 7 // Read with cursor. | 9 // Read with cursor. |
| 8 | 10 |
| 9 const String DB_NAME = 'Test'; | 11 const String DB_NAME = 'Test'; |
| 10 const String STORE_NAME = 'TEST'; | 12 const String STORE_NAME = 'TEST'; |
| 11 const int VERSION = 1; | 13 const int VERSION = 1; |
| 12 | 14 |
| 13 class Test { | |
| 14 fail(message) => (e) { | |
| 15 guardAsync(() { | |
| 16 expect(false, isTrue, reason: 'IndexedDB failure: $message'); | |
| 17 }); | |
| 18 }; | |
| 19 | 15 |
| 20 _createObjectStore(db) { | 16 Future<Database> createAndOpenDb() { |
| 21 try { | 17 return html.window.indexedDB.deleteDatabase(DB_NAME).then((_) { |
| 22 // Nuke object store if it already exists. | 18 return html.window.indexedDB.open(DB_NAME, version: VERSION, |
| 23 db.deleteObjectStore(STORE_NAME); | 19 onUpgradeNeeded: (e) { |
| 24 } | 20 var db = e.target.result; |
| 25 // TODO: | 21 db.createObjectStore(STORE_NAME); |
| 26 //on DomException catch(e) { } // Chrome and Firefox | 22 }); |
| 27 catch(e) { } // Chrome and Firefox | 23 }); |
| 28 db.createObjectStore(STORE_NAME); | 24 } |
| 25 |
| 26 Future<Database> writeItems(Database db) { |
| 27 Future<Object> write(index) { |
| 28 var transaction = db.transaction([STORE_NAME], 'readwrite'); |
| 29 return transaction.objectStore(STORE_NAME).put('Item $index', index); |
| 29 } | 30 } |
| 30 | 31 |
| 31 var db; | 32 var future = write(0); |
| 32 | 33 for (var i = 1; i < 100; ++i) { |
| 33 _openDb(afterOpen()) { | 34 future = future.then((_) => write(i)); |
| 34 var request = window.indexedDB.open(DB_NAME, VERSION); | |
| 35 if (request is OpenDBRequest) { | |
| 36 // New upgrade protocol. FireFox 15, Chrome 24, hopefully IE10. | |
| 37 request.onSuccess.listen(expectAsync1((e) { | |
| 38 db = e.target.result; | |
| 39 afterOpen(); | |
| 40 })); | |
| 41 request.onUpgradeNeeded.listen((e) { | |
| 42 guardAsync(() { | |
| 43 _createObjectStore(e.target.result); | |
| 44 }); | |
| 45 }); | |
| 46 request.onError.listen(fail('open')); | |
| 47 } else { | |
| 48 // Legacy setVersion upgrade protocol. Chrome < 23. | |
| 49 request.onSuccess.listen(expectAsync1((e) { | |
| 50 db = e.target.result; | |
| 51 if (db.version != '$VERSION') { | |
| 52 var setRequest = db.setVersion('$VERSION'); | |
| 53 setRequest.onSuccess.listen( | |
| 54 expectAsync1((e) { | |
| 55 _createObjectStore(db); | |
| 56 var transaction = e.target.result; | |
| 57 transaction.onComplete.listen( | |
| 58 expectAsync1((e) => afterOpen())); | |
| 59 transaction.onError.listen(fail('Upgrade')); | |
| 60 })); | |
| 61 setRequest.onError.listen(fail('setVersion error')); | |
| 62 } else { | |
| 63 afterOpen(); | |
| 64 } | |
| 65 })); | |
| 66 request.onError.listen(fail('open')); | |
| 67 } | |
| 68 } | 35 } |
| 69 | 36 |
| 70 _createAndOpenDb(afterOpen()) { | 37 // Chain on the DB so we return it at the end. |
| 71 var request = window.indexedDB.deleteDatabase(DB_NAME); | 38 return future.then((_) => db); |
| 72 request.onSuccess.listen(expectAsync1((e) { _openDb(afterOpen); })); | 39 } |
| 73 request.onError.listen(fail('delete old Db')); | |
| 74 } | |
| 75 | 40 |
| 76 writeItems(int index) { | 41 Future<Database> setupDb() { |
| 77 if (index < 100) { | 42 return createAndOpenDb().then(writeItems); |
| 78 var transaction = db.transaction([STORE_NAME], 'readwrite'); | 43 } |
| 79 var request = transaction.objectStore(STORE_NAME) | |
| 80 .put('Item $index', index); | |
| 81 request.onSuccess.listen(expectAsync1((e) { | |
| 82 writeItems(index + 1); | |
| 83 } | |
| 84 )); | |
| 85 request.onError.listen(fail('put')); | |
| 86 } | |
| 87 } | |
| 88 | 44 |
| 89 setupDb() { _createAndOpenDb(() => writeItems(0)); } | 45 Future<Database> readAllViaCursor(Database db) { |
| 46 Transaction txn = db.transaction(STORE_NAME, 'readonly'); |
| 47 ObjectStore objectStore = txn.objectStore(STORE_NAME); |
| 48 int itemCount = 0; |
| 49 int sumKeys = 0; |
| 90 | 50 |
| 91 readAllViaCursor() { | 51 var cursors = objectStore.openCursor().asBroadcastStream(); |
| 92 Transaction txn = db.transaction(STORE_NAME, 'readonly'); | 52 cursors.listen( |
| 93 ObjectStore objectStore = txn.objectStore(STORE_NAME); | 53 (cursor) { |
| 94 Request cursorRequest = objectStore.openCursor(); | 54 ++itemCount; |
| 95 int itemCount = 0; | 55 sumKeys += cursor.key; |
| 96 int sumKeys = 0; | 56 expect(cursor.value, 'Item ${cursor.key}'); |
| 97 int lastKey = null; | 57 cursor.next(); |
| 98 cursorRequest.onSuccess.listen(expectAsync1((e) { | 58 }); |
| 99 var cursor = e.target.result; | 59 cursors.last.then( |
| 100 if (cursor != null) { | 60 (cursor) { |
| 101 lastKey = cursor.key; | 61 expect(cursor.key, 99); |
| 102 itemCount += 1; | 62 expect(sumKeys, (100 * 99) ~/ 2); |
| 103 sumKeys += cursor.key; | 63 expect(itemCount, 100); |
| 104 window.console.log('${cursor.key} ${cursor.value}'); | 64 }); |
| 105 expect(cursor.value, 'Item ${cursor.key}'); | |
| 106 cursor.continueFunction(); | |
| 107 } else { | |
| 108 // Done | |
| 109 expect(lastKey, 99); | |
| 110 expect(itemCount, 100); | |
| 111 expect(sumKeys, (100 * 99) ~/ 2); | |
| 112 } | |
| 113 }, count:101)); | |
| 114 cursorRequest.onError.listen(fail('openCursor')); | |
| 115 } | |
| 116 | 65 |
| 117 readAllReversedViaCursor() { | 66 return cursors.last.then((_) => db); |
| 118 Transaction txn = db.transaction(STORE_NAME, 'readonly'); | 67 } |
| 119 ObjectStore objectStore = txn.objectStore(STORE_NAME); | 68 |
| 120 // TODO: create a KeyRange(0,100) | 69 Future<Database> readAllReversedViaCursor(Database db) { |
| 121 Request cursorRequest = objectStore.openCursor(null, 'prev'); | 70 Transaction txn = db.transaction(STORE_NAME, 'readonly'); |
| 122 int itemCount = 0; | 71 ObjectStore objectStore = txn.objectStore(STORE_NAME); |
| 123 int sumKeys = 0; | 72 int itemCount = 0; |
| 124 int lastKey = null; | 73 int sumKeys = 0; |
| 125 cursorRequest.onSuccess.listen(expectAsync1((e) { | 74 |
| 126 var cursor = e.target.result; | 75 var cursors = objectStore.openCursor(direction: 'prev').asBroadcastStream(); |
| 127 if (cursor != null) { | 76 cursors.listen( |
| 128 lastKey = cursor.key; | 77 (cursor) { |
| 129 itemCount += 1; | 78 ++itemCount; |
| 130 sumKeys += cursor.key; | 79 sumKeys += cursor.key; |
| 131 expect(cursor.value, 'Item ${cursor.key}'); | 80 expect(cursor.value, 'Item ${cursor.key}'); |
| 132 cursor.continueFunction(); | 81 cursor.next(); |
| 133 } else { | 82 }); |
| 134 // Done | 83 cursors.last.then( |
| 135 expect(lastKey, 0); // i.e. first key (scanned in reverse). | 84 (cursor) { |
| 136 expect(itemCount, 100); | 85 expect(cursor.key, 0); |
| 137 expect(sumKeys, (100 * 99) ~/ 2); | 86 expect(sumKeys, (100 * 99) ~/ 2); |
| 138 } | 87 expect(itemCount, 100); |
| 139 }, count:101)); | 88 }); |
| 140 cursorRequest.onError.listen(fail('openCursor')); | 89 return cursors.last.then((_) => db); |
| 141 } | |
| 142 } | 90 } |
| 143 | 91 |
| 144 main() { | 92 main() { |
| 145 useHtmlConfiguration(); | 93 useHtmlConfiguration(); |
| 146 | 94 |
| 147 // Don't bother with these tests if it's unsupported. | 95 // Don't bother with these tests if it's unsupported. |
| 148 // Support is tested in indexeddb_1_test | 96 // Support is tested in indexeddb_1_test |
| 149 if (IdbFactory.supported) { | 97 if (IdbFactory.supported) { |
| 150 var test_ = new Test(); | 98 var db; |
| 151 test('prepare', test_.setupDb); | 99 futureTest('prepare', () { |
| 152 test('readAll1', test_.readAllViaCursor); | 100 return setupDb().then((result) { db = result; }); |
| 153 test('readAll2', test_.readAllReversedViaCursor); | 101 }); |
| 102 futureTest('readAll1', () { |
| 103 return readAllViaCursor(db); |
| 104 }); |
| 105 |
| 106 futureTest('readAll2', () { |
| 107 return readAllReversedViaCursor(db); |
| 108 }); |
| 154 } | 109 } |
| 155 } | 110 } |
| OLD | NEW |