Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

// META: title=IDBFactory.open()
// META: global=window,worker
// META: script=resources/support.js
// @author Microsoft <https://www.microsoft.com>
// @author Odin H�rthe Omdal <mailto:odinho@opera.com>
'use strict';
async_test(t => {
const open_rq = createdb(t, undefined, 9);
open_rq.onupgradeneeded = function (e) { };
open_rq.onsuccess = function (e) {
assert_equals(e.target.source, null, "source")
t.done();
}
}, "IDBFactory.open() - request has no source");
async_test(t => {
let database_name = location + '-database_name';
const open_rq = createdb(t, database_name, 13);
open_rq.onupgradeneeded = function (e) { };
open_rq.onsuccess = function (e) {
let db = e.target.result;
assert_equals(db.name, database_name, 'db.name');
assert_equals(db.version, 13, 'db.version');
t.done();
}
}, "IDBFactory.open() - database 'name' and 'version' are correctly set");
async_test(t => {
const open_rq = createdb(t, undefined, 13);
let did_upgrade = false;
open_rq.onupgradeneeded = function () { };
open_rq.onsuccess = function (e) {
let db = e.target.result;
db.close();
let open_rq2 = indexedDB.open(db.name);
open_rq2.onsuccess = t.step_func(function (e) {
assert_equals(e.target.result.version, 13, "db.version")
e.target.result.close();
t.done();
});
open_rq2.onupgradeneeded = fail(t, 'Unexpected upgradeneeded')
open_rq2.onerror = fail(t, 'Unexpected error')
}
}, "IDBFactory.open() - no version opens current database");
async_test(t => {
const open_rq = createdb(t, self.location + '-database_name_new');
open_rq.onupgradeneeded = function (e) {
assert_equals(e.target.result.version, 1, "db.version");
};
open_rq.onsuccess = function (e) {
assert_equals(e.target.result.version, 1, "db.version");
t.done();
};
}, "IDBFactory.open() - new database has default version");
async_test(t => {
const open_rq = createdb(t, self.location + '-database_name');
open_rq.onupgradeneeded = function () { };
open_rq.onsuccess = function (e) {
assert_equals(e.target.result.objectStoreNames.length, 0, "objectStoreNames.length");
t.done();
};
}, "IDBFactory.open() - new database is empty");
async_test(t => {
const open_rq = createdb(t, undefined, 13);
let did_upgrade = false;
let open_rq2;
open_rq.onupgradeneeded = function () { };
open_rq.onsuccess = function (e) {
let db = e.target.result;
db.close();
open_rq2 = indexedDB.open(db.name, 14);
open_rq2.onupgradeneeded = function () { };
open_rq2.onsuccess = t.step_func(open_previous_db);
open_rq2.onerror = fail(t, 'Unexpected error')
}
function open_previous_db(e) {
let open_rq3 = indexedDB.open(e.target.result.name, 13);
open_rq3.onerror = t.step_func(function (e) {
assert_equals(e.target.error.name, 'VersionError', 'e.target.error.name')
open_rq2.result.close();
t.done();
});
open_rq3.onupgradeneeded = fail(t, 'Unexpected upgradeneeded')
open_rq3.onsuccess = fail(t, 'Unexpected success')
}
}, "IDBFactory.open() - open database with a lower version than current");
async_test(t => {
const open_rq = createdb(t, undefined, 13);
let did_upgrade = false;
let open_rq2;
open_rq.onupgradeneeded = function () { };
open_rq.onsuccess = function (e) {
let db = e.target.result;
db.close();
open_rq2 = indexedDB.open(db.name, 14);
open_rq2.onupgradeneeded = function () {
did_upgrade = true;
};
open_rq2.onsuccess = t.step_func(open_current_db);
open_rq2.onerror = fail(t, 'Unexpected error')
}
function open_current_db(e) {
let open_rq3 = indexedDB.open(e.target.result.name);
open_rq3.onsuccess = t.step_func(function (e) {
assert_equals(e.target.result.version, 14, "db.version")
open_rq2.result.close();
open_rq3.result.close();
t.done();
});
open_rq3.onupgradeneeded = fail(t, 'Unexpected upgradeneeded')
open_rq3.onerror = fail(t, 'Unexpected error')
assert_true(did_upgrade, 'did upgrade');
}
}, "IDBFactory.open() - open database with a higher version than current");
async_test(t => {
const open_rq = createdb(t, undefined, 13);
let did_upgrade = false;
let did_db_abort = false;
open_rq.onupgradeneeded = function (e) {
did_upgrade = true;
e.target.result.onabort = function () {
did_db_abort = true;
}
e.target.transaction.abort();
};
open_rq.onerror = function (e) {
assert_true(did_upgrade);
assert_equals(e.target.error.name, 'AbortError', 'target.error');
t.done()
};
}, "IDBFactory.open() - error in version change transaction aborts open");
function should_throw(val, name) {
if (!name) {
name = ((typeof val == "object" && val) ? "object" : format_value(val))
}
test(function () {
assert_throws_js(TypeError, function () {
indexedDB.open('test', val);
});
}, "Calling open() with version argument " + name + " should throw TypeError.")
}
should_throw(-1)
should_throw(-0.5)
should_throw(0)
should_throw(0.5)
should_throw(0.8)
should_throw(0x20000000000000) // Number.MAX_SAFE_INTEGER + 1
should_throw(NaN)
should_throw(Infinity)
should_throw(-Infinity)
should_throw("foo")
should_throw(null)
should_throw(false)
should_throw({
toString: function () { assert_unreached("toString should not be called for ToPrimitive [Number]"); },
valueOf: function () { return 0; }
})
should_throw({
toString: function () { return 0; },
valueOf: function () { return {}; }
}, 'object (second)')
should_throw({
toString: function () { return {}; },
valueOf: function () { return {}; },
}, 'object (third)')
/* Valid */
function should_work(val, expected_version) {
let name = format_value(val);
let dbname = 'test-db-does-not-exist';
async_test(function (t) {
indexedDB.deleteDatabase(dbname);
let rq = indexedDB.open(dbname, val);
rq.onupgradeneeded = t.step_func(function () {
let db = rq.result;
assert_equals(db.version, expected_version, 'version');
rq.transaction.abort();
});
rq.onsuccess = t.unreached_func("open should fail");
rq.onerror = t.step_func(function () {
t.done()
});
}, "Calling open() with version argument " + name + " should not throw.");
}
should_work(1.5, 1)
should_work(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER) // 0x20000000000000 - 1
should_work(undefined, 1);
async_test(t => {
let db, db2;
const open_rq = createdb(t, undefined, 9);
open_rq.onupgradeneeded = function (e) {
db = e.target.result;
let st = db.createObjectStore("store");
st.createIndex("index", "i");
assert_equals(db.version, 9, "first db.version");
assert_true(db.objectStoreNames.contains("store"), "objectStoreNames contains store");
assert_true(st.indexNames.contains("index"), "indexNames contains index");
st.add({ i: "Joshua" }, 1);
st.add({ i: "Jonas" }, 2);
};
open_rq.onsuccess = function (e) {
db.close();
let open_rq2 = indexedDB.open(db.name, 10);
open_rq2.onupgradeneeded = t.step_func(function (e) {
db2 = e.target.result;
db2.createObjectStore("store2");
let store = open_rq2.transaction.objectStore("store")
store.createIndex("index2", "i");
assert_equals(db2.version, 10, "db2.version");
assert_true(db2.objectStoreNames.contains("store"), "second objectStoreNames contains store");
assert_true(db2.objectStoreNames.contains("store2"), "second objectStoreNames contains store2");
assert_true(store.indexNames.contains("index"), "second indexNames contains index");
assert_true(store.indexNames.contains("index2"), "second indexNames contains index2");
store.add({ i: "Odin" }, 3);
store.put({ i: "Sicking" }, 2);
open_rq2.transaction.abort();
});
open_rq2.onerror = t.step_func(function (e) {
assert_equals(db2.version, 9, "db2.version after error");
assert_true(db2.objectStoreNames.contains("store"), "objectStoreNames contains store after error");
assert_false(db2.objectStoreNames.contains("store2"), "objectStoreNames not contains store2 after error");
let open_rq3 = indexedDB.open(db.name);
open_rq3.onsuccess = t
.step_func(function (e) {
let db3 = e.target.result;
assert_true(db3.objectStoreNames.contains("store"), "third objectStoreNames contains store");
assert_false(db3.objectStoreNames.contains("store2"), "third objectStoreNames contains store2");
let st = db3.transaction("store", "readonly", { durability: 'relaxed' }).objectStore("store");
assert_equals(db3.version, 9, "db3.version");
assert_true(st.indexNames.contains("index"), "third indexNames contains index");
assert_false(st.indexNames.contains("index2"), "third indexNames contains index2");
st.openCursor(null, "prev").onsuccess = t.step_func(function (e) {
assert_equals(e.target.result.key, 2, "opencursor(prev) key");
assert_equals(e.target.result.value.i, "Jonas", "opencursor(prev) value");
});
st.get(3).onsuccess = t.step_func(function (e) {
assert_equals(e.target.result, undefined, "get(3)");
});
let idx = st.index("index");
idx.getKey("Jonas").onsuccess = t.step_func(function (e) {
assert_equals(e.target.result, 2, "getKey(Jonas)");
});
idx.getKey("Odin").onsuccess = t.step_func(function (e) {
assert_equals(e.target.result, undefined, "getKey(Odin)");
});
idx.getKey("Sicking").onsuccess = t.step_func(function (e) {
assert_equals(e.target.result, undefined, "getKey(Sicking)");
db3.close();
t.done();
});
});
});
};
}, "IDBFactory.open() - error in upgradeneeded resets db");
async_test(t => {
let db;
let count_done = 0;
const open_rq = createdb(t);
open_rq.onupgradeneeded = function (e) {
db = e.target.result;
db.createObjectStore("store");
assert_true(db.objectStoreNames.contains("store"), "objectStoreNames contains store");
let store = e.target.transaction.objectStore("store");
assert_equals(store.name, "store", "store.name");
store.add("data", 1);
store.count().onsuccess = t.step_func(function (e) {
assert_equals(e.target.result, 1, "count()");
count_done++;
});
store.add("data2", 2);
};
open_rq.onsuccess = function (e) {
let store = db.transaction("store", "readonly", { durability: 'relaxed' }).objectStore("store");
assert_equals(store.name, "store", "store.name");
store.count().onsuccess = t.step_func(function (e) {
assert_equals(e.target.result, 2, "count()");
count_done++;
});
db.close();
let open_rq2 = indexedDB.open(db.name, 10);
open_rq2.onupgradeneeded = t.step_func(function (e) {
let db2 = e.target.result;
assert_true(db2.objectStoreNames.contains("store"), "objectStoreNames contains store");
let store = open_rq2.transaction.objectStore("store");
assert_equals(store.name, "store", "store.name");
store.add("data3", 3);
store.count().onsuccess = t.step_func(function (e) {
assert_equals(e.target.result, 3, "count()");
count_done++;
assert_equals(count_done, 3, "count_done");
db2.close();
t.done();
});
});
};
}, "IDBFactory.open() - second open's transaction is available to get objectStores");
async_test(t => {
let db;
let open_rq = createdb(t, undefined, 9);
let open2_t = t;
open_rq.onupgradeneeded = function (e) {
db = e.target.result;
assert_true(e instanceof IDBVersionChangeEvent, "e instanceof IDBVersionChangeEvent");
assert_equals(e.oldVersion, 0, "oldVersion");
assert_equals(e.newVersion, 9, "newVersion");
assert_equals(e.type, "upgradeneeded", "event type");
assert_equals(db.version, 9, "db.version");
};
open_rq.onsuccess = function (e) {
assert_true(e instanceof Event, "e instanceof Event");
assert_false(e instanceof IDBVersionChangeEvent, "e not instanceof IDBVersionChangeEvent");
assert_equals(e.type, "success", "event type");
t.done();
/**
* Second test
*/
db.onversionchange = function () { db.close(); };
let open_rq2 = createdb(open2_t, db.name, 10);
open_rq2.onupgradeneeded = function (e) {
let db2 = e.target.result;
assert_true(e instanceof IDBVersionChangeEvent, "e instanceof IDBVersionChangeEvent");
assert_equals(e.oldVersion, 9, "oldVersion");
assert_equals(e.newVersion, 10, "newVersion");
assert_equals(e.type, "upgradeneeded", "event type");
assert_equals(db2.version, 10, "new db.version");
t.done();
};
};
}, "IDBFactory.open() - upgradeneeded gets VersionChangeEvent");