summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/IndexedDB/resources/support.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/IndexedDB/resources/support.js
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/IndexedDB/resources/support.js')
-rw-r--r--testing/web-platform/tests/IndexedDB/resources/support.js228
1 files changed, 228 insertions, 0 deletions
diff --git a/testing/web-platform/tests/IndexedDB/resources/support.js b/testing/web-platform/tests/IndexedDB/resources/support.js
new file mode 100644
index 0000000000..5036e50466
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/resources/support.js
@@ -0,0 +1,228 @@
+/* Delete created databases
+ *
+ * Go through each finished test, see if it has an associated database. Close
+ * that and delete the database. */
+add_completion_callback(function(tests)
+{
+ for (var i in tests)
+ {
+ if(tests[i].db)
+ {
+ tests[i].db.close();
+ self.indexedDB.deleteDatabase(tests[i].db.name);
+ }
+ }
+});
+
+function fail(test, desc) {
+ return test.step_func(function(e) {
+ if (e && e.message && e.target.error)
+ assert_unreached(desc + " (" + e.target.error.name + ": " + e.message + ")");
+ else if (e && e.message)
+ assert_unreached(desc + " (" + e.message + ")");
+ else if (e && e.target.readyState === 'done' && e.target.error)
+ assert_unreached(desc + " (" + e.target.error.name + ")");
+ else
+ assert_unreached(desc);
+ });
+}
+
+function createdb(test, dbname, version)
+{
+ var rq_open = createdb_for_multiple_tests(dbname, version);
+ return rq_open.setTest(test);
+}
+
+function createdb_for_multiple_tests(dbname, version) {
+ var rq_open,
+ fake_open = {},
+ test = null,
+ dbname = (dbname ? dbname : "testdb-" + new Date().getTime() + Math.random() );
+
+ if (version)
+ rq_open = self.indexedDB.open(dbname, version);
+ else
+ rq_open = self.indexedDB.open(dbname);
+
+ function auto_fail(evt, current_test) {
+ /* Fail handlers, if we haven't set on/whatever/, don't
+ * expect to get event whatever. */
+ rq_open.manually_handled = {};
+
+ rq_open.addEventListener(evt, function(e) {
+ if (current_test !== test) {
+ return;
+ }
+
+ test.step(function() {
+ if (!rq_open.manually_handled[evt]) {
+ assert_unreached("unexpected open." + evt + " event");
+ }
+
+ if (e.target.result + '' == '[object IDBDatabase]' &&
+ !this.db) {
+ this.db = e.target.result;
+
+ this.db.onerror = fail(test, 'unexpected db.error');
+ this.db.onabort = fail(test, 'unexpected db.abort');
+ this.db.onversionchange =
+ fail(test, 'unexpected db.versionchange');
+ }
+ });
+ });
+ rq_open.__defineSetter__("on" + evt, function(h) {
+ rq_open.manually_handled[evt] = true;
+ if (!h)
+ rq_open.addEventListener(evt, function() {});
+ else
+ rq_open.addEventListener(evt, test.step_func(h));
+ });
+ }
+
+ // add a .setTest method to the IDBOpenDBRequest object
+ Object.defineProperty(rq_open, 'setTest', {
+ enumerable: false,
+ value: function(t) {
+ test = t;
+
+ auto_fail("upgradeneeded", test);
+ auto_fail("success", test);
+ auto_fail("blocked", test);
+ auto_fail("error", test);
+
+ return this;
+ }
+ });
+
+ return rq_open;
+}
+
+function assert_key_equals(actual, expected, description) {
+ assert_equals(indexedDB.cmp(actual, expected), 0, description);
+}
+
+// Usage:
+// indexeddb_test(
+// (test_object, db_connection, upgrade_tx, open_request) => {
+// // Database creation logic.
+// },
+// (test_object, db_connection, open_request) => {
+// // Test logic.
+// test_object.done();
+// },
+// 'Test case description');
+function indexeddb_test(upgrade_func, open_func, description, options) {
+ async_test(function(t) {
+ options = Object.assign({upgrade_will_abort: false}, options);
+ var dbname = location + '-' + t.name;
+ var del = indexedDB.deleteDatabase(dbname);
+ del.onerror = t.unreached_func('deleteDatabase should succeed');
+ var open = indexedDB.open(dbname, 1);
+ open.onupgradeneeded = t.step_func(function() {
+ var db = open.result;
+ t.add_cleanup(function() {
+ // If open didn't succeed already, ignore the error.
+ open.onerror = function(e) {
+ e.preventDefault();
+ };
+ db.close();
+ indexedDB.deleteDatabase(db.name);
+ });
+ var tx = open.transaction;
+ upgrade_func(t, db, tx, open);
+ });
+ if (options.upgrade_will_abort) {
+ open.onsuccess = t.unreached_func('open should not succeed');
+ } else {
+ open.onerror = t.unreached_func('open should succeed');
+ open.onsuccess = t.step_func(function() {
+ var db = open.result;
+ if (open_func)
+ open_func(t, db, open);
+ });
+ }
+ }, description);
+}
+
+// Call with a Test and an array of expected results in order. Returns
+// a function; call the function when a result arrives and when the
+// expected number appear the order will be asserted and test
+// completed.
+function expect(t, expected) {
+ var results = [];
+ return result => {
+ results.push(result);
+ if (results.length === expected.length) {
+ assert_array_equals(results, expected);
+ t.done();
+ }
+ };
+}
+
+// Checks to see if the passed transaction is active (by making
+// requests against the named store).
+function is_transaction_active(tx, store_name) {
+ try {
+ const request = tx.objectStore(store_name).get(0);
+ request.onerror = e => {
+ e.preventDefault();
+ e.stopPropagation();
+ };
+ return true;
+ } catch (ex) {
+ assert_equals(ex.name, 'TransactionInactiveError',
+ 'Active check should either not throw anything, or throw ' +
+ 'TransactionInactiveError');
+ return false;
+ }
+}
+
+// Keeps the passed transaction alive indefinitely (by making requests
+// against the named store). Returns a function that asserts that the
+// transaction has not already completed and then ends the request loop so that
+// the transaction may autocommit and complete.
+function keep_alive(tx, store_name) {
+ let completed = false;
+ tx.addEventListener('complete', () => { completed = true; });
+
+ let keepSpinning = true;
+
+ function spin() {
+ if (!keepSpinning)
+ return;
+ tx.objectStore(store_name).get(0).onsuccess = spin;
+ }
+ spin();
+
+ return () => {
+ assert_false(completed, 'Transaction completed while kept alive');
+ keepSpinning = false;
+ };
+}
+
+// Returns a new function. After it is called |count| times, |func|
+// will be called.
+function barrier_func(count, func) {
+ let n = 0;
+ return () => {
+ if (++n === count)
+ func();
+ };
+}
+
+// Create an IndexedDB by executing script on the given remote context
+// with |dbName| and |version|.
+async function createIndexedDBForTesting(rc, dbName, version) {
+ await rc.executeScript((dbName, version) => {
+ let request = indexedDB.open(dbName, version);
+ request.onupgradeneeded = () => {
+ if (version == 1) {
+ // Only create the object store once.
+ request.result.createObjectStore('store');
+ }
+ }
+ request.onversionchange = () => {
+ fail(t, 'unexpectedly received versionchange event.');
+ }
+ }, [dbName, version]);
+}