395 lines
No EOL
14 KiB
JavaScript
395 lines
No EOL
14 KiB
JavaScript
// 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").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").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"); |