@@ -7,58 +7,69 @@ export const hrtimeNow = () => nanoToMs(Number(process.hrtime.bigint()));
77
88export const now = ( ) => performance . now ( ) ;
99
10- function isPromiseLike < T > (
10+ /**
11+ * Checks if a value is a promise-like object.
12+ *
13+ * @param maybePromiseLike - the value to check
14+ * @returns true if the value is a promise-like object
15+ */
16+ const isPromiseLike = < T > (
1117 maybePromiseLike : any ,
12- ) : maybePromiseLike is PromiseLike < T > {
13- return (
14- maybePromiseLike !== null
15- && typeof maybePromiseLike === 'object'
16- && typeof maybePromiseLike . then === 'function'
17- ) ;
18- }
18+ ) : maybePromiseLike is PromiseLike < T > => maybePromiseLike !== null
19+ && typeof maybePromiseLike === 'object'
20+ && typeof maybePromiseLike . then === 'function' ;
1921
20- // eslint-disable-next-line @typescript-eslint/no-empty-function
21- const AsyncFunctionConstructor = ( async ( ) => { } ) . constructor ;
22+ type AsyncFunctionType < A extends unknown [ ] , R > = ( ...args : A ) => PromiseLike < R > ;
2223
2324/**
24- * An async function check method only consider runtime support async syntax
25+ * An async function check helper only considering runtime support async syntax
26+ *
27+ * @param fn - the function to check
28+ * @returns true if the function is an async function
2529 */
26- export const isAsyncFunction = ( fn : Fn ) => fn . constructor === AsyncFunctionConstructor ;
30+ const isAsyncFunction = (
31+ fn : Fn ,
32+ // eslint-disable-next-line @typescript-eslint/no-empty-function
33+ ) : fn is AsyncFunctionType < unknown [ ] , unknown > => fn ?. constructor === ( async ( ) => { } ) . constructor ;
2734
28- export const isAsyncTask = async ( task : Task ) => {
29- if ( isAsyncFunction ( task . fn ) ) {
35+ /**
36+ * An async function check helper considering runtime support async syntax and promise return
37+ *
38+ * @param fn - the function to check
39+ * @returns true if the function is an async function or returns a promise
40+ */
41+ export const isAsyncFnResource = async ( fn : Fn ) : Promise < boolean > => {
42+ if ( fn == null ) {
43+ return false ;
44+ }
45+ if ( isAsyncFunction ( fn ) ) {
3046 return true ;
3147 }
3248 try {
33- if ( task . opts . beforeEach != null ) {
34- try {
35- await task . opts . beforeEach . call ( task ) ;
36- } catch ( e ) {
37- // ignore
38- }
39- }
40- const call = task . fn ( ) ;
41- const promiseLike = isPromiseLike ( call ) ;
49+ const fnCall = fn ( ) ;
50+ const promiseLike = isPromiseLike ( fnCall ) ;
4251 if ( promiseLike ) {
52+ // silence promise rejection
4353 try {
44- await call ;
45- } catch ( e ) {
46- // ignore
47- }
48- }
49- if ( task . opts . afterEach != null ) {
50- try {
51- await task . opts . afterEach . call ( task ) ;
52- } catch ( e ) {
54+ await fnCall ;
55+ } catch {
5356 // ignore
5457 }
5558 }
5659 return promiseLike ;
57- } catch ( e ) {
60+ } catch {
5861 return false ;
5962 }
6063} ;
6164
65+ /**
66+ * An async task check helper considering runtime support async syntax and promise return
67+ *
68+ * @param task - the task to check
69+ * @returns true if the task is an async task
70+ */
71+ export const isAsyncTask = async ( task : Task ) : Promise < boolean > => isAsyncFnResource ( task ?. fn ) ;
72+
6273/**
6374 * Computes the average of a sample.
6475 *
@@ -69,7 +80,6 @@ export const average = (samples: number[]) => {
6980 if ( samples . length === 0 ) {
7081 throw new Error ( 'samples must not be empty' ) ;
7182 }
72-
7383 return samples . reduce ( ( a , b ) => a + b , 0 ) / samples . length || 0 ;
7484} ;
7585
0 commit comments