| // META: title=IDBDatabase.createObjectStore() |
| // META: global=window,worker |
| // META: script=resources/support.js |
| |
| // Spec: https://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore |
| |
| 'use strict'; |
| |
| async_test(t => { |
| let db; |
| let open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| let store = db.createObjectStore(''); |
| |
| for (let i = 0; i < 5; i++) |
| store.add({idx: 'object_' + i}, i); |
| |
| store.createIndex('', 'idx'); |
| |
| store.get(4).onsuccess = t.step_func(function(e) { |
| assert_equals(e.target.result.idx, 'object_4', 'result'); |
| }); |
| assert_equals(store.indexNames[0], '', 'indexNames[0]'); |
| assert_equals(store.indexNames.length, 1, 'indexNames.length'); |
| }; |
| |
| open_rq.onsuccess = function() { |
| let store = db.transaction('').objectStore(''); |
| |
| assert_equals(store.indexNames[0], '', 'indexNames[0]'); |
| assert_equals(store.indexNames.length, 1, 'indexNames.length'); |
| |
| store.index('').get('object_4').onsuccess = t.step_func(function(e) { |
| assert_equals(e.target.result.idx, 'object_4', 'result'); |
| t.done(); |
| }); |
| }; |
| }, 'Both with empty name'); |
| |
| async_test(t => { |
| let open_rq = createdb(t); |
| |
| open_rq.onupgradeneeded = function(e) { |
| let db = e.target.result; |
| let objStore = db.createObjectStore('instancetest'); |
| |
| assert_true( |
| objStore instanceof IDBObjectStore, 'instanceof IDBObjectStore'); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| let db = e.target.result; |
| let objStore = |
| db.transaction('instancetest', 'readonly').objectStore('instancetest'); |
| |
| assert_true( |
| objStore instanceof IDBObjectStore, 'instanceof IDBObjectStore'); |
| t.done(); |
| }; |
| }, 'Returns an instance of IDBObjectStore'); |
| |
| async_test(t => { |
| let db; |
| let open_rq = createdb(t); |
| |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| let store; |
| let i; |
| for (i = 0; i < 1000; i++) { |
| store = db.createObjectStore('object_store_' + i); |
| store.add('test', 1); |
| } |
| |
| store.get(1).onsuccess = t.step_func(function(e) { |
| assert_equals(e.target.result, 'test'); |
| }); |
| }; |
| open_rq.onsuccess = function(e) { |
| db.close(); |
| self.indexedDB.deleteDatabase(db.name).onsuccess = function(e) { |
| t.done(); |
| } |
| }; |
| }, 'Create 1000 object stores, add one item and delete'); |
| |
| async_test(t => { |
| let db; |
| let open_rq = createdb(t); |
| open_rq.onupgradeneeded = function(e) { |
| db = e.target.result; |
| let store = db.createObjectStore(''); |
| |
| for (let i = 0; i < 5; i++) |
| store.add('object_' + i, i); |
| |
| assert_equals(db.objectStoreNames[0], '', 'db.objectStoreNames[0]'); |
| assert_equals(db.objectStoreNames.length, 1, 'objectStoreNames.length'); |
| }; |
| |
| open_rq.onsuccess = function() { |
| let store = db.transaction('').objectStore(''); |
| |
| store.get(2).onsuccess = t.step_func(function(e) { |
| assert_equals(e.target.result, 'object_2'); |
| }) |
| |
| assert_equals(db.objectStoreNames[0], '', 'db.objectStoreNames[0]'); |
| assert_equals(db.objectStoreNames.length, 1, 'objectStoreNames.length'); |
| |
| t.done(); |
| }; |
| }, 'Empty name'); |
| |
| async_test(t => { |
| let open_rq = createdb(t); |
| |
| open_rq.onupgradeneeded = function(e) { |
| let db = e.target.result; |
| db.createObjectStore('store'); |
| assert_throws_dom('ConstraintError', function() { |
| db.createObjectStore('store', { |
| keyPath: 'key1', |
| }); |
| }); |
| t.done(); |
| }; |
| }, 'Attempting to create an existing object store with a different keyPath throw ConstraintError '); |
| |
| async_test(t => { |
| let open_rq = createdb(t); |
| |
| open_rq.onupgradeneeded = function(e) { |
| let db = e.target.result; |
| let objStore = db.createObjectStore('prop', {keyPath: 'mykeypath'}); |
| |
| assert_equals(objStore.name, 'prop', 'object store name'); |
| assert_equals(objStore.keyPath, 'mykeypath', 'key path'); |
| assert_equals(objStore.autoIncrement, false, 'auto increment'); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| let db = e.target.result; |
| let objStore = db.transaction('prop', 'readonly').objectStore('prop'); |
| |
| assert_equals(objStore.name, 'prop', 'object store name'); |
| assert_equals(objStore.keyPath, 'mykeypath', 'key path'); |
| assert_equals(objStore.autoIncrement, false, 'auto increment'); |
| t.done(); |
| }; |
| }, 'Object store \'name\' and \'keyPath\' properties are correctly set '); |
| |
| async_test(t => { |
| let open_rq = createdb(t); |
| open_rq.onupgradeneeded = function() {}; |
| open_rq.onsuccess = function(e) { |
| let db = e.target.result; |
| assert_throws_dom('InvalidStateError', function() { |
| db.createObjectStore('fails') |
| }); |
| t.done(); |
| }; |
| }, 'Attempt to create an object store outside of a version change transaction '); |
| |
| async_test(t => { |
| let open_rq = createdb(t); |
| |
| open_rq.onupgradeneeded = function(e) { |
| let db = e.target.result; |
| db.createObjectStore('dupe'); |
| assert_throws_dom('ConstraintError', function() { |
| db.createObjectStore('dupe'); |
| }); |
| |
| // Bonus test creating a new objectstore after the exception |
| db.createObjectStore('dupe '); |
| t.done(); |
| }; |
| }, 'Attempt to create an object store that already exists '); |
| |
| async_test(t => { |
| let open_rq = createdb(t); |
| |
| open_rq.onupgradeneeded = function(e) { |
| let db = e.target.result; |
| |
| db.createObjectStore('My cool object store name'); |
| assert_true( |
| db.objectStoreNames.contains('My cool object store name'), |
| 'objectStoreNames.contains'); |
| }; |
| |
| open_rq.onsuccess = function(e) { |
| let db = e.target.result; |
| |
| assert_true( |
| db.objectStoreNames.contains('My cool object store name'), |
| 'objectStoreNames.contains (in success)'); |
| t.done(); |
| }; |
| }, 'Object store\'s name appears in database\'s list '); |
| |
| async_test(t => { |
| let open_rq = createdb(t); |
| |
| open_rq.onupgradeneeded = function(e) { |
| let db = e.target.result; |
| |
| assert_throws_dom('SyntaxError', function() { |
| db.createObjectStore('invalidkeypath', {keyPath: 'Invalid Keypath'}) |
| }); |
| |
| assert_throws_dom('SyntaxError', function() { |
| db.createObjectStore( |
| 'invalidkeypath', {autoIncrement: true, keyPath: 'Invalid Keypath'}) |
| }); |
| |
| t.done(); |
| }; |
| }, 'Attempt to create an object store with an invalid key path '); |
| |
| async_test(t => { |
| let open_rq = createdb(t); |
| |
| open_rq.onupgradeneeded = function(e) { |
| let db = e.target.result; |
| db.createObjectStore('with unknown param', {parameter: 0}); |
| |
| t.done(); |
| }; |
| }, 'Create an object store with an unknown optional parameter '); |
| |
| function optionalParameters(desc, params, t) { |
| promise_test(t => { |
| return new Promise((resolve, reject) => { |
| const request = createdb(t); |
| request.onupgradeneeded = t.step_func(function(e) { |
| e.target.result.createObjectStore('store', params); |
| resolve(); |
| }); |
| }); |
| }, desc); |
| } |
| |
| optionalParameters('autoInc true', {autoIncrement: true}); |
| |
| optionalParameters( |
| 'autoInc true, keyPath null', {autoIncrement: true, keyPath: null}); |
| |
| optionalParameters( |
| 'autoInc true, keyPath undefined', |
| {autoIncrement: true, keyPath: undefined}); |
| |
| optionalParameters( |
| 'autoInc true, keyPath string', {autoIncrement: true, keyPath: 'a'}); |
| |
| optionalParameters( |
| 'autoInc false, keyPath empty', {autoIncrement: false, keyPath: ''}); |
| |
| optionalParameters( |
| 'autoInc false, keyPath array', |
| {autoIncrement: false, keyPath: ['h', 'j']}); |
| |
| optionalParameters( |
| 'autoInc false, keyPath string', {autoIncrement: false, keyPath: 'abc'}); |
| |
| optionalParameters('keyPath empty', {keyPath: ''}); |
| |
| optionalParameters('keyPath array', {keyPath: ['a', 'b']}); |
| |
| optionalParameters('keyPath string', {keyPath: 'abc'}); |
| |
| optionalParameters('keyPath null', {keyPath: null}); |
| |
| optionalParameters('keyPath undefined', {keyPath: undefined}); |
| |
| function invalid_optionalParameters( |
| desc, params, exception = 'InvalidAccessError') { |
| promise_test(t => { |
| return new Promise((resolve, reject) => { |
| const request = createdb(t); |
| request.onupgradeneeded = t.step_func(function(e) { |
| assert_throws_dom(exception, function() { |
| e.target.result.createObjectStore('store', params); |
| }); |
| resolve(); |
| }); |
| }); |
| }, desc); |
| } |
| |
| invalid_optionalParameters( |
| 'autoInc and empty keyPath', {autoIncrement: true, keyPath: ''}); |
| |
| invalid_optionalParameters( |
| 'autoInc and keyPath array', {autoIncrement: true, keyPath: []}, |
| 'SyntaxError'); |
| |
| invalid_optionalParameters( |
| 'autoInc and keyPath array 2', {autoIncrement: true, keyPath: ['hey']}); |
| |
| invalid_optionalParameters( |
| 'autoInc and keyPath object', |
| {autoIncrement: true, keyPath: {a: 'hey', b: 2}}, 'SyntaxError'); |