acquire.https.any.js (4989B)
1 // META: title=Web Locks API: navigator.locks.request method 2 // META: script=resources/helpers.js 3 // META: global=window,dedicatedworker,sharedworker,serviceworker 4 5 'use strict'; 6 7 promise_test(async t => { 8 const res = uniqueName(t); 9 await promise_rejects_js(t, TypeError, navigator.locks.request()); 10 await promise_rejects_js(t, TypeError, navigator.locks.request(res)); 11 }, 'navigator.locks.request requires a name and a callback'); 12 13 promise_test(async t => { 14 const res = uniqueName(t); 15 await promise_rejects_js( 16 t, TypeError, 17 navigator.locks.request(res, {mode: 'foo'}, lock => {})); 18 await promise_rejects_js( 19 t, TypeError, 20 navigator.locks.request(res, {mode: null }, lock => {})); 21 assert_equals(await navigator.locks.request( 22 res, {mode: 'exclusive'}, lock => lock.mode), 'exclusive', 23 'mode is exclusive'); 24 assert_equals(await navigator.locks.request( 25 res, {mode: 'shared'}, lock => lock.mode), 'shared', 26 'mode is shared'); 27 }, 'mode must be "shared" or "exclusive"'); 28 29 promise_test(async t => { 30 const res = uniqueName(t); 31 await promise_rejects_dom( 32 t, 'NotSupportedError', 33 navigator.locks.request( 34 res, {steal: true, ifAvailable: true}, lock => {}), 35 "A NotSupportedError should be thrown if both " + 36 "'steal' and 'ifAvailable' are specified."); 37 }, "The 'steal' and 'ifAvailable' options are mutually exclusive"); 38 39 promise_test(async t => { 40 const res = uniqueName(t); 41 await promise_rejects_dom( 42 t, 'NotSupportedError', 43 navigator.locks.request(res, {mode: 'shared', steal: true}, lock => {}), 44 'Request with mode=shared and steal=true should fail'); 45 }, "The 'steal' option must be used with exclusive locks"); 46 47 promise_test(async t => { 48 const res = uniqueName(t); 49 const controller = new AbortController(); 50 await promise_rejects_dom( 51 t, 'NotSupportedError', 52 navigator.locks.request( 53 res, {signal: controller.signal, steal: true}, lock => {}), 54 'Request with signal and steal=true should fail'); 55 }, "The 'signal' and 'steal' options are mutually exclusive"); 56 57 promise_test(async t => { 58 const res = uniqueName(t); 59 const controller = new AbortController(); 60 await promise_rejects_dom( 61 t, 'NotSupportedError', 62 navigator.locks.request( 63 res, {signal: controller.signal, ifAvailable: true}, lock => {}), 64 'Request with signal and ifAvailable=true should fail'); 65 }, "The 'signal' and 'ifAvailable' options are mutually exclusive"); 66 67 promise_test(async t => { 68 const res = uniqueName(t); 69 await promise_rejects_js( 70 t, TypeError, navigator.locks.request(res, undefined)); 71 await promise_rejects_js( 72 t, TypeError, navigator.locks.request(res, null)); 73 await promise_rejects_js( 74 t, TypeError, navigator.locks.request(res, 123)); 75 await promise_rejects_js( 76 t, TypeError, navigator.locks.request(res, 'abc')); 77 await promise_rejects_js( 78 t, TypeError, navigator.locks.request(res, [])); 79 await promise_rejects_js( 80 t, TypeError, navigator.locks.request(res, {})); 81 await promise_rejects_js( 82 t, TypeError, navigator.locks.request(res, new Promise(r => {}))); 83 }, 'callback must be a function'); 84 85 promise_test(async t => { 86 const res = uniqueName(t); 87 let release; 88 const promise = new Promise(r => { release = r; }); 89 90 let returned = navigator.locks.request(res, lock => { return promise; }); 91 92 const order = []; 93 94 returned.then(() => { order.push('returned'); }); 95 promise.then(() => { order.push('holding'); }); 96 97 release(); 98 99 await Promise.all([returned, promise]); 100 101 assert_array_equals(order, ['holding', 'returned']); 102 103 }, 'navigator.locks.request\'s returned promise resolves after' + 104 ' lock is released'); 105 106 promise_test(async t => { 107 const res = uniqueName(t); 108 const test_error = {name: 'test'}; 109 const p = navigator.locks.request(res, lock => { 110 throw test_error; 111 }); 112 assert_equals(Promise.resolve(p), p, 'request() result is a Promise'); 113 await promise_rejects_exactly(t, test_error, p, 'result should reject'); 114 }, 'Returned Promise rejects if callback throws synchronously'); 115 116 promise_test(async t => { 117 const res = uniqueName(t); 118 const test_error = {name: 'test'}; 119 const p = navigator.locks.request(res, async lock => { 120 throw test_error; 121 }); 122 assert_equals(Promise.resolve(p), p, 'request() result is a Promise'); 123 await promise_rejects_exactly(t, test_error, p, 'result should reject'); 124 }, 'Returned Promise rejects if callback throws asynchronously'); 125 126 promise_test(async t => { 127 const res = uniqueName(t); 128 let then_invoked = false; 129 const test_error = { then: _ => { then_invoked = true; } }; 130 const p = navigator.locks.request(res, async lock => { 131 throw test_error; 132 }); 133 assert_equals(Promise.resolve(p), p, 'request() result is a Promise'); 134 await promise_rejects_exactly(t, test_error, p, 'result should reject'); 135 assert_false(then_invoked, 'then() should not be invoked'); 136 }, 'If callback throws a thenable, its then() should not be invoked');