| // META: global=window,worker |
| // META: title=IDBObjectStore.put() |
| // META: script=resources/support.js |
| // @author Microsoft <https://www.microsoft.com> |
| // @author Intel <http://www.intel.com> |
| |
| 'use strict'; |
| |
| async_test(t => { |
| let db; |
| const record = { key: 1, property: "data" }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| const objStore = db.createObjectStore("store", { keyPath: "key" }); |
| |
| objStore.put(record); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| const rq = db.transaction("store", "readonly") |
| .objectStore("store") |
| .get(record.key); |
| |
| rq.onsuccess = t.step_func(function(e) { |
| assert_equals(e.target.result.property, record.property); |
| assert_equals(e.target.result.key, record.key); |
| t.done(); |
| }); |
| }; |
| }, 'put() with an inline key'); |
| |
| async_test(t => { |
| let db; |
| const key = 1; |
| const record = { property: "data" }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| const objStore = db.createObjectStore("store"); |
| |
| objStore.put(record, key); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| const rq = db.transaction("store", "readonly") |
| .objectStore("store") |
| .get(key); |
| |
| rq.onsuccess = t.step_func(function(e) { |
| assert_equals(e.target.result.property, record.property); |
| |
| t.done(); |
| }); |
| }; |
| },'put() with an out-of-line key'); |
| |
| async_test(t => { |
| let db; |
| let success_event; |
| const record = { key: 1, property: "data" }; |
| const record_put = { key: 1, property: "changed", more: ["stuff", 2] }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| const objStore = db.createObjectStore("store", { keyPath: "key" }); |
| objStore.put(record); |
| |
| const rq = objStore.put(record_put); |
| rq.onerror = fail(t, "error on put"); |
| |
| rq.onsuccess = t.step_func(function(e) { |
| success_event = true; |
| }); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| assert_true(success_event); |
| |
| const rq = db.transaction("store", "readonly") |
| .objectStore("store") |
| .get(1); |
| |
| rq.onsuccess = t.step_func(function(e) { |
| const rec = e.target.result; |
| |
| assert_equals(rec.key, record_put.key); |
| assert_equals(rec.property, record_put.property); |
| assert_array_equals(rec.more, record_put.more); |
| |
| t.done(); |
| }); |
| }; |
| }, 'put() record with key already exists'); |
| |
| async_test(t => { |
| const record = { key: 1, property: "data" }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| let db = e.target.result; |
| const objStore = db.createObjectStore("store", { |
| autoIncrement: true }); |
| objStore.createIndex("i1", "property", { unique: true }); |
| objStore.put(record); |
| |
| const rq = objStore.put(record); |
| rq.onsuccess = fail(t, "success on putting duplicate indexed record"); |
| |
| rq.onerror = t.step_func(function(e) { |
| assert_equals(rq.error.name, "ConstraintError"); |
| assert_equals(e.target.error.name, "ConstraintError"); |
| |
| assert_equals(e.type, "error"); |
| |
| e.preventDefault(); |
| e.stopPropagation(); |
| }); |
| }; |
| |
| // Defer done, giving a spurious rq.onsuccess a chance to run |
| open_rq.onsuccess = function(e) { |
| t.done(); |
| }; |
| }, 'put() where an index has unique:true specified'); |
| |
| async_test(t => { |
| let db; |
| const record = { test: { obj: { key: 1 } }, property: "data" }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| const objStore = db.createObjectStore("store", |
| { keyPath: "test.obj.key" }); |
| objStore.put(record); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| const rq = db.transaction("store", "readonly") |
| .objectStore("store") |
| .get(record.test.obj.key); |
| |
| rq.onsuccess = t.step_func(function(e) { |
| assert_equals(e.target.result.property, record.property); |
| |
| t.done(); |
| }); |
| }; |
| }, 'Object store\'s key path is an object attribute'); |
| |
| async_test(t => { |
| let db; |
| const record = { property: "data" }; |
| const expected_keys = [1, 2, 3, 4]; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| const objStore = db.createObjectStore("store", { keyPath: "key", |
| autoIncrement: true }); |
| |
| objStore.put(record); |
| objStore.put(record); |
| objStore.put(record); |
| objStore.put(record); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| let actual_keys = []; |
| const rq = db.transaction("store", "readonly") |
| .objectStore("store") |
| .openCursor(); |
| |
| rq.onsuccess = t.step_func(function(e) { |
| const cursor = e.target.result; |
| |
| if (cursor) { |
| actual_keys.push(cursor.value.key); |
| cursor.continue(); |
| } else { |
| assert_array_equals(actual_keys, expected_keys); |
| t.done(); |
| } |
| }); |
| }; |
| }, 'autoIncrement and inline keys'); |
| |
| async_test(t => { |
| let db; |
| const record = { property: "data" }; |
| const expected_keys = [1, 2, 3, 4]; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| const objStore = db.createObjectStore("store", { keyPath: "key", |
| autoIncrement: true }); |
| |
| objStore.put(record); |
| objStore.put(record); |
| objStore.put(record); |
| objStore.put(record); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| const actual_keys = []; |
| const rq = db.transaction("store", "readonly") |
| .objectStore("store") |
| .openCursor(); |
| |
| rq.onsuccess = t.step_func(function(e) { |
| const cursor = e.target.result; |
| |
| if(cursor) { |
| actual_keys.push(cursor.value.key); |
| cursor.continue(); |
| } else { |
| assert_array_equals(actual_keys, expected_keys); |
| t.done(); |
| } |
| }); |
| }; |
| }, 'autoIncrement and out-of-line keys'); |
| |
| async_test(t => { |
| let db; |
| const record = { property: "data" }; |
| const expected_keys = [1, 2, 3, 4]; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| const objStore = db.createObjectStore("store", |
| { keyPath: "test.obj.key", autoIncrement: true }); |
| |
| objStore.put(record); |
| objStore.put(record); |
| objStore.put(record); |
| objStore.put(record); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| const actual_keys = []; |
| const rq = db.transaction("store", "readonly") |
| .objectStore("store") |
| .openCursor(); |
| |
| rq.onsuccess = t.step_func(function(e) { |
| const cursor = e.target.result; |
| |
| if (cursor) { |
| actual_keys.push(cursor.value.test.obj.key); |
| cursor.continue(); |
| } else { |
| assert_array_equals(actual_keys, expected_keys); |
| t.done(); |
| } |
| }); |
| }; |
| }, 'Object store has autoIncrement:true and the key path is an object \ |
| attribute'); |
| |
| async_test(t => { |
| const record = { key: 1, property: "data" }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| let rq; |
| const db = e.target.result; |
| const objStore = db.createObjectStore("store", { keyPath: "key" }); |
| |
| assert_throws_dom("DataError", function() { |
| rq = objStore.put(record, 1); |
| }); |
| |
| assert_equals(rq, undefined); |
| t.done(); |
| }; |
| }, 'Attempt to put() a record that does not meet the constraints of an object \ |
| store\'s inline key requirements'); |
| |
| async_test(t => { |
| const record = { property: "data" }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| let db = e.target.result; |
| |
| let rq; |
| const objStore = db.createObjectStore("store", { keyPath: "key" }); |
| |
| assert_throws_dom("DataError", function() { |
| rq = objStore.put(record); |
| }); |
| |
| assert_equals(rq, undefined); |
| t.done(); |
| }; |
| }, 'Attempt to call put() without an key parameter when the object store uses \ |
| out-of-line keys'); |
| |
| async_test(t => { |
| const record = { key: { value: 1 }, property: "data" }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| const db = e.target.result; |
| |
| let rq; |
| const objStore = db.createObjectStore("store", { keyPath: "key" }); |
| |
| assert_throws_dom("DataError", function() { |
| rq = objStore.put(record); |
| }); |
| |
| assert_equals(rq, undefined); |
| t.done(); |
| }; |
| }, 'Attempt to put() a record where the record\'s key does not meet the \ |
| constraints of a valid key'); |
| |
| async_test(t => { |
| const record = { property: "data" }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| const db = e.target.result; |
| |
| let rq; |
| const objStore = db.createObjectStore("store", { keyPath: "key" }); |
| |
| assert_throws_dom("DataError", function() { |
| rq = objStore.put(record); |
| }); |
| |
| assert_equals(rq, undefined); |
| t.done(); |
| }; |
| }, 'Attempt to put() a record where the record\'s in-line key is not defined'); |
| |
| async_test(t => { |
| const record = { property: "data" }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| const db = e.target.result; |
| |
| let rq; |
| const objStore = db.createObjectStore("store"); |
| |
| assert_throws_dom("DataError", function() { |
| rq = objStore.put(record, { value: 1 }); |
| }); |
| |
| assert_equals(rq, undefined); |
| t.done(); |
| }; |
| }, 'Attempt to put() a record where the out of line key provided does not \ |
| meet the constraints of a valid key'); |
| |
| async_test(t => { |
| const record = { key: 1, indexedProperty: { property: "data" } }; |
| |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| const db = e.target.result; |
| |
| let rq; |
| const objStore = db.createObjectStore("store", { keyPath: "key" }); |
| |
| objStore.createIndex("index", "indexedProperty"); |
| |
| rq = objStore.put(record); |
| |
| assert_true(rq instanceof IDBRequest); |
| rq.onsuccess = function() { |
| t.done(); |
| }; |
| }; |
| }, 'put() a record where a value being indexed does not meet the constraints \ |
| of a valid key'); |
| |
| async_test(t => { |
| let db; |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(event) { |
| db = event.target.result; |
| db.createObjectStore("store", { keyPath: "pKey" }); |
| }; |
| |
| open_rq.onsuccess = function(event) { |
| const txn = db.transaction("store", "readonly"); |
| const ostore = txn.objectStore("store"); |
| t.step(function() { |
| assert_throws_dom("ReadOnlyError", function() { |
| ostore.put({ pKey: "primaryKey_0" }); |
| }); |
| }); |
| t.done(); |
| }; |
| }, 'If the transaction this IDBObjectStore belongs to has its mode set to \ |
| readonly, throw ReadOnlyError'); |
| |
| async_test(t => { |
| let ostore; |
| const open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(event) { |
| const db = event.target.result; |
| ostore = db.createObjectStore("store", { keyPath: "pKey" }); |
| db.deleteObjectStore("store"); |
| assert_throws_dom("InvalidStateError", function() { |
| ostore.put({ pKey: "primaryKey_0" }); |
| }); |
| t.done(); |
| }; |
| }, 'If the object store has been deleted, the implementation must throw a \ |
| DOMException of type InvalidStateError'); |