/**
 * Copyright 2019 Twitter, Inc.
 * Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 */ import Semaphore from "../../src/jslib/Semaphore" ; import * as bluebird from "bluebird" ; const setImmediatePromise = ( ) => { return new Promise ( ( resolve ) => setImmediate ( resolve ) ) ; } ; test ( "hits promise when it gets to zero" , async ( ) => { const counter = new Semaphore ( ) ; const counts = [ ] ; counter . on ( "change" , ( count ? ) => counts . push ( count ) ) ; await counter . waitForZero ( ) ; counter . increment ( ) ; counter . increment ( ) ; let promise = counter . waitForZero ( ) ; expect ( promise . isPending ( ) ) . toBe ( true ) ; counter . decrement ( ) ; expect ( promise . isPending ( ) ) . toBe ( true ) ; counter . decrement ( ) ; expect ( promise . isPending ( ) ) . toBe ( false ) ; counter . increment ( ) ; promise = counter . waitForZero ( ) ; expect ( promise . isPending ( ) ) . toBe ( true ) ; counter . decrement ( ) ; expect ( promise . isPending ( ) ) . toBe ( false ) ; expect ( counts ) . toEqual ( [ 1 , 2 , 1 , 0 , 1 , 0 ] ) ; } ) ; test ( "locks as expected" , async ( ) => { const counter = new Semaphore ( { max : 3 } ) ; const counts = [ ] ; counter . on ( "change" , ( count ? ) => counts . push ( count ) ) ; let value = 0 ; counter . increment ( ) . then ( function ( ) { value ++ ; } ) ; counter . increment ( ) . then ( function ( ) { value ++ ; } ) ; await setImmediatePromise ( ) ; expect ( value ) . toEqual ( 2 ) ; counter . increment ( ) . then ( function ( ) { value ++ ; } ) ; await setImmediatePromise ( ) ; expect ( value ) . toEqual ( 3 ) ; expect ( counts ) . toEqual ( [ 1 , 2 , 3 ] ) ; counter . increment ( ) . then ( function ( ) { value ++ ; } ) ; await setImmediatePromise ( ) ; expect ( value ) . toEqual ( 3 ) ; await setImmediatePromise ( ) ; expect ( value ) . toEqual ( 3 ) ; expect ( counts ) . toEqual ( [ 1 , 2 , 3 ] ) ; let coroutineStarted = false ; const coroutinePromise = counter . withLock ( async function ( ) { coroutineStarted = true ; await bluebird . delay ( 150 ) ; return "OKAY!" ; } ) ; counter . decrement ( ) ; await setImmediatePromise ( ) ; expect ( value ) . toEqual ( 4 ) ; expect ( counts ) . toEqual ( [ 1 , 2 , 3 ] ) ; expect ( coroutineStarted ) . toEqual ( false ) ; await setImmediatePromise ( ) ; expect ( coroutineStarted ) . toEqual ( false ) ; counter . decrement ( ) ; await setImmediatePromise ( ) ; expect ( coroutineStarted ) . toEqual ( true ) ; expect ( counts ) . toEqual ( [ 1 , 2 , 3 ] ) ; expect ( await coroutinePromise ) . toBe ( "OKAY!" ) ; expect ( counter . getCount ( ) ) . toEqual ( 2 ) ; await bluebird . promisify ( process . nextTick ) ( ) ; expect ( counts ) . toEqual ( [ 1 , 2 , 3 , 2 ] ) ; value = 0 ; for ( let i = 0 ; i < 50 ; i ++ ) { counter . increment ( ) . then ( function ( ) { value ++ ; } ) ; } await setImmediatePromise ( ) ; expect ( value ) . toEqual ( 1 ) ; counter . setMax ( 10 ) ; await setImmediatePromise ( ) ; expect ( value ) . toEqual ( 8 ) ; counter . setMax ( null ) ; await setImmediatePromise ( ) ; expect ( value ) . toEqual ( 50 ) ; } ) ;