1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/indexedDB/test/unit/test_lowDiskSpace.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,737 @@ 1.4 +/** 1.5 + * Any copyright is dedicated to the Public Domain. 1.6 + * http://creativecommons.org/publicdomain/zero/1.0/ 1.7 + */ 1.8 +"use strict"; 1.9 + 1.10 +var self = this; 1.11 + 1.12 +var testGenerator = testSteps(); 1.13 + 1.14 +function testSteps() 1.15 +{ 1.16 + const dbName = self.window ? window.location.pathname : "test_lowDiskSpace"; 1.17 + const dbVersion = 1; 1.18 + 1.19 + const objectStoreName = "foo"; 1.20 + const objectStoreOptions = { keyPath: "foo" }; 1.21 + 1.22 + const indexName = "bar"; 1.23 + const indexOptions = { unique: true }; 1.24 + 1.25 + const dbData = [ 1.26 + { foo: 0, bar: 0 }, 1.27 + { foo: 1, bar: 10 }, 1.28 + { foo: 2, bar: 20 }, 1.29 + { foo: 3, bar: 30 }, 1.30 + { foo: 4, bar: 40 }, 1.31 + { foo: 5, bar: 50 }, 1.32 + { foo: 6, bar: 60 }, 1.33 + { foo: 7, bar: 70 }, 1.34 + { foo: 8, bar: 80 }, 1.35 + { foo: 9, bar: 90 } 1.36 + ]; 1.37 + 1.38 + let lowDiskMode = false; 1.39 + function setLowDiskMode(val) { 1.40 + let data = val ? "full" : "free"; 1.41 + 1.42 + if (val == lowDiskMode) { 1.43 + info("Low disk mode is: " + data); 1.44 + } 1.45 + else { 1.46 + info("Changing low disk mode to: " + data); 1.47 + SpecialPowers.notifyObserversInParentProcess(null, "disk-space-watcher", 1.48 + data); 1.49 + lowDiskMode = val; 1.50 + } 1.51 + } 1.52 + 1.53 + { // Make sure opening works from the beginning. 1.54 + info("Test 1"); 1.55 + 1.56 + setLowDiskMode(false); 1.57 + 1.58 + let request = indexedDB.open(dbName, dbVersion); 1.59 + request.onerror = errorHandler; 1.60 + request.onsuccess = grabEventAndContinueHandler; 1.61 + let event = yield undefined; 1.62 + 1.63 + is(event.type, "success", "Opened database without setting low disk mode"); 1.64 + 1.65 + let db = event.target.result; 1.66 + db.close(); 1.67 + } 1.68 + 1.69 + { // Make sure delete works in low disk mode. 1.70 + info("Test 2"); 1.71 + 1.72 + setLowDiskMode(true); 1.73 + 1.74 + let request = indexedDB.deleteDatabase(dbName); 1.75 + request.onerror = errorHandler; 1.76 + request.onsuccess = grabEventAndContinueHandler; 1.77 + let event = yield undefined; 1.78 + 1.79 + is(event.type, "success", "Deleted database after setting low disk mode"); 1.80 + } 1.81 + 1.82 + { // Make sure creating a db in low disk mode fails. 1.83 + info("Test 3"); 1.84 + 1.85 + setLowDiskMode(true); 1.86 + 1.87 + let request = indexedDB.open(dbName, dbVersion); 1.88 + request.onerror = expectedErrorHandler("QuotaExceededError"); 1.89 + request.onupgradeneeded = unexpectedSuccessHandler; 1.90 + request.onsuccess = unexpectedSuccessHandler; 1.91 + let event = yield undefined; 1.92 + 1.93 + is(event.type, "error", "Didn't create new database in low disk mode"); 1.94 + } 1.95 + 1.96 + { // Make sure opening an already-existing db in low disk mode succeeds. 1.97 + info("Test 4"); 1.98 + 1.99 + setLowDiskMode(false); 1.100 + 1.101 + let request = indexedDB.open(dbName, dbVersion); 1.102 + request.onerror = errorHandler; 1.103 + request.onupgradeneeded = grabEventAndContinueHandler; 1.104 + request.onsuccess = unexpectedSuccessHandler; 1.105 + let event = yield undefined; 1.106 + 1.107 + is(event.type, "upgradeneeded", "Upgrading database"); 1.108 + 1.109 + let db = event.target.result; 1.110 + db.onerror = errorHandler; 1.111 + 1.112 + request.onupgradeneeded = unexpectedSuccessHandler; 1.113 + request.onsuccess = grabEventAndContinueHandler; 1.114 + event = yield undefined; 1.115 + 1.116 + is(event.type, "success", "Created database"); 1.117 + ok(event.target.result === db, "Got the same database"); 1.118 + 1.119 + db.close(); 1.120 + 1.121 + setLowDiskMode(true); 1.122 + 1.123 + request = indexedDB.open(dbName); 1.124 + request.onerror = errorHandler; 1.125 + request.onupgradeneeded = unexpectedSuccessHandler; 1.126 + request.onsuccess = grabEventAndContinueHandler; 1.127 + event = yield undefined; 1.128 + 1.129 + is(event.type, "success", "Opened existing database in low disk mode"); 1.130 + 1.131 + db = event.target.result; 1.132 + db.close(); 1.133 + } 1.134 + 1.135 + { // Make sure upgrading an already-existing db in low disk mode succeeds. 1.136 + info("Test 5"); 1.137 + 1.138 + setLowDiskMode(true); 1.139 + 1.140 + let request = indexedDB.open(dbName, dbVersion + 1); 1.141 + request.onerror = errorHandler; 1.142 + request.onupgradeneeded = grabEventAndContinueHandler; 1.143 + request.onsuccess = unexpectedSuccessHandler; 1.144 + 1.145 + let event = yield undefined; 1.146 + 1.147 + is(event.type, "upgradeneeded", "Upgrading database"); 1.148 + 1.149 + let db = event.target.result; 1.150 + db.onerror = errorHandler; 1.151 + 1.152 + request.onupgradeneeded = unexpectedSuccessHandler; 1.153 + request.onsuccess = grabEventAndContinueHandler; 1.154 + event = yield undefined; 1.155 + 1.156 + is(event.type, "success", "Created database"); 1.157 + ok(event.target.result === db, "Got the same database"); 1.158 + 1.159 + db.close(); 1.160 + } 1.161 + 1.162 + { // Make sure creating objectStores in low disk mode fails. 1.163 + info("Test 6"); 1.164 + 1.165 + setLowDiskMode(true); 1.166 + 1.167 + let request = indexedDB.open(dbName, dbVersion + 2); 1.168 + request.onerror = expectedErrorHandler("QuotaExceededError"); 1.169 + request.onupgradeneeded = grabEventAndContinueHandler; 1.170 + request.onsuccess = unexpectedSuccessHandler; 1.171 + 1.172 + let event = yield undefined; 1.173 + 1.174 + is(event.type, "upgradeneeded", "Upgrading database"); 1.175 + 1.176 + let db = event.target.result; 1.177 + db.onerror = errorHandler; 1.178 + 1.179 + let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions); 1.180 + 1.181 + request.onupgradeneeded = unexpectedSuccessHandler; 1.182 + event = yield undefined; 1.183 + 1.184 + is(event.type, "error", "Failed database upgrade"); 1.185 + } 1.186 + 1.187 + { // Make sure creating indexes in low disk mode fails. 1.188 + info("Test 7"); 1.189 + 1.190 + setLowDiskMode(false); 1.191 + 1.192 + let request = indexedDB.open(dbName, dbVersion + 2); 1.193 + request.onerror = errorHandler; 1.194 + request.onupgradeneeded = grabEventAndContinueHandler; 1.195 + request.onsuccess = unexpectedSuccessHandler; 1.196 + 1.197 + let event = yield undefined; 1.198 + 1.199 + is(event.type, "upgradeneeded", "Upgrading database"); 1.200 + 1.201 + let db = event.target.result; 1.202 + db.onerror = errorHandler; 1.203 + 1.204 + let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions); 1.205 + 1.206 + request.onupgradeneeded = unexpectedSuccessHandler; 1.207 + request.onsuccess = grabEventAndContinueHandler; 1.208 + event = yield undefined; 1.209 + 1.210 + is(event.type, "success", "Upgraded database"); 1.211 + ok(event.target.result === db, "Got the same database"); 1.212 + 1.213 + db.close(); 1.214 + 1.215 + setLowDiskMode(true); 1.216 + 1.217 + request = indexedDB.open(dbName, dbVersion + 3); 1.218 + request.onerror = expectedErrorHandler("QuotaExceededError"); 1.219 + request.onupgradeneeded = grabEventAndContinueHandler; 1.220 + request.onsuccess = unexpectedSuccessHandler; 1.221 + event = yield undefined; 1.222 + 1.223 + is(event.type, "upgradeneeded", "Upgrading database"); 1.224 + 1.225 + db = event.target.result; 1.226 + db.onerror = errorHandler; 1.227 + 1.228 + objectStore = event.target.transaction.objectStore(objectStoreName); 1.229 + let index = objectStore.createIndex(indexName, indexName, indexOptions); 1.230 + 1.231 + request.onupgradeneeded = unexpectedSuccessHandler; 1.232 + event = yield undefined; 1.233 + 1.234 + is(event.type, "error", "Failed database upgrade"); 1.235 + } 1.236 + 1.237 + { // Make sure deleting indexes in low disk mode succeeds. 1.238 + info("Test 8"); 1.239 + 1.240 + setLowDiskMode(false); 1.241 + 1.242 + let request = indexedDB.open(dbName, dbVersion + 3); 1.243 + request.onerror = errorHandler; 1.244 + request.onupgradeneeded = grabEventAndContinueHandler; 1.245 + request.onsuccess = unexpectedSuccessHandler; 1.246 + 1.247 + let event = yield undefined; 1.248 + 1.249 + is(event.type, "upgradeneeded", "Upgrading database"); 1.250 + 1.251 + let db = event.target.result; 1.252 + db.onerror = errorHandler; 1.253 + 1.254 + let objectStore = event.target.transaction.objectStore(objectStoreName); 1.255 + let index = objectStore.createIndex(indexName, indexName, indexOptions); 1.256 + 1.257 + request.onupgradeneeded = unexpectedSuccessHandler; 1.258 + request.onsuccess = grabEventAndContinueHandler; 1.259 + event = yield undefined; 1.260 + 1.261 + is(event.type, "success", "Upgraded database"); 1.262 + ok(event.target.result === db, "Got the same database"); 1.263 + 1.264 + db.close(); 1.265 + 1.266 + setLowDiskMode(true); 1.267 + 1.268 + request = indexedDB.open(dbName, dbVersion + 4); 1.269 + request.onerror = errorHandler; 1.270 + request.onupgradeneeded = grabEventAndContinueHandler; 1.271 + request.onsuccess = unexpectedSuccessHandler; 1.272 + event = yield undefined; 1.273 + 1.274 + is(event.type, "upgradeneeded", "Upgrading database"); 1.275 + 1.276 + db = event.target.result; 1.277 + db.onerror = errorHandler; 1.278 + 1.279 + objectStore = event.target.transaction.objectStore(objectStoreName); 1.280 + objectStore.deleteIndex(indexName); 1.281 + 1.282 + request.onupgradeneeded = unexpectedSuccessHandler; 1.283 + request.onsuccess = grabEventAndContinueHandler; 1.284 + event = yield undefined; 1.285 + 1.286 + is(event.type, "success", "Upgraded database"); 1.287 + ok(event.target.result === db, "Got the same database"); 1.288 + 1.289 + db.close(); 1.290 + } 1.291 + 1.292 + { // Make sure deleting objectStores in low disk mode succeeds. 1.293 + info("Test 9"); 1.294 + 1.295 + setLowDiskMode(true); 1.296 + 1.297 + let request = indexedDB.open(dbName, dbVersion + 5); 1.298 + request.onerror = errorHandler; 1.299 + request.onupgradeneeded = grabEventAndContinueHandler; 1.300 + request.onsuccess = unexpectedSuccessHandler; 1.301 + 1.302 + let event = yield undefined; 1.303 + 1.304 + is(event.type, "upgradeneeded", "Upgrading database"); 1.305 + 1.306 + let db = event.target.result; 1.307 + db.onerror = errorHandler; 1.308 + 1.309 + db.deleteObjectStore(objectStoreName); 1.310 + 1.311 + request.onupgradeneeded = unexpectedSuccessHandler; 1.312 + request.onsuccess = grabEventAndContinueHandler; 1.313 + event = yield undefined; 1.314 + 1.315 + is(event.type, "success", "Upgraded database"); 1.316 + ok(event.target.result === db, "Got the same database"); 1.317 + 1.318 + db.close(); 1.319 + 1.320 + // Reset everything. 1.321 + indexedDB.deleteDatabase(dbName); 1.322 + } 1.323 + 1.324 + 1.325 + { // Add data that the rest of the tests will use. 1.326 + info("Adding test data"); 1.327 + 1.328 + setLowDiskMode(false); 1.329 + 1.330 + let request = indexedDB.open(dbName, dbVersion); 1.331 + request.onerror = errorHandler; 1.332 + request.onupgradeneeded = grabEventAndContinueHandler; 1.333 + request.onsuccess = unexpectedSuccessHandler; 1.334 + let event = yield undefined; 1.335 + 1.336 + is(event.type, "upgradeneeded", "Upgrading database"); 1.337 + 1.338 + let db = event.target.result; 1.339 + db.onerror = errorHandler; 1.340 + 1.341 + let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions); 1.342 + let index = objectStore.createIndex(indexName, indexName, indexOptions); 1.343 + 1.344 + for each (let data in dbData) { 1.345 + objectStore.add(data); 1.346 + } 1.347 + 1.348 + request.onupgradeneeded = unexpectedSuccessHandler; 1.349 + request.onsuccess = grabEventAndContinueHandler; 1.350 + event = yield undefined; 1.351 + 1.352 + is(event.type, "success", "Upgraded database"); 1.353 + ok(event.target.result === db, "Got the same database"); 1.354 + 1.355 + db.close(); 1.356 + } 1.357 + 1.358 + { // Make sure read operations in readonly transactions succeed in low disk 1.359 + // mode. 1.360 + info("Test 10"); 1.361 + 1.362 + setLowDiskMode(true); 1.363 + 1.364 + let request = indexedDB.open(dbName, dbVersion); 1.365 + request.onerror = errorHandler; 1.366 + request.onupgradeneeded = unexpectedSuccessHandler; 1.367 + request.onsuccess = grabEventAndContinueHandler; 1.368 + let event = yield undefined; 1.369 + 1.370 + let db = event.target.result; 1.371 + db.onerror = errorHandler; 1.372 + 1.373 + let transaction = db.transaction(objectStoreName); 1.374 + let objectStore = transaction.objectStore(objectStoreName); 1.375 + let index = objectStore.index(indexName); 1.376 + 1.377 + let data = dbData[0]; 1.378 + 1.379 + let requestCounter = new RequestCounter(); 1.380 + 1.381 + objectStore.get(data.foo).onsuccess = requestCounter.handler(); 1.382 + objectStore.mozGetAll().onsuccess = requestCounter.handler(); 1.383 + objectStore.count().onsuccess = requestCounter.handler(); 1.384 + index.get(data.bar).onsuccess = requestCounter.handler(); 1.385 + index.mozGetAll().onsuccess = requestCounter.handler(); 1.386 + index.getKey(data.bar).onsuccess = requestCounter.handler(); 1.387 + index.mozGetAllKeys().onsuccess = requestCounter.handler(); 1.388 + index.count().onsuccess = requestCounter.handler(); 1.389 + 1.390 + let objectStoreDataCount = 0; 1.391 + 1.392 + request = objectStore.openCursor(); 1.393 + request.onsuccess = function(event) { 1.394 + let cursor = event.target.result; 1.395 + if (cursor) { 1.396 + objectStoreDataCount++; 1.397 + objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1); 1.398 + } 1.399 + else { 1.400 + is(objectStoreDataCount, dbData.length, "Saw all data"); 1.401 + requestCounter.decr(); 1.402 + } 1.403 + }; 1.404 + requestCounter.incr(); 1.405 + 1.406 + let indexDataCount = 0; 1.407 + 1.408 + request = index.openCursor(); 1.409 + request.onsuccess = function(event) { 1.410 + let cursor = event.target.result; 1.411 + if (cursor) { 1.412 + indexDataCount++; 1.413 + indexDataCount % 2 ? cursor.continue() : cursor.advance(1); 1.414 + } 1.415 + else { 1.416 + is(indexDataCount, dbData.length, "Saw all data"); 1.417 + requestCounter.decr(); 1.418 + } 1.419 + }; 1.420 + requestCounter.incr(); 1.421 + 1.422 + let indexKeyDataCount = 0; 1.423 + 1.424 + request = index.openCursor(); 1.425 + request.onsuccess = function(event) { 1.426 + let cursor = event.target.result; 1.427 + if (cursor) { 1.428 + indexKeyDataCount++; 1.429 + indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1); 1.430 + } 1.431 + else { 1.432 + is(indexKeyDataCount, dbData.length, "Saw all data"); 1.433 + requestCounter.decr(); 1.434 + } 1.435 + }; 1.436 + requestCounter.incr(); 1.437 + 1.438 + // Wait for all requests. 1.439 + yield undefined; 1.440 + 1.441 + transaction.oncomplete = grabEventAndContinueHandler; 1.442 + event = yield undefined; 1.443 + 1.444 + is(event.type, "complete", "Transaction succeeded"); 1.445 + 1.446 + db.close(); 1.447 + } 1.448 + 1.449 + { // Make sure read operations in readwrite transactions succeed in low disk 1.450 + // mode. 1.451 + info("Test 11"); 1.452 + 1.453 + setLowDiskMode(true); 1.454 + 1.455 + let request = indexedDB.open(dbName, dbVersion); 1.456 + request.onerror = errorHandler; 1.457 + request.onupgradeneeded = unexpectedSuccessHandler; 1.458 + request.onsuccess = grabEventAndContinueHandler; 1.459 + let event = yield undefined; 1.460 + 1.461 + let db = event.target.result; 1.462 + db.onerror = errorHandler; 1.463 + 1.464 + let transaction = db.transaction(objectStoreName, "readwrite"); 1.465 + let objectStore = transaction.objectStore(objectStoreName); 1.466 + let index = objectStore.index(indexName); 1.467 + 1.468 + let data = dbData[0]; 1.469 + 1.470 + let requestCounter = new RequestCounter(); 1.471 + 1.472 + objectStore.get(data.foo).onsuccess = requestCounter.handler(); 1.473 + objectStore.mozGetAll().onsuccess = requestCounter.handler(); 1.474 + objectStore.count().onsuccess = requestCounter.handler(); 1.475 + index.get(data.bar).onsuccess = requestCounter.handler(); 1.476 + index.mozGetAll().onsuccess = requestCounter.handler(); 1.477 + index.getKey(data.bar).onsuccess = requestCounter.handler(); 1.478 + index.mozGetAllKeys().onsuccess = requestCounter.handler(); 1.479 + index.count().onsuccess = requestCounter.handler(); 1.480 + 1.481 + let objectStoreDataCount = 0; 1.482 + 1.483 + request = objectStore.openCursor(); 1.484 + request.onsuccess = function(event) { 1.485 + let cursor = event.target.result; 1.486 + if (cursor) { 1.487 + objectStoreDataCount++; 1.488 + objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1); 1.489 + } 1.490 + else { 1.491 + is(objectStoreDataCount, dbData.length, "Saw all data"); 1.492 + requestCounter.decr(); 1.493 + } 1.494 + }; 1.495 + requestCounter.incr(); 1.496 + 1.497 + let indexDataCount = 0; 1.498 + 1.499 + request = index.openCursor(); 1.500 + request.onsuccess = function(event) { 1.501 + let cursor = event.target.result; 1.502 + if (cursor) { 1.503 + indexDataCount++; 1.504 + indexDataCount % 2 ? cursor.continue() : cursor.advance(1); 1.505 + } 1.506 + else { 1.507 + is(indexDataCount, dbData.length, "Saw all data"); 1.508 + requestCounter.decr(); 1.509 + } 1.510 + }; 1.511 + requestCounter.incr(); 1.512 + 1.513 + let indexKeyDataCount = 0; 1.514 + 1.515 + request = index.openCursor(); 1.516 + request.onsuccess = function(event) { 1.517 + let cursor = event.target.result; 1.518 + if (cursor) { 1.519 + indexKeyDataCount++; 1.520 + indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1); 1.521 + } 1.522 + else { 1.523 + is(indexKeyDataCount, dbData.length, "Saw all data"); 1.524 + requestCounter.decr(); 1.525 + } 1.526 + }; 1.527 + requestCounter.incr(); 1.528 + 1.529 + // Wait for all requests. 1.530 + yield undefined; 1.531 + 1.532 + transaction.oncomplete = grabEventAndContinueHandler; 1.533 + event = yield undefined; 1.534 + 1.535 + is(event.type, "complete", "Transaction succeeded"); 1.536 + 1.537 + db.close(); 1.538 + } 1.539 + 1.540 + { // Make sure write operations in readwrite transactions fail in low disk 1.541 + // mode. 1.542 + info("Test 12"); 1.543 + 1.544 + setLowDiskMode(true); 1.545 + 1.546 + let request = indexedDB.open(dbName, dbVersion); 1.547 + request.onerror = errorHandler; 1.548 + request.onupgradeneeded = unexpectedSuccessHandler; 1.549 + request.onsuccess = grabEventAndContinueHandler; 1.550 + let event = yield undefined; 1.551 + 1.552 + let db = event.target.result; 1.553 + db.onerror = errorHandler; 1.554 + 1.555 + let transaction = db.transaction(objectStoreName, "readwrite"); 1.556 + let objectStore = transaction.objectStore(objectStoreName); 1.557 + let index = objectStore.index(indexName); 1.558 + 1.559 + let data = dbData[0]; 1.560 + let newData = { foo: 999, bar: 999 }; 1.561 + 1.562 + let requestCounter = new RequestCounter(); 1.563 + 1.564 + objectStore.add(newData).onerror = requestCounter.errorHandler(); 1.565 + objectStore.put(newData).onerror = requestCounter.errorHandler(); 1.566 + 1.567 + objectStore.get(data.foo).onsuccess = requestCounter.handler(); 1.568 + objectStore.mozGetAll().onsuccess = requestCounter.handler(); 1.569 + objectStore.count().onsuccess = requestCounter.handler(); 1.570 + index.get(data.bar).onsuccess = requestCounter.handler(); 1.571 + index.mozGetAll().onsuccess = requestCounter.handler(); 1.572 + index.getKey(data.bar).onsuccess = requestCounter.handler(); 1.573 + index.mozGetAllKeys().onsuccess = requestCounter.handler(); 1.574 + index.count().onsuccess = requestCounter.handler(); 1.575 + 1.576 + let objectStoreDataCount = 0; 1.577 + 1.578 + request = objectStore.openCursor(); 1.579 + request.onsuccess = function(event) { 1.580 + let cursor = event.target.result; 1.581 + if (cursor) { 1.582 + objectStoreDataCount++; 1.583 + cursor.update(cursor.value).onerror = requestCounter.errorHandler(); 1.584 + objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1); 1.585 + } 1.586 + else { 1.587 + is(objectStoreDataCount, dbData.length, "Saw all data"); 1.588 + requestCounter.decr(); 1.589 + } 1.590 + }; 1.591 + requestCounter.incr(); 1.592 + 1.593 + let indexDataCount = 0; 1.594 + 1.595 + request = index.openCursor(); 1.596 + request.onsuccess = function(event) { 1.597 + let cursor = event.target.result; 1.598 + if (cursor) { 1.599 + indexDataCount++; 1.600 + cursor.update(cursor.value).onerror = requestCounter.errorHandler(); 1.601 + indexDataCount % 2 ? cursor.continue() : cursor.advance(1); 1.602 + } 1.603 + else { 1.604 + is(indexDataCount, dbData.length, "Saw all data"); 1.605 + requestCounter.decr(); 1.606 + } 1.607 + }; 1.608 + requestCounter.incr(); 1.609 + 1.610 + let indexKeyDataCount = 0; 1.611 + 1.612 + request = index.openCursor(); 1.613 + request.onsuccess = function(event) { 1.614 + let cursor = event.target.result; 1.615 + if (cursor) { 1.616 + indexKeyDataCount++; 1.617 + cursor.update(cursor.value).onerror = requestCounter.errorHandler(); 1.618 + indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1); 1.619 + } 1.620 + else { 1.621 + is(indexKeyDataCount, dbData.length, "Saw all data"); 1.622 + requestCounter.decr(); 1.623 + } 1.624 + }; 1.625 + requestCounter.incr(); 1.626 + 1.627 + // Wait for all requests. 1.628 + yield undefined; 1.629 + 1.630 + transaction.oncomplete = grabEventAndContinueHandler; 1.631 + event = yield undefined; 1.632 + 1.633 + is(event.type, "complete", "Transaction succeeded"); 1.634 + 1.635 + db.close(); 1.636 + } 1.637 + 1.638 + { // Make sure deleting operations in readwrite transactions succeed in low 1.639 + // disk mode. 1.640 + info("Test 13"); 1.641 + 1.642 + setLowDiskMode(true); 1.643 + 1.644 + let request = indexedDB.open(dbName, dbVersion); 1.645 + request.onerror = errorHandler; 1.646 + request.onupgradeneeded = unexpectedSuccessHandler; 1.647 + request.onsuccess = grabEventAndContinueHandler; 1.648 + let event = yield undefined; 1.649 + 1.650 + let db = event.target.result; 1.651 + db.onerror = errorHandler; 1.652 + 1.653 + let transaction = db.transaction(objectStoreName, "readwrite"); 1.654 + let objectStore = transaction.objectStore(objectStoreName); 1.655 + let index = objectStore.index(indexName); 1.656 + 1.657 + let dataIndex = 0; 1.658 + let data = dbData[dataIndex++]; 1.659 + 1.660 + let requestCounter = new RequestCounter(); 1.661 + 1.662 + objectStore.delete(data.foo).onsuccess = requestCounter.handler(); 1.663 + 1.664 + objectStore.openCursor().onsuccess = function(event) { 1.665 + let cursor = event.target.result; 1.666 + if (cursor) { 1.667 + cursor.delete().onsuccess = requestCounter.handler(); 1.668 + } 1.669 + requestCounter.decr(); 1.670 + }; 1.671 + requestCounter.incr(); 1.672 + 1.673 + index.openCursor(null, "prev").onsuccess = function(event) { 1.674 + let cursor = event.target.result; 1.675 + if (cursor) { 1.676 + cursor.delete().onsuccess = requestCounter.handler(); 1.677 + } 1.678 + requestCounter.decr(); 1.679 + }; 1.680 + requestCounter.incr(); 1.681 + 1.682 + yield undefined; 1.683 + 1.684 + objectStore.count().onsuccess = grabEventAndContinueHandler; 1.685 + event = yield undefined; 1.686 + 1.687 + is(event.target.result, dbData.length - 3, "Actually deleted something"); 1.688 + 1.689 + objectStore.clear(); 1.690 + objectStore.count().onsuccess = grabEventAndContinueHandler; 1.691 + event = yield undefined; 1.692 + 1.693 + is(event.target.result, 0, "Actually cleared"); 1.694 + 1.695 + transaction.oncomplete = grabEventAndContinueHandler; 1.696 + event = yield undefined; 1.697 + 1.698 + is(event.type, "complete", "Transaction succeeded"); 1.699 + 1.700 + db.close(); 1.701 + } 1.702 + 1.703 + finishTest(); 1.704 + yield undefined; 1.705 +} 1.706 + 1.707 +function RequestCounter(expectedType) { 1.708 + this._counter = 0; 1.709 +} 1.710 +RequestCounter.prototype = { 1.711 + incr: function() { 1.712 + this._counter++; 1.713 + }, 1.714 + 1.715 + decr: function() { 1.716 + if (!--this._counter) { 1.717 + continueToNextStepSync(); 1.718 + } 1.719 + }, 1.720 + 1.721 + handler: function(type, preventDefault) { 1.722 + this.incr(); 1.723 + return function(event) { 1.724 + is(event.type, type || "success", "Correct type"); 1.725 + this.decr(); 1.726 + }.bind(this); 1.727 + }, 1.728 + 1.729 + errorHandler: function(eventType, errorName) { 1.730 + this.incr(); 1.731 + return function(event) { 1.732 + is(event.type, eventType || "error", "Correct type"); 1.733 + is(event.target.error.name, errorName || "QuotaExceededError", 1.734 + "Correct error name"); 1.735 + event.preventDefault(); 1.736 + event.stopPropagation(); 1.737 + this.decr(); 1.738 + }.bind(this); 1.739 + } 1.740 +};