Skip to content

Commit 3c59c54

Browse files
authored
feat: throw error if provided hooks are not functions (#390)
1 parent c4091cb commit 3c59c54

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

src/task.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import {
2424
toError,
2525
} from './utils'
2626

27+
const hookNames = ['afterAll', 'beforeAll', 'beforeEach', 'afterEach'] as const
28+
2729
/**
2830
* A class that represents each benchmark task in Tinybench. It keeps track of the
2931
* results, name, the task function, the number times the task function has been executed, ...
@@ -94,6 +96,15 @@ export class Task extends EventTarget {
9496
this.#async = fnOpts.async ?? isFnAsyncResource(fn)
9597
this.#signal = fnOpts.signal
9698

99+
for (const hookName of hookNames) {
100+
if (this.#fnOpts[hookName] != null) {
101+
invariant(
102+
typeof this.#fnOpts[hookName] === 'function',
103+
`'${hookName}' must be a function if provided`
104+
)
105+
}
106+
}
107+
97108
if (this.#signal) {
98109
this.#signal.addEventListener(
99110
'abort',
@@ -264,7 +275,7 @@ export class Task extends EventTarget {
264275
time: number,
265276
iterations: number
266277
): Promise<{ error: Error, samples?: never } | { error?: never, samples?: Samples }> {
267-
if (this.#fnOpts.beforeAll != null) {
278+
if (this.#fnOpts.beforeAll) {
268279
try {
269280
await this.#fnOpts.beforeAll.call(this, mode)
270281
} catch (error) {
@@ -350,7 +361,7 @@ export class Task extends EventTarget {
350361
time: number,
351362
iterations: number
352363
): { error: Error, samples?: never } | { error?: never, samples?: Samples } {
353-
if (this.#fnOpts.beforeAll != null) {
364+
if (this.#fnOpts.beforeAll) {
354365
try {
355366
const beforeAllResult = this.#fnOpts.beforeAll.call(this, mode)
356367
invariant(
@@ -370,7 +381,7 @@ export class Task extends EventTarget {
370381
return
371382
}
372383
try {
373-
if (this.#fnOpts.beforeEach != null) {
384+
if (this.#fnOpts.beforeEach) {
374385
const beforeEachResult = this.#fnOpts.beforeEach.call(this, mode)
375386
invariant(
376387
!isPromiseLike(beforeEachResult),
@@ -383,7 +394,7 @@ export class Task extends EventTarget {
383394
samples.push(taskTime)
384395
totalTime += taskTime
385396
} finally {
386-
if (this.#fnOpts.afterEach != null) {
397+
if (this.#fnOpts.afterEach) {
387398
const afterEachResult = this.#fnOpts.afterEach.call(this, mode)
388399
invariant(
389400
!isPromiseLike(afterEachResult),
@@ -406,7 +417,7 @@ export class Task extends EventTarget {
406417
return { error: toError(error) }
407418
}
408419

409-
if (this.#fnOpts.afterAll != null) {
420+
if (this.#fnOpts.afterAll) {
410421
try {
411422
const afterAllResult = this.#fnOpts.afterAll.call(this, mode)
412423
invariant(

test/hooks-errors.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { expect, test } from 'vitest'
22

3-
import { Bench } from '../src'
3+
import { Bench, FnHook } from '../src'
44

55
test.each(['warmup', 'run'])('%s error handling (async)', async mode => {
66
const bench = new Bench({ warmup: mode === 'warmup' })
@@ -84,6 +84,36 @@ test.each(['warmup', 'run'])('%s error handling (sync)', mode => {
8484
expect(bazTask.result.error).toStrictEqual(error)
8585
})
8686

87+
test('throw error when hooks are provided with no functions', () => {
88+
const bench = new Bench()
89+
90+
const notAFunction = new Error('Not a function') as unknown as FnHook
91+
92+
expect(() => {
93+
bench.add('test', () => 1, {
94+
beforeAll: notAFunction
95+
})
96+
}).toThrowError(new Error("'beforeAll' must be a function if provided"))
97+
98+
expect(() => {
99+
bench.add('test', () => 1, {
100+
beforeEach: notAFunction
101+
})
102+
}).toThrowError(new Error("'beforeEach' must be a function if provided"))
103+
104+
expect(() => {
105+
bench.add('test', () => 1, {
106+
afterAll: notAFunction
107+
})
108+
}).toThrowError(new Error("'afterAll' must be a function if provided"))
109+
110+
expect(() => {
111+
bench.add('test', () => 1, {
112+
afterEach: notAFunction
113+
})
114+
}).toThrowError(new Error("'afterEach' must be a function if provided"))
115+
})
116+
87117
test('hooks error handling (async)', async () => {
88118
const bench = new Bench()
89119

0 commit comments

Comments
 (0)