tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

idbindex-rename.any.js (15594B)


      1 // META: title=IndexedDB: index renaming support
      2 // META: global=window,worker
      3 // META: script=resources/support-promises.js
      4 // META: timeout=long
      5 
      6 // Spec: https://w3c.github.io/IndexedDB/#dom-idbindex-name
      7 
      8 'use strict';
      9 
     10 promise_test(testCase => {
     11  let authorIndex = null;
     12  let authorIndex2 = null;
     13  let renamedAuthorIndex = null;
     14  let renamedAuthorIndex2 = null;
     15  return createDatabase(
     16             testCase,
     17             (database, transaction) => {
     18               const store = createBooksStore(testCase, database);
     19               authorIndex = store.index('by_author');
     20             })
     21      .then(database => {
     22        const transaction = database.transaction('books', 'readonly');
     23        const store = transaction.objectStore('books');
     24        assert_array_equals(
     25            store.indexNames, ['by_author', 'by_title'],
     26            'Test setup should have created two indexes');
     27        authorIndex2 = store.index('by_author');
     28        return checkAuthorIndexContents(
     29                   testCase, authorIndex2,
     30                   'The index should have the expected contents before any renaming')
     31            .then(() => database.close());
     32      })
     33      .then(
     34          () => migrateDatabase(
     35              testCase, 2,
     36              (database, transaction) => {
     37                const store = transaction.objectStore('books');
     38                renamedAuthorIndex = store.index('by_author');
     39                renamedAuthorIndex.name = 'renamed_by_author';
     40 
     41                assert_equals(
     42                    renamedAuthorIndex.name, 'renamed_by_author',
     43                    'IDBIndex name should change immediately after a rename');
     44                assert_array_equals(
     45                    store.indexNames, ['by_title', 'renamed_by_author'],
     46                    'IDBObjectStore.indexNames should immediately reflect the rename');
     47                assert_equals(
     48                    store.index('renamed_by_author'), renamedAuthorIndex,
     49                    'IDBObjectStore.index should return the renamed index store when ' +
     50                        'queried using the new name immediately after the rename');
     51                assert_throws_dom(
     52                    'NotFoundError', () => store.index('by_author'),
     53                    'IDBObjectStore.index should throw when queried using the ' +
     54                        'renamed index\'s old name immediately after the rename');
     55              }))
     56      .then(database => {
     57        const transaction = database.transaction('books', 'readonly');
     58        const store = transaction.objectStore('books');
     59        assert_array_equals(
     60            store.indexNames, ['by_title', 'renamed_by_author'],
     61            'IDBObjectStore.indexNames should still reflect the rename after ' +
     62                'the versionchange transaction commits');
     63        renamedAuthorIndex2 = store.index('renamed_by_author');
     64        return checkAuthorIndexContents(
     65                   testCase, renamedAuthorIndex2,
     66                   'Renaming an index should not change its contents')
     67            .then(() => database.close());
     68      })
     69      .then(() => {
     70        assert_equals(
     71            authorIndex.name, 'by_author',
     72            'IDBIndex obtained before the rename transaction should not ' +
     73                'reflect the rename');
     74        assert_equals(
     75            authorIndex2.name, 'by_author',
     76            'IDBIndex obtained before the rename transaction should not ' +
     77                'reflect the rename');
     78        assert_equals(
     79            renamedAuthorIndex.name, 'renamed_by_author',
     80            'IDBIndex used in the rename transaction should keep reflecting ' +
     81                'the new name after the transaction is committed');
     82        assert_equals(
     83            renamedAuthorIndex2.name, 'renamed_by_author',
     84            'IDBIndex obtained after the rename transaction should reflect ' +
     85                'the new name');
     86      });
     87 }, 'IndexedDB index rename in new transaction');
     88 
     89 promise_test(testCase => {
     90  let renamedAuthorIndex = null;
     91  let renamedAuthorIndex2 = null;
     92  return createDatabase(
     93             testCase,
     94             (database, transaction) => {
     95               const store = createBooksStore(testCase, database);
     96               renamedAuthorIndex = store.index('by_author');
     97               renamedAuthorIndex.name = 'renamed_by_author';
     98 
     99               assert_equals(
    100                   renamedAuthorIndex.name, 'renamed_by_author',
    101                   'IDBIndex name should change immediately after a rename');
    102               assert_array_equals(
    103                   store.indexNames, ['by_title', 'renamed_by_author'],
    104                   'IDBObjectStore.indexNames should immediately reflect the rename');
    105               assert_equals(
    106                   store.index('renamed_by_author'), renamedAuthorIndex,
    107                   'IDBObjectStore.index should return the renamed index store when ' +
    108                       'queried using the new name immediately after the rename');
    109               assert_throws_dom(
    110                   'NotFoundError', () => store.index('by_author'),
    111                   'IDBObjectStore.index should throw when queried using the ' +
    112                       'renamed index\'s old name immediately after the rename');
    113             })
    114      .then(database => {
    115        const transaction = database.transaction('books', 'readonly');
    116        const store = transaction.objectStore('books');
    117        assert_array_equals(
    118            store.indexNames, ['by_title', 'renamed_by_author'],
    119            'IDBObjectStore.indexNames should still reflect the rename after ' +
    120                'the versionchange transaction commits');
    121        renamedAuthorIndex2 = store.index('renamed_by_author');
    122        return checkAuthorIndexContents(
    123                   testCase, renamedAuthorIndex2,
    124                   'Renaming an index should not change its contents')
    125            .then(() => database.close());
    126      })
    127      .then(() => {
    128        assert_equals(
    129            renamedAuthorIndex.name, 'renamed_by_author',
    130            'IDBIndex used in the rename transaction should keep reflecting ' +
    131                'the new name after the transaction is committed');
    132        assert_equals(
    133            renamedAuthorIndex2.name, 'renamed_by_author',
    134            'IDBIndex obtained after the rename transaction should reflect ' +
    135                'the new name');
    136      });
    137 }, 'IndexedDB index rename in the transaction where it is created');
    138 
    139 promise_test(testCase => {
    140  return createDatabase(
    141             testCase,
    142             (database, transaction) => {
    143               createBooksStore(testCase, database);
    144             })
    145      .then(database => {
    146        database.close();
    147      })
    148      .then(
    149          () => migrateDatabase(
    150              testCase, 2,
    151              (database, transaction) => {
    152                const store = transaction.objectStore('books');
    153                const index = store.index('by_author');
    154                index.name = 'by_author';
    155                assert_array_equals(
    156                    store.indexNames, ['by_author', 'by_title'],
    157                    'Renaming an index to the same name should not change the ' +
    158                        'index\'s IDBObjectStore.indexNames');
    159              }))
    160      .then(database => {
    161        const transaction = database.transaction('books', 'readonly');
    162        const store = transaction.objectStore('books');
    163        assert_array_equals(
    164            store.indexNames, ['by_author', 'by_title'],
    165            'Committing a transaction that renames a store to the same name ' +
    166                'should not change the index\'s IDBObjectStore.indexNames');
    167        const index = store.index('by_author');
    168        return checkAuthorIndexContents(
    169                   testCase, index,
    170                   'Committing a transaction that renames an index to the same name ' +
    171                       'should not change the index\'s contents')
    172            .then(() => database.close());
    173      });
    174 }, 'IndexedDB index rename to the same name succeeds');
    175 
    176 promise_test(testCase => {
    177  return createDatabase(
    178             testCase,
    179             (database, transaction) => {
    180               createBooksStore(testCase, database);
    181             })
    182      .then(database => {
    183        database.close();
    184      })
    185      .then(
    186          () => migrateDatabase(
    187              testCase, 2,
    188              (database, transaction) => {
    189                const store = transaction.objectStore('books');
    190                const index = store.index('by_author');
    191                store.deleteIndex('by_title');
    192                index.name = 'by_title';
    193                assert_array_equals(
    194                    store.indexNames, ['by_title'],
    195                    'IDBObjectStore.indexNames should immediately reflect the rename');
    196              }))
    197      .then(database => {
    198        const transaction = database.transaction('books', 'readonly');
    199        const store = transaction.objectStore('books');
    200        assert_array_equals(
    201            store.indexNames, ['by_title'],
    202            'IDBObjectStore.indexNames should still reflect the rename after ' +
    203                'the versionchange transaction commits');
    204        const index = store.index('by_title');
    205        return checkAuthorIndexContents(
    206                   testCase, index,
    207                   'Renaming an index should not change its contents')
    208            .then(() => database.close());
    209      });
    210 }, 'IndexedDB index rename to the name of a deleted index succeeds');
    211 
    212 promise_test(testCase => {
    213  return createDatabase(
    214             testCase,
    215             (database, transaction) => {
    216               createBooksStore(testCase, database);
    217             })
    218      .then(database => {
    219        database.close();
    220      })
    221      .then(
    222          () => migrateDatabase(
    223              testCase, 2,
    224              (database, transaction) => {
    225                const store = transaction.objectStore('books');
    226                store.index('by_author').name = 'tmp';
    227                store.index('by_title').name = 'by_author';
    228                store.index('tmp').name = 'by_title';
    229                assert_array_equals(
    230                    store.indexNames, ['by_author', 'by_title'],
    231                    'IDBObjectStore.indexNames should reflect the swap immediately ' +
    232                        'after the renames');
    233                return checkTitleIndexContents(
    234                    testCase, store.index('by_author'),
    235                    'Renaming an index should not change its contents');
    236              }))
    237      .then(database => {
    238        const transaction = database.transaction('books', 'readonly');
    239        const store = transaction.objectStore('books');
    240        assert_array_equals(
    241            store.indexNames, ['by_author', 'by_title'],
    242            'IDBObjectStore.indexNames should still reflect the swap after ' +
    243                'the versionchange transaction commits');
    244        const index = store.index('by_title');
    245        return checkAuthorIndexContents(
    246                   testCase, index,
    247                   'Renaming an index should not change its contents')
    248            .then(() => database.close());
    249      });
    250 }, 'IndexedDB index swapping via renames succeeds');
    251 
    252 promise_test(testCase => {
    253  return createDatabase(
    254             testCase,
    255             (database, transaction) => {
    256               createBooksStore(testCase, database);
    257             })
    258      .then(database => {
    259        database.close();
    260      })
    261      .then(
    262          () => migrateDatabase(
    263              testCase, 2,
    264              (database, transaction) => {
    265                const store = transaction.objectStore('books');
    266                const index = store.index('by_author');
    267 
    268                index.name = 42;
    269                assert_equals(
    270                    index.name, '42',
    271                    'IDBIndex name should change immediately after a rename to a ' +
    272                        'number');
    273                assert_array_equals(
    274                    store.indexNames, ['42', 'by_title'],
    275                    'IDBObjectStore.indexNames should immediately reflect the ' +
    276                        'stringifying rename');
    277 
    278                index.name = true;
    279                assert_equals(
    280                    index.name, 'true',
    281                    'IDBIndex name should change immediately after a rename to a ' +
    282                        'boolean');
    283 
    284                index.name = {};
    285                assert_equals(
    286                    index.name, '[object Object]',
    287                    'IDBIndex name should change immediately after a rename to an ' +
    288                        'object');
    289 
    290                index.name = () => null;
    291                assert_equals(
    292                    index.name, '() => null',
    293                    'IDBIndex name should change immediately after a rename to a ' +
    294                        'function');
    295 
    296                index.name = undefined;
    297                assert_equals(
    298                    index.name, 'undefined',
    299                    'IDBIndex name should change immediately after a rename to ' +
    300                        'undefined');
    301              }))
    302      .then(database => {
    303        const transaction = database.transaction('books', 'readonly');
    304        const store = transaction.objectStore('books');
    305        assert_array_equals(
    306            store.indexNames, ['by_title', 'undefined'],
    307            'IDBObjectStore.indexNames should reflect the last rename ' +
    308                'after the versionchange transaction commits');
    309        const index = store.index('undefined');
    310        return checkAuthorIndexContents(
    311                   testCase, index,
    312                   'Renaming an index should not change its contents')
    313            .then(() => database.close());
    314      });
    315 }, 'IndexedDB index rename stringifies non-string names');
    316 
    317 for (let escapedName of ['', '\\u0000', '\\uDC00\\uD800'])
    318  ((escapedName) => {
    319    const name = JSON.parse('"' + escapedName + '"');
    320    promise_test(testCase => {
    321      return createDatabase(
    322                 testCase,
    323                 (database, transaction) => {
    324                   createBooksStore(testCase, database);
    325                 })
    326          .then(database => {
    327            database.close();
    328          })
    329          .then(
    330              () => migrateDatabase(
    331                  testCase, 2,
    332                  (database, transaction) => {
    333                    const store = transaction.objectStore('books');
    334                    const index = store.index('by_author');
    335 
    336                    index.name = name;
    337                    assert_equals(
    338                        index.name, name,
    339                        'IDBIndex name should change immediately after the rename');
    340                    assert_array_equals(
    341                        store.indexNames, [name, 'by_title'].sort(),
    342                        'IDBObjectStore.indexNames should immediately reflect the rename');
    343                  }))
    344          .then(database => {
    345            const transaction = database.transaction('books', 'readonly');
    346            const store = transaction.objectStore('books');
    347            assert_array_equals(
    348                store.indexNames, [name, 'by_title'].sort(),
    349                'IDBObjectStore.indexNames should reflect the rename ' +
    350                    'after the versionchange transaction commits');
    351            const index = store.index(name);
    352            return checkAuthorIndexContents(
    353                       testCase, index,
    354                       'Renaming an index should not change its contents')
    355                .then(() => database.close());
    356          });
    357    }, 'IndexedDB index can be renamed to "' + escapedName + '"');
    358  })(escapedName);