diff --git a/std/testing/README.md b/std/testing/README.md index 42ce49d5c8..82f8f91144 100644 --- a/std/testing/README.md +++ b/std/testing/README.md @@ -226,7 +226,7 @@ runBenchmarks({ silent: true }, (p: BenchmarkRunProgress) => { Registers a benchmark that will be run once `runBenchmarks` is called. -##### `runBenchmarks(opts?: BenchmarkRunOptions, progressCb?: (p: BenchmarkRunProgress) => void): Promise` +##### `runBenchmarks(opts?: BenchmarkRunOptions, progressCb?: (p: BenchmarkRunProgress) => void | Promise): Promise` Runs all registered benchmarks serially. Filtering can be applied by setting `BenchmarkRunOptions.only` and/or `BenchmarkRunOptions.skip` to regular diff --git a/std/testing/bench.ts b/std/testing/bench.ts index 87be641abe..a5e6490ac6 100644 --- a/std/testing/bench.ts +++ b/std/testing/bench.ts @@ -187,7 +187,7 @@ export function clearBenchmarks({ */ export async function runBenchmarks( { only = /[^\s]/, skip = /^\s*$/, silent }: BenchmarkRunOptions = {}, - progressCb?: (progress: BenchmarkRunProgress) => void + progressCb?: (progress: BenchmarkRunProgress) => void | Promise ): Promise { // Filtering candidates by the "only" and "skip" constraint const benchmarks: BenchmarkDefinition[] = candidates.filter( @@ -213,7 +213,7 @@ export async function runBenchmarks( }; // Publish initial progress data - publishProgress(progress, ProgressState.BenchmarkingStart, progressCb); + await publishProgress(progress, ProgressState.BenchmarkingStart, progressCb); if (!silent) { console.log( @@ -243,7 +243,7 @@ export async function runBenchmarks( // Init the progress of the running benchmark progress.running = { name, runsCount: runs, measuredRunsMs: [] }; // Publish starting of a benchmark - publishProgress(progress, ProgressState.BenchStart, progressCb); + await publishProgress(progress, ProgressState.BenchStart, progressCb); // Trying benchmark.func let result = ""; @@ -267,7 +267,11 @@ export async function runBenchmarks( // Adding partial result progress.running.measuredRunsMs.push(measuredMs); // Publish partial benchmark results - publishProgress(progress, ProgressState.BenchPartialResult, progressCb); + await publishProgress( + progress, + ProgressState.BenchPartialResult, + progressCb + ); // Resetting the benchmark clock clock.start = clock.stop = NaN; @@ -288,7 +292,11 @@ export async function runBenchmarks( // Clear currently running delete progress.running; // Publish results of the benchmark - publishProgress(progress, ProgressState.BenchResult, progressCb); + await publishProgress( + progress, + ProgressState.BenchResult, + progressCb + ); break; } } @@ -317,7 +325,7 @@ export async function runBenchmarks( // Indicate finished running delete progress.queued; // Publish final result in Cb too - publishProgress(progress, ProgressState.BenchmarkingEnd, progressCb); + await publishProgress(progress, ProgressState.BenchmarkingEnd, progressCb); if (!silent) { // Closing results @@ -340,12 +348,12 @@ export async function runBenchmarks( return benchmarkRunResult; } -function publishProgress( +async function publishProgress( progress: BenchmarkRunProgress, state: ProgressState, - progressCb?: (progress: BenchmarkRunProgress) => void -): void { - progressCb && progressCb(cloneProgressWithState(progress, state)); + progressCb?: (progress: BenchmarkRunProgress) => void | Promise +): Promise { + progressCb && (await progressCb(cloneProgressWithState(progress, state))); } function cloneProgressWithState( diff --git a/std/testing/bench_test.ts b/std/testing/bench_test.ts index a56d4fd555..0b101c22f3 100644 --- a/std/testing/bench_test.ts +++ b/std/testing/bench_test.ts @@ -338,6 +338,27 @@ test({ }, }); +test({ + name: "async progressCallback", + fn: async function (): Promise { + clearBenchmarks(); + dummyBench("single"); + + const asyncCallbacks = []; + + await runBenchmarks({ silent: true }, (progress) => { + return new Promise((resolve) => { + queueMicrotask(() => { + asyncCallbacks.push(progress); + resolve(); + }); + }); + }); + + assertEquals(asyncCallbacks.length, 5); + }, +}); + function dummyBench(name: string, runs = 1): void { bench({ name,