Bug 1942563 [wpt PR 50168] - IDB WPTs: Extend request related tests to workers, a=testonly
Automatic update from web-platform-tests IDB WPTs: Extend request related tests to workers The update modifies request related WPTs to run not only in window environments but also on dedicated, service, and shared workers. Bug: 41455766 Change-Id: I4160274ceb2909ec5e9c9a9b40c5f3573ba1f9d0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5912455 Commit-Queue: Garima Chadha <garimachadha@microsoft.com> Reviewed-by: Steve Becker <stevebe@microsoft.com> Reviewed-by: Rahul Singh <rahsin@microsoft.com> Auto-Submit: Garima Chadha <garimachadha@microsoft.com> Cr-Commit-Position: refs/heads/main@{#1408517} -- wpt-commits: 55e0dc19031e9f71f8821b5d64e59f3858ba6bef wpt-pr: 50168
This commit is contained in:
committed by
moz-wptsync-bot
parent
b7a0204010
commit
745a300fda
@@ -0,0 +1,85 @@
|
||||
// META: title=IndexedDB: request abort events are delivered in order
|
||||
// META: global=window,worker
|
||||
// META: script=resources/support-promises.js
|
||||
// META: script=resources/support.js
|
||||
|
||||
// Spec: https://w3c.github.io/IndexedDB/#abort-transaction
|
||||
|
||||
'use strict';
|
||||
|
||||
promise_test(testCase => {
|
||||
let requests;
|
||||
|
||||
return createDatabase(
|
||||
testCase,
|
||||
(database, transaction) => {
|
||||
createBooksStore(testCase, database);
|
||||
})
|
||||
.then(database => {
|
||||
const transaction = database.transaction(['books'], 'readwrite');
|
||||
const store = transaction.objectStore('books');
|
||||
const index = store.index('by_author');
|
||||
const cursorRequest = store.openCursor(IDBKeyRange.lowerBound(0));
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
cursorRequest.onerror = testCase.step_func(event => {
|
||||
event.preventDefault();
|
||||
reject(cursorRequest.error);
|
||||
});
|
||||
|
||||
cursorRequest.onsuccess = testCase.step_func(() => {
|
||||
const cursor = cursorRequest.result;
|
||||
requests = [
|
||||
() => store.get(123456),
|
||||
() => index.get('Fred'),
|
||||
() => store.count(),
|
||||
() => index.count(),
|
||||
() =>
|
||||
store.put({title: 'Bedrock II', author: 'Barney', isbn: 987}),
|
||||
() => store.getAll(),
|
||||
() => index.getAll(),
|
||||
() => store.get(999999),
|
||||
() => index.get('Nobody'),
|
||||
() => store.openCursor(IDBKeyRange.lowerBound(0)),
|
||||
() => index.openCursor(IDBKeyRange.lowerBound('')),
|
||||
() => {
|
||||
cursor.continue();
|
||||
return cursorRequest;
|
||||
},
|
||||
];
|
||||
|
||||
const results = [];
|
||||
const promises = [];
|
||||
for (let i = 0; i < requests.length; ++i) {
|
||||
promises.push(new Promise((resolve, reject) => {
|
||||
const requestId = i;
|
||||
const request = requests[i](store);
|
||||
request.onsuccess = testCase.step_func(() => {
|
||||
reject(new Error(
|
||||
'IDB requests should not succeed after transaction abort'));
|
||||
});
|
||||
request.onerror = testCase.step_func(event => {
|
||||
event.preventDefault();
|
||||
results.push([requestId, request.error]);
|
||||
resolve();
|
||||
});
|
||||
}));
|
||||
};
|
||||
transaction.abort();
|
||||
resolve(Promise.all(promises).then(() => results));
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(results => {
|
||||
assert_equals(
|
||||
results.length, requests.length,
|
||||
'Promise.all should resolve after all sub-promises resolve');
|
||||
for (let i = 0; i < requests.length; ++i) {
|
||||
assert_equals(
|
||||
results[i][0], i, 'error event order should match request order');
|
||||
assert_equals(
|
||||
results[i][1].name, 'AbortError',
|
||||
'transaction aborting should result in AbortError on all requests');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,83 +0,0 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf8">
|
||||
<meta name="timeout" content="long">
|
||||
<title>IndexedDB: request abort events are delivered in order</title>
|
||||
<link rel="help" href="https://w3c.github.io/IndexedDB/#abort-transaction">
|
||||
<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';
|
||||
|
||||
promise_test(testCase => {
|
||||
let requests;
|
||||
|
||||
return createDatabase(testCase, (database, transaction) => {
|
||||
createBooksStore(testCase, database);
|
||||
}).then(database => {
|
||||
const transaction = database.transaction(['books'], 'readwrite');
|
||||
const store = transaction.objectStore('books');
|
||||
const index = store.index('by_author');
|
||||
const cursorRequest = store.openCursor(IDBKeyRange.lowerBound(0));
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
cursorRequest.onerror = testCase.step_func(event => {
|
||||
event.preventDefault();
|
||||
reject(cursorRequest.error);
|
||||
});
|
||||
|
||||
cursorRequest.onsuccess = testCase.step_func(() => {
|
||||
const cursor = cursorRequest.result;
|
||||
requests = [
|
||||
() => store.get(123456),
|
||||
() => index.get('Fred'),
|
||||
() => store.count(),
|
||||
() => index.count(),
|
||||
() => store.put({title: 'Bedrock II', author: 'Barney', isbn: 987 }),
|
||||
() => store.getAll(),
|
||||
() => index.getAll(),
|
||||
() => store.get(999999),
|
||||
() => index.get('Nobody'),
|
||||
() => store.openCursor(IDBKeyRange.lowerBound(0)),
|
||||
() => index.openCursor(IDBKeyRange.lowerBound('')),
|
||||
() => { cursor.continue(); return cursorRequest; },
|
||||
];
|
||||
|
||||
const results = [];
|
||||
const promises = [];
|
||||
for (let i = 0; i < requests.length; ++i) {
|
||||
promises.push(new Promise((resolve, reject) => {
|
||||
const requestId = i;
|
||||
const request = requests[i](store);
|
||||
request.onsuccess = testCase.step_func(() => {
|
||||
reject(new Error(
|
||||
'IDB requests should not succeed after transaction abort'));
|
||||
});
|
||||
request.onerror = testCase.step_func(event => {
|
||||
event.preventDefault();
|
||||
results.push([requestId, request.error]);
|
||||
resolve();
|
||||
});
|
||||
}));
|
||||
};
|
||||
transaction.abort();
|
||||
resolve(Promise.all(promises).then(() => results));
|
||||
});
|
||||
});
|
||||
}).then(results => {
|
||||
assert_equals(
|
||||
results.length, requests.length,
|
||||
'Promise.all should resolve after all sub-promises resolve');
|
||||
for (let i = 0; i < requests.length; ++i) {
|
||||
assert_equals(
|
||||
results[i][0], i,
|
||||
'error event order should match request order');
|
||||
assert_equals(
|
||||
results[i][1].name, 'AbortError',
|
||||
'transaction aborting should result in AbortError on all requests');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@@ -1,13 +1,11 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf8">
|
||||
<meta name="timeout" content="long">
|
||||
<title>IndexedDB: request result events are delivered in order</title>
|
||||
<link rel="help" href="https://w3c.github.io/IndexedDB/#abort-transaction">
|
||||
<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>
|
||||
// META: title=IndexedDB: request result events are delivered in order
|
||||
// META: global=window,worker
|
||||
// META: script=resources/support-promises.js
|
||||
// META: script=resources/support.js
|
||||
// META: timeout=long
|
||||
|
||||
// Spec: https://w3c.github.io/IndexedDB/#abort-transaction
|
||||
|
||||
'use strict';
|
||||
|
||||
// Should be large enough to trigger large value handling in the IndexedDB
|
||||
@@ -15,10 +13,10 @@
|
||||
const wrapThreshold = 128 * 1024;
|
||||
|
||||
function populateStore(store) {
|
||||
store.put({id: 1, key: 'k1', value: largeValue(wrapThreshold, 1) });
|
||||
store.put({id: 2, key: 'k2', value: ['small-2'] });
|
||||
store.put({id: 3, key: 'k3', value: largeValue(wrapThreshold, 3) });
|
||||
store.put({id: 4, key: 'k4', value: ['small-4'] });
|
||||
store.put({id: 1, key: 'k1', value: largeValue(wrapThreshold, 1)});
|
||||
store.put({id: 2, key: 'k2', value: ['small-2']});
|
||||
store.put({id: 3, key: 'k3', value: largeValue(wrapThreshold, 3)});
|
||||
store.put({id: 4, key: 'k4', value: ['small-4']});
|
||||
}
|
||||
|
||||
// Assigns cursor indexes for operations that require open cursors.
|
||||
@@ -41,8 +39,8 @@ function openCursors(testCase, index, operations, onerror, onsuccess) {
|
||||
let request;
|
||||
switch (opcode) {
|
||||
case 'continue':
|
||||
request = index.openCursor(
|
||||
IDBKeyRange.lowerBound(`k${primaryKey - 1}`));
|
||||
request =
|
||||
index.openCursor(IDBKeyRange.lowerBound(`k${primaryKey - 1}`));
|
||||
break;
|
||||
case 'continue-empty':
|
||||
// k4 is the last key in the data set, so calling continue() will get
|
||||
@@ -77,19 +75,21 @@ function doOperation(testCase, store, index, operation, requestId, results) {
|
||||
let request;
|
||||
switch (opcode) {
|
||||
case 'add': // Tests returning a primary key.
|
||||
request = store.add(
|
||||
{ key: `k${primaryKey}`, value: [`small-${primaryKey}`] });
|
||||
request =
|
||||
store.add({key: `k${primaryKey}`, value: [`small-${primaryKey}`]});
|
||||
break;
|
||||
case 'put': // Tests returning a primary key.
|
||||
request = store.put(
|
||||
{ key: `k${primaryKey}`, value: [`small-${primaryKey}`] });
|
||||
request =
|
||||
store.put({key: `k${primaryKey}`, value: [`small-${primaryKey}`]});
|
||||
break;
|
||||
case 'put-with-id': // Tests returning success or a primary key.
|
||||
request = store.put(
|
||||
{ key: `k${primaryKey}`, value: [`small-${primaryKey}`],
|
||||
id: primaryKey });
|
||||
request = store.put({
|
||||
key: `k${primaryKey}`,
|
||||
value: [`small-${primaryKey}`],
|
||||
id: primaryKey
|
||||
});
|
||||
break;
|
||||
case 'get': // Tests returning a value.
|
||||
case 'get': // Tests returning a value.
|
||||
case 'get-empty': // Tests returning undefined.
|
||||
request = store.get(primaryKey);
|
||||
break;
|
||||
@@ -97,8 +97,8 @@ function doOperation(testCase, store, index, operation, requestId, results) {
|
||||
request = store.getAll();
|
||||
break;
|
||||
case 'error': // Tests returning an error.
|
||||
request = store.put(
|
||||
{ key: `k${primaryKey}`, value: [`small-${primaryKey}`] });
|
||||
request =
|
||||
store.put({key: `k${primaryKey}`, value: [`small-${primaryKey}`]});
|
||||
request.onerror = testCase.step_func(event => {
|
||||
event.preventDefault();
|
||||
results.push([requestId, request.error]);
|
||||
@@ -173,7 +173,8 @@ function checkOperationResult(operation, result, requestId) {
|
||||
const primaryKey = operation[1];
|
||||
|
||||
const expectedValue = (primaryKey == 1 || primaryKey == 3) ?
|
||||
largeValue(wrapThreshold, primaryKey) : [`small-${primaryKey}`];
|
||||
largeValue(wrapThreshold, primaryKey) :
|
||||
[`small-${primaryKey}`];
|
||||
|
||||
const requestIndex = result[0];
|
||||
assert_equals(
|
||||
@@ -211,7 +212,8 @@ function checkOperationResult(operation, result, requestId) {
|
||||
`get result ${i + 1} should match put value (key)`);
|
||||
|
||||
const expectedValue = (i == 0 || i == 2) ?
|
||||
largeValue(wrapThreshold, i + 1) : [`small-${i + 1}`];
|
||||
largeValue(wrapThreshold, i + 1) :
|
||||
[`small-${i + 1}`];
|
||||
assert_equals(
|
||||
object.value.join(','), object.value.join(','),
|
||||
`get result ${i + 1} should match put value (nested value)`);
|
||||
@@ -253,56 +255,48 @@ function checkOperationResult(operation, result, requestId) {
|
||||
|
||||
function eventsTest(label, operations) {
|
||||
promise_test(testCase => {
|
||||
return createDatabase(testCase, (database, transaction) => {
|
||||
const store = database.createObjectStore(
|
||||
'test-store', { autoIncrement: true, keyPath: 'id' });
|
||||
store.createIndex('test-index', 'key', { unique: true });
|
||||
populateStore(store);
|
||||
}).then(database => {
|
||||
const transaction = database.transaction(['test-store'], 'readwrite');
|
||||
const store = transaction.objectStore('test-store');
|
||||
const index = store.index('test-index');
|
||||
return new Promise((resolve, reject) => {
|
||||
openCursors(testCase, index, operations, reject, () => {
|
||||
const results = [];
|
||||
const promises = [];
|
||||
for (let i = 0; i < operations.length; ++i) {
|
||||
const promise = doOperation(
|
||||
testCase, store, index, operations[i], i, results);
|
||||
promises.push(promise);
|
||||
};
|
||||
resolve(Promise.all(promises).then(() => results));
|
||||
return createDatabase(
|
||||
testCase,
|
||||
(database, transaction) => {
|
||||
const store = database.createObjectStore(
|
||||
'test-store', {autoIncrement: true, keyPath: 'id'});
|
||||
store.createIndex('test-index', 'key', {unique: true});
|
||||
populateStore(store);
|
||||
})
|
||||
.then(database => {
|
||||
const transaction = database.transaction(['test-store'], 'readwrite');
|
||||
const store = transaction.objectStore('test-store');
|
||||
const index = store.index('test-index');
|
||||
return new Promise((resolve, reject) => {
|
||||
openCursors(testCase, index, operations, reject, () => {
|
||||
const results = [];
|
||||
const promises = [];
|
||||
for (let i = 0; i < operations.length; ++i) {
|
||||
const promise = doOperation(
|
||||
testCase, store, index, operations[i], i, results);
|
||||
promises.push(promise);
|
||||
};
|
||||
resolve(Promise.all(promises).then(() => results));
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(results => {
|
||||
assert_equals(
|
||||
results.length, operations.length,
|
||||
'Promise.all should resolve after all sub-promises resolve');
|
||||
for (let i = 0; i < operations.length; ++i)
|
||||
checkOperationResult(operations[i], results[i], i);
|
||||
});
|
||||
});
|
||||
}).then(results => {
|
||||
assert_equals(
|
||||
results.length, operations.length,
|
||||
'Promise.all should resolve after all sub-promises resolve');
|
||||
for (let i = 0; i < operations.length; ++i)
|
||||
checkOperationResult(operations[i], results[i], i);
|
||||
});
|
||||
}, label);
|
||||
}
|
||||
|
||||
eventsTest('small values', [
|
||||
['get', 2],
|
||||
['count', 4],
|
||||
['continue-empty', null],
|
||||
['get-empty', 5],
|
||||
['add', 5],
|
||||
['open', 2],
|
||||
['continue', 2],
|
||||
['get', 4],
|
||||
['get-empty', 6],
|
||||
['count', 5],
|
||||
['put-with-id', 5],
|
||||
['put', 6],
|
||||
['error', 3],
|
||||
['continue', 4],
|
||||
['count', 6],
|
||||
['get-empty', 7],
|
||||
['open', 4],
|
||||
['open-empty', 7],
|
||||
['get', 2], ['count', 4], ['continue-empty', null],
|
||||
['get-empty', 5], ['add', 5], ['open', 2],
|
||||
['continue', 2], ['get', 4], ['get-empty', 6],
|
||||
['count', 5], ['put-with-id', 5], ['put', 6],
|
||||
['error', 3], ['continue', 4], ['count', 6],
|
||||
['get-empty', 7], ['open', 4], ['open-empty', 7],
|
||||
['add', 7],
|
||||
]);
|
||||
|
||||
@@ -365,5 +359,3 @@ eventsTest('large values mixed with small values', [
|
||||
['error', 3],
|
||||
['count', 7],
|
||||
]);
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,70 @@
|
||||
// META: title=Bubbling and capturing of request events
|
||||
// META: global=window,worker
|
||||
// META: script=resources/support-promises.js
|
||||
// META: script=resources/support.js
|
||||
|
||||
'use strict';
|
||||
|
||||
async_test(t => {
|
||||
let events = [];
|
||||
|
||||
let open_rq = createdb(t);
|
||||
open_rq.onupgradeneeded =
|
||||
function(e) {
|
||||
let db = e.target.result;
|
||||
let txn = e.target.transaction;
|
||||
let store = db.createObjectStore('s');
|
||||
let rq1 = store.add('', 1);
|
||||
let rq2 = store.add('', 1);
|
||||
db.onerror = function() {};
|
||||
|
||||
log_request(' db', db);
|
||||
log_request('txn', txn);
|
||||
log_request('rq1', rq1);
|
||||
log_request('rq2', rq2);
|
||||
|
||||
// Don't let it get to abort
|
||||
db.addEventListener('error', function(e) {
|
||||
e.preventDefault()
|
||||
}, false);
|
||||
}
|
||||
|
||||
open_rq.onsuccess =
|
||||
function(e) {
|
||||
log('open_rq.success')(e);
|
||||
assert_array_equals(
|
||||
events,
|
||||
[
|
||||
'capture db.success', 'capture txn.success', 'capture rq1.success',
|
||||
'bubble rq1.success',
|
||||
|
||||
'capture db.error: ConstraintError',
|
||||
'capture txn.error: ConstraintError',
|
||||
'capture rq2.error: ConstraintError',
|
||||
'bubble rq2.error: ConstraintError',
|
||||
'bubble txn.error: ConstraintError',
|
||||
'bubble db.error: ConstraintError',
|
||||
|
||||
'open_rq.success'
|
||||
],
|
||||
'events');
|
||||
t.done();
|
||||
}
|
||||
|
||||
|
||||
function log_request(type, obj) {
|
||||
obj.addEventListener('success', log('capture ' + type + '.success'), true);
|
||||
obj.addEventListener('success', log('bubble ' + type + '.success'), false);
|
||||
obj.addEventListener('error', log('capture ' + type + '.error'), true);
|
||||
obj.addEventListener('error', log('bubble ' + type + '.error'), false);
|
||||
}
|
||||
|
||||
function log(msg) {
|
||||
return function(e) {
|
||||
if (e && e.target && e.target.error)
|
||||
events.push(msg + ': ' + e.target.error.name);
|
||||
else
|
||||
events.push(msg);
|
||||
};
|
||||
}
|
||||
}, 'IndexedDB Request Event Propagation: Bubbling and Capturing');
|
||||
@@ -1,69 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Bubbling and capturing of request events</title>
|
||||
<link rel="author" href="mailto:odinho@opera.com" title="Odin Hørthe Omdal">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=resources/support.js></script>
|
||||
|
||||
<script>
|
||||
var events = [];
|
||||
|
||||
var open_rq = createdb(async_test());
|
||||
open_rq.onupgradeneeded = function(e) {
|
||||
var db = e.target.result;
|
||||
var txn = e.target.transaction;
|
||||
var store = db.createObjectStore("s");
|
||||
var rq1 = store.add("", 1);
|
||||
var rq2 = store.add("", 1);
|
||||
db.onerror = function(){};
|
||||
|
||||
log_request(' db', db);
|
||||
log_request('txn', txn);
|
||||
log_request('rq1', rq1);
|
||||
log_request('rq2', rq2);
|
||||
|
||||
// Don't let it get to abort
|
||||
db.addEventListener('error', function(e) { e.preventDefault() }, false);
|
||||
}
|
||||
|
||||
open_rq.onsuccess = function(e) {
|
||||
log("open_rq.success")(e);
|
||||
assert_array_equals(events, [
|
||||
"capture db.success",
|
||||
"capture txn.success",
|
||||
"capture rq1.success",
|
||||
"bubble rq1.success",
|
||||
|
||||
"capture db.error: ConstraintError",
|
||||
"capture txn.error: ConstraintError",
|
||||
"capture rq2.error: ConstraintError",
|
||||
"bubble rq2.error: ConstraintError",
|
||||
"bubble txn.error: ConstraintError",
|
||||
"bubble db.error: ConstraintError",
|
||||
|
||||
"open_rq.success"
|
||||
],
|
||||
"events");
|
||||
this.done();
|
||||
}
|
||||
|
||||
|
||||
function log_request(type, obj) {
|
||||
obj.addEventListener('success', log('capture ' + type + '.success'), true);
|
||||
obj.addEventListener('success', log('bubble ' + type + '.success'), false);
|
||||
obj.addEventListener('error', log('capture ' + type + '.error'), true);
|
||||
obj.addEventListener('error', log('bubble ' + type + '.error'), false);
|
||||
}
|
||||
|
||||
function log(msg) {
|
||||
return function(e) {
|
||||
if(e && e.target && e.target.error)
|
||||
events.push(msg + ": " + e.target.error.name);
|
||||
else
|
||||
events.push(msg);
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id=log></div>
|
||||
Reference in New Issue
Block a user