diff options
Diffstat (limited to 'testing/web-platform/tests/IndexedDB/name-scopes.html')
-rw-r--r-- | testing/web-platform/tests/IndexedDB/name-scopes.html | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/testing/web-platform/tests/IndexedDB/name-scopes.html b/testing/web-platform/tests/IndexedDB/name-scopes.html new file mode 100644 index 0000000000..d92f706e0a --- /dev/null +++ b/testing/web-platform/tests/IndexedDB/name-scopes.html @@ -0,0 +1,134 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + IndexedDB: scoping for database / object store / index names, and index keys +</title> +<link rel="help" href="https://w3c.github.io/IndexedDB/#constructs"> +<link rel="author" href="pwnall@chromium.org" title="Victor Costan"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/support-promises.js"></script> +<script> +'use strict'; + +// Creates the structure inside a test database. +// +// The structure includes two stores with identical indexes and nearly-similar +// records. The records differ in the "path" attribute values, which are used to +// verify that IndexedDB returns the correct records when queried. +// +// databaseName appears redundant, but we don't want to rely on database.name. +const buildStores = (database, databaseName, useUniqueKeys) => { + for (let storeName of ['x', 'y']) { + const store = database.createObjectStore( + storeName, { keyPath: 'pKey', autoIncrement: true }); + for (let indexName of ['x', 'y']) { + store.createIndex( + indexName, `${indexName}Key`, { unique: useUniqueKeys }); + } + + for (let xKeyRoot of ['x', 'y']) { + for (let yKeyRoot of ['x', 'y']) { + let xKey, yKey; + if (useUniqueKeys) { + xKey = `${xKeyRoot}${yKeyRoot}`; + yKey = `${yKeyRoot}${xKeyRoot}`; + } else { + xKey = xKeyRoot; + yKey = yKeyRoot; + } + const path = `${databaseName}-${storeName}-${xKeyRoot}-${yKeyRoot}`; + store.put({ xKey: xKey, yKey: yKey, path: path }); + } + } + } +}; + +// Creates two databases with identical structures. +const buildDatabases = (testCase, useUniqueKeys) => { + return createNamedDatabase( + testCase, 'x', database => buildStores(database, 'x', useUniqueKeys)) + .then(database => database.close()) + .then(() => createNamedDatabase( + testCase, 'y', database => buildStores(database, 'y', useUniqueKeys))) + .then(database => database.close()); +}; + +// Reads all the store's values using an index. +// +// Returns a Promise that resolves with an array of values. +const readIndex = (testCase, index) => { + return new Promise((resolve, reject) => { + const results = []; + const request = index.openCursor(IDBKeyRange.bound('a', 'z'), 'next'); + request.onsuccess = () => { + const cursor = request.result; + if (cursor) { + results.push(cursor.value); + cursor.continue(); + } else { + resolve(results); + } + } + }); +} + +// Verifies that a database contains the expected records. +const checkDatabaseContent = + (testCase, database, databaseName, usedUniqueKeys) => { + const promises = []; + const transaction = database.transaction(['x', 'y'], 'readonly'); + for (let storeName of ['x', 'y']) { + const store = transaction.objectStore(storeName); + for (let indexName of ['x', 'y']) { + const index = store.index(indexName); + + const promise = readIndex(testCase, index).then((results) => { + assert_array_equals( + results.map(result => `${result.path}:${result.pKey}`).sort(), + [`${databaseName}-${storeName}-x-x:1`, + `${databaseName}-${storeName}-x-y:2`, + `${databaseName}-${storeName}-y-x:3`, + `${databaseName}-${storeName}-y-y:4`], + 'The results should include all records put into the store'); + + let expectedKeys = (usedUniqueKeys) ? + ['xx:xx', 'xy:yx', 'yx:xy', 'yy:yy'] : ['x:x', 'x:y', 'y:x', 'y:y']; + assert_array_equals( + results.map(result => `${result.xKey}:${result.yKey}`).sort(), + expectedKeys, + 'The results should include all the index keys put in the store'); + + assert_array_equals( + results.map(result => result[`${indexName}Key`]), + results.map(result => result[`${indexName}Key`]).sort(), + 'The results should be sorted by the index key'); + }); + promises.push(promise); + } + } + + return Promise.all(promises).then(() => database); +} + +promise_test(testCase => { + return buildDatabases(testCase, false) + .then(() => openNamedDatabase(testCase, 'x', 1)) + .then(database => checkDatabaseContent(testCase, database, 'x', false)) + .then(database => database.close()) + .then(() => openNamedDatabase(testCase, 'y', 1)) + .then(database => checkDatabaseContent(testCase, database, 'y', false)) + .then(database => database.close()); +}, 'Non-unique index keys'); + +promise_test(testCase => { + return buildDatabases(testCase, true) + .then(() => openNamedDatabase(testCase, 'x', 1)) + .then(database => checkDatabaseContent(testCase, database, 'x', true)) + .then(database => database.close()) + .then(() => openNamedDatabase(testCase, 'y', 1)) + .then(database => checkDatabaseContent(testCase, database, 'y', true)) + .then(database => database.close()); +}, 'Unique index keys'); + +</script> |