Skip to content

Commit

Permalink
refactor: factor out function type detection helpers
Browse files Browse the repository at this point in the history
Signed-off-by: Jérôme Benoit <[email protected]>
  • Loading branch information
jerome-benoit committed Oct 3, 2024
1 parent 25ac409 commit cada431
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 35 deletions.
33 changes: 13 additions & 20 deletions src/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
} from './constants.js'
import {
os,
AsyncFunction,
checkBenchmarkArgs,
colors,
cpuModel,
Expand All @@ -34,7 +33,7 @@ import {
} from './reporter/terminal/index.js'
import { runtime } from './runtime.js'
import { now } from './time.js'
import { isObject } from './utils.js'
import { isAsyncFunction, isFunction, isObject } from './utils.js'

let groupName = null
const groups = new Map()
Expand Down Expand Up @@ -69,16 +68,16 @@ export function group(name, cb = undefined) {
name != null &&
'string' !== typeof name &&
!isObject(name) &&
![Function, AsyncFunction].includes(name.constructor)
!isFunction(name)
)
throw new TypeError(
`expected string, object or function, got ${name.constructor.name}`
)
if ([Function, AsyncFunction].includes(name.constructor)) {
if (isFunction(name)) {
// biome-ignore lint/style/noParameterAssign: <explanation>
cb = name
}
if (![Function, AsyncFunction].includes(cb.constructor))
if (!isFunction(cb))
throw new TypeError(`expected function, got ${cb.constructor.name}`)
if (isObject(name)) {
if (name.name != null && 'string' !== typeof name.name)
Expand Down Expand Up @@ -109,17 +108,11 @@ export function group(name, cb = undefined) {
throw new TypeError(
`expected function as 'now' option, got ${name.now.constructor.name}`
)
if (
name.before != null &&
![Function, AsyncFunction].includes(name.before.constructor)
)
if (name.before != null && !isFunction(name.before))
throw new TypeError(
`expected function as 'before' option, got ${name.before.constructor.name}`
)
if (
name.after != null &&
![Function, AsyncFunction].includes(name.after.constructor)
)
if (name.after != null && !isFunction(name.after))
throw new TypeError(
`expected function as 'after' option, got ${name.after.constructor.name}`
)
Expand All @@ -138,7 +131,7 @@ export function group(name, cb = undefined) {
before: name.before ?? emptyFunction,
after: name.after ?? emptyFunction,
})
if (AsyncFunction === cb.constructor) {
if (isAsyncFunction(cb)) {
cb().then(() => {
groupName = null
})
Expand All @@ -162,7 +155,7 @@ export function group(name, cb = undefined) {
* @param {CallbackType} [opts.after=()=>{}] after hook
*/
export function bench(name, fn = undefined, opts = {}) {
if ([Function, AsyncFunction].includes(name.constructor)) {
if (isFunction(name)) {
// biome-ignore lint/style/noParameterAssign: <explanation>
fn = name
// biome-ignore lint/style/noParameterAssign: <explanation>
Expand All @@ -183,7 +176,7 @@ export function bench(name, fn = undefined, opts = {}) {
samples: opts.samples ?? defaultSamples,
warmup: opts.warmup ?? true,
baseline: false,
async: AsyncFunction === fn.constructor,
async: isAsyncFunction(fn),
})
}

Expand All @@ -202,7 +195,7 @@ export function bench(name, fn = undefined, opts = {}) {
* @param {CallbackType} [opts.after=()=>{}] after hook
*/
export function baseline(name, fn = undefined, opts = {}) {
if ([Function, AsyncFunction].includes(name.constructor)) {
if (isFunction(name)) {
// biome-ignore lint/style/noParameterAssign: <explanation>
fn = name
// biome-ignore lint/style/noParameterAssign: <explanation>
Expand All @@ -223,7 +216,7 @@ export function baseline(name, fn = undefined, opts = {}) {
samples: opts.samples ?? defaultSamples,
warmup: opts.warmup ?? true,
baseline: true,
async: AsyncFunction === fn.constructor,
async: isAsyncFunction(fn),
})
}

Expand Down Expand Up @@ -385,7 +378,7 @@ export async function run(opts = {}) {
log(dim(opts.colors, white(opts.colors, br(opts))))
}

AsyncFunction === groupOpts.before.constructor
isAsyncFunction(groupOpts.before)
? await groupOpts.before()
: groupOpts.before()

Expand All @@ -396,7 +389,7 @@ export async function run(opts = {}) {
groupOpts
)

AsyncFunction === groupOpts.after.constructor
isAsyncFunction(groupOpts.after)
? await groupOpts.after()
: groupOpts.after()
}
Expand Down
28 changes: 13 additions & 15 deletions src/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ import {
variance,
} from './stats-utils.js'
import { now } from './time.js'
import { checkDividend, isObject } from './utils.js'

export const AsyncFunction = (async () => {}).constructor
import {
AsyncFunction,
checkDividend,
isAsyncFunction,
isFunction,
isObject,
} from './utils.js'

export const version = (() => {
return {
Expand Down Expand Up @@ -141,7 +145,7 @@ export const gc = (() => {
})()

export const checkBenchmarkArgs = (fn, opts = {}) => {
if (![Function, AsyncFunction].includes(fn.constructor))
if (!isFunction(fn))
throw new TypeError(`expected function, got ${fn.constructor.name}`)
if (!isObject(opts))
throw new TypeError(`expected object, got ${opts.constructor.name}`)
Expand All @@ -165,17 +169,11 @@ export const checkBenchmarkArgs = (fn, opts = {}) => {
throw new TypeError(
`expected function as 'now' option, got ${opts.now.constructor.name}`
)
if (
opts.before != null &&
![Function, AsyncFunction].includes(opts.before.constructor)
)
if (opts.before != null && !isFunction(opts.before))
throw new TypeError(
`expected function as 'before' option, got ${opts.before.constructor.name}`
)
if (
opts.after != null &&
![Function, AsyncFunction].includes(opts.after.constructor)
)
if (opts.after != null && !isFunction(opts.after))
throw new TypeError(
`expected function as 'after' option, got ${opts.after.constructor.name}`
)
Expand Down Expand Up @@ -209,7 +207,7 @@ export async function measure(fn, opts = {}) {
`expected boolean as 'async' option, got ${opts.async.constructor.name}`
)

opts.async = opts.async ?? AsyncFunction === fn.constructor
opts.async = opts.async ?? isAsyncFunction(fn)
opts.time = opts.time ?? defaultTime
opts.samples = opts.samples ?? defaultSamples
opts.warmup =
Expand All @@ -222,8 +220,8 @@ export async function measure(fn, opts = {}) {
opts.before = opts.before ?? emptyFunction
opts.after = opts.after ?? emptyFunction

const asyncBefore = AsyncFunction === opts.before.constructor
const asyncAfter = AsyncFunction === opts.after.constructor
const asyncBefore = isAsyncFunction(opts.before)
const asyncAfter = isAsyncFunction(opts.after)

const asyncFunction = opts.async || asyncBefore || asyncAfter

Expand Down
10 changes: 10 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
export const isFunction = fn => {
return [Function, AsyncFunction].includes(fn.constructor)
}

export const AsyncFunction = (async () => {}).constructor

export const isAsyncFunction = fn => {
return AsyncFunction === fn.constructor
}

export const isObject = value => {
return Object.prototype.toString.call(value).slice(8, -1) === 'Object'
}
Expand Down

0 comments on commit cada431

Please sign in to comment.