import * as SUT from './index' ; import { WaitUntilOptions , defaultWaitUntilOptions , noWaitNoThrowOptions } from '../wait-until' ; describe ( 'wait for stability of' , ( ) : void => { test ( 'should wait until value function returns bar' , async ( ) : Promise < void > => { const wait = 500 ; const startTime = new Date ( ) . getTime ( ) ; const valueFunction = async ( ) : Promise < string > => { const endTime = new Date ( ) . getTime ( ) ; if ( endTime - startTime <= wait ) { return 'foo' ; } return 'bar' ; } ; await SUT . waitForStabilityOf ( valueFunction , 'cannot wait any more!' , { stabilityInMilliseconds : 1000 , } ) ; const result = await valueFunction ( ) ; expect ( result ) . toBe ( 'bar' ) ; } ) ; test ( 'should wait until value function returns a null' , async ( ) : Promise < void > => { const wait = 500 ; const startTime = new Date ( ) . getTime ( ) ; const valueFunction = async ( ) : Promise < null | undefined > => { const endTime = new Date ( ) . getTime ( ) ; if ( endTime - startTime <= wait ) { return undefined ; } return null ; } ; await SUT . waitForStabilityOf ( valueFunction , 'cannot wait any more!' , { stabilityInMilliseconds : 1000 , verbose : false , } ) ; const result = await valueFunction ( ) ; expect ( result ) . toBeNull ( ) ; } ) ; test ( 'should wait until value function returns undefined' , async ( ) : Promise < void > => { const wait = 500 ; const startTime = new Date ( ) . getTime ( ) ; const valueFunction = async ( ) : Promise < null | undefined > => { const endTime = new Date ( ) . getTime ( ) ; if ( endTime - startTime <= wait ) { return null ; } return undefined ; } ; await SUT . waitForStabilityOf ( valueFunction , 'cannot wait any more!' , { stabilityInMilliseconds : 1000 , } ) ; const result = await valueFunction ( ) ; expect ( result ) . toBeUndefined ( ) ; } ) ; test ( 'should wait until value function returns 0' , async ( ) : Promise < void > => { const wait = 500 ; const startTime = new Date ( ) . getTime ( ) ; const valueFunction = async ( ) : Promise < number > => { const endTime = new Date ( ) . getTime ( ) ; if ( endTime - startTime <= wait ) { return - 1 ; } return 0 ; } ; await SUT . waitForStabilityOf ( valueFunction , 'cannot wait any more!' , { stabilityInMilliseconds : 1000 , } ) ; const result = await valueFunction ( ) ; expect ( result ) . toBe ( 0 ) ; } ) ; test ( 'should wait until value function returns false' , async ( ) : Promise < void > => { const wait = 500 ; const startTime = new Date ( ) . getTime ( ) ; const valueFunction = async ( ) : Promise < boolean > => { const endTime = new Date ( ) . getTime ( ) ; if ( endTime - startTime <= wait ) { return true ; } return false ; } ; await SUT . waitForStabilityOf ( valueFunction , 'cannot wait any more!' , { stabilityInMilliseconds : 1000 , } ) ; const result = await valueFunction ( ) ; expect ( result ) . toBe ( false ) ; } ) ; test ( 'should not throw on timeout' , async ( ) : Promise < void > => { const wait = 500 ; const startTime = new Date ( ) . getTime ( ) ; const valueFunction = async ( ) : Promise < number > => { const endTime = new Date ( ) . getTime ( ) ; if ( endTime - startTime <= wait ) { return - 1 ; } return 0 ; } ; const options = { ... defaultWaitUntilOptions , timeoutInMilliseconds : 200 , throwOnTimeout : false , verbose : false , } ; await SUT . waitForStabilityOf ( valueFunction , 'cannot wait any more!' , options ) ; const result = await valueFunction ( ) ; expect ( result ) . toBe ( - 1 ) ; } ) ; test ( 'should not wait and not throw' , async ( ) : Promise < void > => { const options = { ... noWaitNoThrowOptions , } ; const predicate = async ( ) : Promise < boolean > => { return false ; } ; const startTime = new Date ( ) . getTime ( ) ; await SUT . waitForStabilityOf ( predicate , 'cannot wait any more!' , options ) ; const result = await predicate ( ) ; const endTime = new Date ( ) . getTime ( ) ; const duration = endTime - startTime ; console . log ( `measured duration with noWaitNoThrowOptions = ${ duration } ms` ) ; expect ( duration ) . toBeLessThan ( 3000 ) ; expect ( result ) . toBe ( false ) ; } ) ; test ( 'should throw when timeout is reached' , async ( ) : Promise < void > => { const options = { ... defaultWaitUntilOptions , stabilityInMilliseconds : 300 , timeoutInMilliseconds : 200 , verbose : false , } ; const predicate = async ( ) : Promise < boolean > => { return false ; } ; const expectedError = new Error ( 'cannot wait any more!' ) ; await SUT . waitForStabilityOf ( predicate , 'cannot wait any more!' , options ) . catch ( ( error ) : void => expect ( error ) . toMatchObject ( expectedError ) ) ; } ) ; test ( 'should throw func when timeout is reached' , async ( ) : Promise < void > => { const options = { ... defaultWaitUntilOptions , stabilityInMilliseconds : 300 , timeoutInMilliseconds : 200 , verbose : false , } ; const predicate = async ( ) : Promise < boolean > => { return false ; } ; const expectedError = new Error ( 'cannot wait any more!' ) ; await SUT . waitForStabilityOf ( predicate , ( ) => Promise . resolve ( 'cannot wait any more!' ) , options ) . catch ( ( error ) : void => expect ( error ) . toMatchObject ( expectedError ) ) ; } ) ; } ) ;