summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/web-locks/ifAvailable.tentative.https.any.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/web-locks/ifAvailable.tentative.https.any.js')
-rw-r--r--testing/web-platform/tests/web-locks/ifAvailable.tentative.https.any.js163
1 files changed, 163 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-locks/ifAvailable.tentative.https.any.js b/testing/web-platform/tests/web-locks/ifAvailable.tentative.https.any.js
new file mode 100644
index 0000000000..63e6d568fe
--- /dev/null
+++ b/testing/web-platform/tests/web-locks/ifAvailable.tentative.https.any.js
@@ -0,0 +1,163 @@
+// META: title=Web Locks API: ifAvailable option
+// META: script=resources/helpers.js
+// META: global=window,dedicatedworker,sharedworker,serviceworker
+
+'use strict';
+
+promise_test(async t => {
+ const res = self.uniqueName(t);
+ let callback_called = false;
+ await navigator.locks.request(res, {ifAvailable: true}, async lock => {
+ callback_called = true;
+ assert_not_equals(lock, null, 'lock should be granted');
+ });
+ assert_true(callback_called, 'callback should be called');
+}, 'Lock request with ifAvailable - lock available');
+
+promise_test(async t => {
+ const res = self.uniqueName(t);
+ let callback_called = false;
+ await navigator.locks.request(res, async lock => {
+ // Request would time out if |ifAvailable| was not specified.
+ const result = await navigator.locks.request(
+ res, {ifAvailable: true}, async lock => {
+ callback_called = true;
+ assert_equals(lock, null, 'lock should not be granted');
+ return 123;
+ });
+ assert_equals(result, 123, 'result should be value returned by callback');
+ });
+ assert_true(callback_called, 'callback should be called');
+}, 'Lock request with ifAvailable - lock not available');
+
+promise_test(async t => {
+ const res = self.uniqueName(t);
+ let callback_called = false;
+ await navigator.locks.request(res, async lock => {
+ try {
+ // Request would time out if |ifAvailable| was not specified.
+ await navigator.locks.request(res, {ifAvailable: true}, async lock => {
+ callback_called = true;
+ assert_equals(lock, null, 'lock should not be granted');
+ throw 123;
+ });
+ assert_unreached('call should throw');
+ } catch (ex) {
+ assert_equals(ex, 123, 'ex should be value thrown by callback');
+ }
+ });
+ assert_true(callback_called, 'callback should be called');
+}, 'Lock request with ifAvailable - lock not available, callback throws');
+
+promise_test(async t => {
+ const res = self.uniqueName(t);
+ let callback_called = false;
+ await navigator.locks.request(res, async lock => {
+ // Request with a different name - should be grantable.
+ await navigator.locks.request('different', {ifAvailable: true}, async lock => {
+ callback_called = true;
+ assert_not_equals(lock, null, 'lock should be granted');
+ });
+ });
+ assert_true(callback_called, 'callback should be called');
+}, 'Lock request with ifAvailable - unrelated lock held');
+
+promise_test(async t => {
+ const res = self.uniqueName(t);
+ let callback_called = false;
+ await navigator.locks.request(res, {mode: 'shared'}, async lock => {
+ await navigator.locks.request(
+ res, {mode: 'shared', ifAvailable: true}, async lock => {
+ callback_called = true;
+ assert_not_equals(lock, null, 'lock should be granted');
+ });
+ });
+ assert_true(callback_called, 'callback should be called');
+}, 'Shared lock request with ifAvailable - shared lock held');
+
+promise_test(async t => {
+ const res = self.uniqueName(t);
+ let callback_called = false;
+ await navigator.locks.request(res, {mode: 'shared'}, async lock => {
+ // Request would time out if |ifAvailable| was not specified.
+ await navigator.locks.request(res, {ifAvailable: true}, async lock => {
+ callback_called = true;
+ assert_equals(lock, null, 'lock should not be granted');
+ });
+ });
+ assert_true(callback_called, 'callback should be called');
+}, 'Exclusive lock request with ifAvailable - shared lock held');
+
+promise_test(async t => {
+ const res = self.uniqueName(t);
+ let callback_called = false;
+ await navigator.locks.request(res, async lock => {
+ // Request would time out if |ifAvailable| was not specified.
+ await navigator.locks.request(
+ res, {mode: 'shared', ifAvailable: true}, async lock => {
+ callback_called = true;
+ assert_equals(lock, null, 'lock should not be granted');
+ });
+ });
+ assert_true(callback_called, 'callback should be called');
+}, 'Shared lock request with ifAvailable - exclusive lock held');
+
+promise_test(async t => {
+ const res = self.uniqueName(t);
+ let callback_called = false;
+ await navigator.locks.request(res, async lock => {
+ callback_called = true;
+ const test_error = {name: 'test'};
+ const p = navigator.locks.request(
+ res, {ifAvailable: true}, lock => {
+ assert_equals(lock, null, 'lock should not be available');
+ throw test_error;
+ });
+ assert_equals(Promise.resolve(p), p, 'request() result is a Promise');
+ await promise_rejects_exactly(t, test_error, p, 'result should reject');
+ });
+ assert_true(callback_called, 'callback should be called');
+}, 'Returned Promise rejects if callback throws synchronously');
+
+promise_test(async t => {
+ const res = self.uniqueName(t);
+ let callback_called = false;
+ await navigator.locks.request(res, async lock => {
+ callback_called = true;
+ const test_error = {name: 'test'};
+ const p = navigator.locks.request(
+ res, {ifAvailable: true}, async lock => {
+ assert_equals(lock, null, 'lock should not be available');
+ throw test_error;
+ });
+ assert_equals(Promise.resolve(p), p, 'request() result is a Promise');
+ await promise_rejects_exactly(t, test_error, p, 'result should reject');
+ });
+ assert_true(callback_called, 'callback should be called');
+}, 'Returned Promise rejects if async callback yields rejected promise');
+
+// Regression test for: https://crbug.com/840994
+promise_test(async t => {
+ const res1 = self.uniqueName(t);
+ const res2 = self.uniqueName(t);
+ let callback1_called = false;
+ await navigator.locks.request(res1, async lock => {
+ callback1_called = true;
+ let callback2_called = false;
+ await navigator.locks.request(res2, async lock => {
+ callback2_called = true;
+ });
+ assert_true(callback2_called, 'callback2 should be called');
+
+ let callback3_called = false;
+ await navigator.locks.request(res2, {ifAvailable: true}, async lock => {
+ callback3_called = true;
+ // This request would fail if the "is this grantable?" test
+ // failed, e.g. due to the release without a pending request
+ // skipping steps.
+ assert_not_equals(lock, null, 'Lock should be available');
+ });
+ assert_true(callback3_called, 'callback2 should be called');
+ });
+ assert_true(callback1_called, 'callback1 should be called');
+}, 'Locks are available once previous release is processed');