| // 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"); |