@@ -50,6 +50,90 @@ describe("withLock", () => {
5050 expect ( isLockActive ( scope1 , key1 ) ) . toBe ( false ) ;
5151 } ) ;
5252
53+ test ( "lock works with acquireLockSignal" , async ( ) => {
54+ const scope1 = { } ;
55+ const key1 = "key" ;
56+
57+ const waitForEnoughMicrotasks = async ( ) => {
58+ for ( let i = 0 ; i < 10 ; i ++ )
59+ await Promise . resolve ( ) ;
60+ } ;
61+
62+ let proceedLock1 : ( ( value : "something" ) => void ) | null = null ;
63+ let lock1Done = false ;
64+ let lock1Error : any = undefined ;
65+ const lock1Controller = new AbortController ( ) ;
66+ const lockPromise1 = withLock ( scope1 , key1 , lock1Controller . signal , async ( ) => {
67+ const res = await new Promise ( ( accept ) => {
68+ proceedLock1 = accept ;
69+ } ) ;
70+ lock1Done = true ;
71+ return res ;
72+ } )
73+ . catch ( ( error ) => {
74+ lock1Error = error ;
75+ } ) ;
76+
77+ let proceedLock2 : ( ( value : "something2" ) => void ) | null = null ;
78+ let lock2Done = false ;
79+ let lock2Error : any = undefined ;
80+ const lock2Controller = new AbortController ( ) ;
81+ withLock ( scope1 , key1 , lock2Controller . signal , async ( ) => {
82+ const res = await new Promise ( ( accept ) => {
83+ proceedLock2 = accept ;
84+ } ) ;
85+ lock2Done = true ;
86+ return res ;
87+ } )
88+ . catch ( ( error ) => {
89+ lock2Error = error ;
90+ } ) ;
91+
92+ expect ( proceedLock1 ) . not . toBeNull ( ) ;
93+ expect ( proceedLock2 ) . toBeNull ( ) ;
94+ expect ( lock1Error ) . toBeUndefined ( ) ;
95+ expect ( lock2Error ) . toBeUndefined ( ) ;
96+ expect ( lock1Done ) . toBe ( false ) ;
97+ expect ( lock2Done ) . toBe ( false ) ;
98+ expect ( isLockActive ( scope1 , key1 ) ) . toBe ( true ) ;
99+
100+ lock1Controller . abort ( new TestError ( ) ) ;
101+
102+ expect ( proceedLock1 ) . not . toBeNull ( ) ;
103+ expect ( proceedLock2 ) . toBeNull ( ) ;
104+ expect ( lock1Error ) . toBeUndefined ( ) ;
105+ expect ( lock2Error ) . toBeUndefined ( ) ;
106+ expect ( lock1Done ) . toBe ( false ) ;
107+ expect ( lock2Done ) . toBe ( false ) ;
108+ expect ( isLockActive ( scope1 , key1 ) ) . toBe ( true ) ;
109+
110+ lock2Controller . abort ( new TestError ( ) ) ;
111+
112+ expect ( proceedLock1 ) . not . toBeNull ( ) ;
113+ expect ( proceedLock2 ) . toBeNull ( ) ;
114+ expect ( lock1Error ) . toBeUndefined ( ) ;
115+ expect ( lock2Error ) . toBeUndefined ( ) ;
116+ expect ( lock1Done ) . toBe ( false ) ;
117+ expect ( lock2Done ) . toBe ( false ) ;
118+ expect ( isLockActive ( scope1 , key1 ) ) . toBe ( true ) ;
119+
120+ await waitForEnoughMicrotasks ( ) ;
121+
122+ expect ( proceedLock1 ) . not . toBeNull ( ) ;
123+ expect ( proceedLock2 ) . toBeNull ( ) ;
124+ expect ( lock1Error ) . toBeUndefined ( ) ;
125+ expect ( lock2Error ) . to . be . instanceof ( TestError ) ;
126+ expect ( lock1Done ) . toBe ( false ) ;
127+ expect ( lock2Done ) . toBe ( false ) ;
128+ expect ( isLockActive ( scope1 , key1 ) ) . toBe ( true ) ;
129+
130+ proceedLock1 ! ( "something" ) ;
131+ await expect ( lockPromise1 ) . resolves . toBe ( "something" ) ;
132+ expect ( isLockActive ( scope1 , key1 ) ) . toBe ( false ) ;
133+ expect ( proceedLock2 ) . toBeNull ( ) ;
134+ expect ( lock2Done ) . toBe ( false ) ;
135+ } ) ;
136+
53137 test ( "acquireLock" , async ( ) => {
54138 const scope1 = { } ;
55139 const key1 = "key" ;
@@ -82,6 +166,32 @@ describe("withLock", () => {
82166 expect ( isLockActive ( scope1 , key1 ) ) . toBe ( false ) ;
83167 } ) ;
84168
169+ test ( "acquireLock with acquireLockSignal" , async ( ) => {
170+ const scope1 = { } ;
171+ const key1 = "key" ;
172+
173+ const lock1Controller = new AbortController ( ) ;
174+ const lock1Promise = acquireLock ( scope1 , key1 , lock1Controller . signal ) ;
175+ expect ( isLockActive ( scope1 , key1 ) ) . toBe ( true ) ;
176+
177+ lock1Controller . abort ( new TestError ( ) ) ;
178+ expect ( isLockActive ( scope1 , key1 ) ) . toBe ( true ) ;
179+
180+ const lock1 = await lock1Promise ;
181+ expect ( isLockActive ( scope1 , key1 ) ) . toBe ( true ) ;
182+
183+ const lock2Controller = new AbortController ( ) ;
184+ const lock2Promise = acquireLock ( scope1 , key1 , lock2Controller . signal ) ;
185+
186+ lock2Controller . abort ( new TestError ( ) ) ;
187+ await expect ( lock2Promise ) . rejects . toBeInstanceOf ( TestError ) ;
188+
189+ lock1 . dispose ( ) ;
190+ await new Promise ( ( accept ) => setTimeout ( accept , 0 ) ) ;
191+
192+ expect ( isLockActive ( scope1 , key1 ) ) . toBe ( false ) ;
193+ } ) ;
194+
85195 test ( "call order" , async ( ) => {
86196 const scope1 = { } ;
87197 const key1 = "key" ;
@@ -155,4 +265,44 @@ describe("withLock", () => {
155265 await waitForEnoughMicrotasks ( ) ;
156266 expect ( lockReleased ) . toBe ( true ) ;
157267 } ) ;
268+
269+ test ( "waitForLockRelease with signal" , async ( ) => {
270+ const scope1 = { } ;
271+ const key1 = "key" ;
272+
273+ const lock1 = await acquireLock ( scope1 , key1 ) ;
274+
275+ const lockWithError2 = withLock ( scope1 , key1 , async ( ) => {
276+ throw new Error ( "some error" ) ;
277+ } ) ;
278+
279+ const lockReleasedSignal = new AbortController ( ) ;
280+
281+ let lockReleased = false ;
282+ const lockReleasePromise = ( async ( ) => {
283+ await waitForLockRelease ( scope1 , key1 , lockReleasedSignal . signal ) ;
284+ lockReleased = true ;
285+ } ) ( ) ;
286+
287+ expect ( lockReleased ) . toBe ( false ) ;
288+ lockReleasedSignal . abort ( new TestError ( ) ) ;
289+
290+ expect ( lockReleased ) . toBe ( false ) ;
291+ await expect ( lockReleasePromise ) . rejects . toBeInstanceOf ( TestError ) ;
292+ expect ( lockReleased ) . toBe ( false ) ;
293+
294+ lock1 . dispose ( ) ;
295+
296+ try {
297+ await lockWithError2 ;
298+ expect . unreachable ( "lockWithError2 should throw" ) ;
299+ } catch ( err ) {
300+ // do nothing
301+ }
302+ } ) ;
158303} ) ;
304+
305+
306+ class TestError extends Error {
307+
308+ }
0 commit comments