Skip to content

Commit 6dcb2e5

Browse files
committed
Move to suites.ts
1 parent 42b67ec commit 6dcb2e5

File tree

3 files changed

+77
-60
lines changed

3 files changed

+77
-60
lines changed
+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import 'reflect-metadata';
2+
import path from 'node:path';
3+
import type Bench from 'tinybench';
4+
import { assert } from 'n8n-workflow';
5+
import glob from 'fast-glob';
6+
import callsites from 'callsites';
7+
import type { Task } from '../types';
8+
9+
export const suites: {
10+
[suiteFilepath: string]: {
11+
hooks: Partial<{ beforeEach: () => Promise<void> }>;
12+
tasks: Task[];
13+
};
14+
} = {};
15+
16+
export function suiteCount() {
17+
return Object.keys(suites).length;
18+
}
19+
20+
function suiteFilePath() {
21+
const filePath = callsites()
22+
.map((site) => site.getFileName())
23+
.filter((site): site is string => site !== null)
24+
.find((site) => site.endsWith('.tasks.js'));
25+
26+
assert(filePath !== undefined);
27+
28+
return filePath;
29+
}
30+
31+
export async function collectSuites() {
32+
const files = await glob('**/*.tasks.js', {
33+
cwd: path.join('dist', 'benchmark'),
34+
absolute: true,
35+
});
36+
37+
for (const file of files) {
38+
await import(file);
39+
}
40+
}
41+
42+
export function registerSuites(bench: Bench) {
43+
for (const { tasks, hooks } of Object.values(suites)) {
44+
for (const t of tasks) {
45+
/**
46+
* `beforeAll` in tinybench is called once before all iterations of a single operation.
47+
* This is functionally equivalent to `beforeEach` in jest and vitest.
48+
*/
49+
const options = hooks.beforeEach ? { beforeAll: hooks.beforeEach } : {};
50+
51+
bench.add(t.description, t.operation, options);
52+
}
53+
}
54+
}
55+
56+
/**
57+
* Benchmarking API
58+
*/
59+
60+
export function task(description: string, operation: Task['operation']) {
61+
suites[suiteFilePath()] ||= { hooks: {}, tasks: [] };
62+
suites[suiteFilePath()].tasks.push({ description, operation });
63+
}
64+
65+
export function beforeEach(fn: () => Promise<void>) {
66+
suites[suiteFilePath()] ||= { hooks: {}, tasks: [] };
67+
suites[suiteFilePath()].hooks.beforeEach = fn;
68+
}

packages/cli/src/benchmark/main.ts

+7-60
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,20 @@
11
import 'reflect-metadata';
2-
import path from 'node:path';
3-
import { assert } from 'n8n-workflow';
4-
import glob from 'fast-glob';
5-
import callsites from 'callsites';
6-
import type { Task } from './types';
72
import { globalHooks } from './hooks';
83

94
/* eslint-disable import/no-extraneous-dependencies */
105
import { withCodSpeed } from '@codspeed/tinybench-plugin';
116
import Bench from 'tinybench';
7+
import { collectSuites, registerSuites, suiteCount } from './lib/suites';
128
/* eslint-enable import/no-extraneous-dependencies */
139

14-
const map: {
15-
[suiteFilepath: string]: {
16-
hooks: Partial<{ beforeEach: () => Promise<void> }>;
17-
tasks: Task[];
18-
};
19-
} = {};
20-
21-
function suiteFilePath() {
22-
const filePath = callsites()
23-
.map((site) => site.getFileName())
24-
.filter((site): site is string => site !== null)
25-
.find((site) => site.endsWith('.tasks.js'));
26-
27-
assert(filePath !== undefined);
28-
29-
return filePath;
30-
}
31-
32-
export function task(description: string, operation: Task['operation']) {
33-
map[suiteFilePath()] ||= { hooks: {}, tasks: [] };
34-
map[suiteFilePath()].tasks.push({ description, operation });
35-
}
36-
37-
export function beforeEach(fn: () => Promise<void>) {
38-
map[suiteFilePath()] ||= { hooks: {}, tasks: [] };
39-
map[suiteFilePath()].hooks.beforeEach = fn;
40-
}
41-
42-
async function loadTasks() {
43-
const files = await glob('**/*.tasks.js', {
44-
cwd: path.join('dist', 'benchmark'),
45-
absolute: true,
46-
});
47-
48-
for (const file of files) {
49-
await import(file);
50-
}
51-
}
10+
export { beforeEach, task } from './lib/suites';
5211

5312
async function main() {
54-
await loadTasks();
13+
await collectSuites();
5514

56-
const suitesCount = Object.keys(map).length;
15+
const count = suiteCount();
5716

58-
if (suitesCount === 0) {
17+
if (count === 0) {
5918
console.log('No benchmarking suites found');
6019
return;
6120
}
@@ -69,21 +28,9 @@ async function main() {
6928

7029
const bench = process.env.CI === 'true' ? withCodSpeed(_bench) : _bench;
7130

72-
for (const filePath of Object.keys(map)) {
73-
const { tasks, hooks } = map[filePath];
74-
75-
for (const t of tasks) {
76-
/**
77-
* `beforeAll` in tinybench is called once before all iterations of a single operation.
78-
* This is functionally equivalent to `beforeEach` in jest and vitest.
79-
*/
80-
const options = hooks.beforeEach ? { beforeAll: hooks.beforeEach } : {};
81-
82-
bench.add(t.description, t.operation, options);
83-
}
84-
}
31+
registerSuites(bench);
8532

86-
console.log(`Running ${suitesCount} benchmarking suites...`);
33+
console.log(`Running ${count} benchmarking suites...`);
8734

8835
await bench.run();
8936

packages/cli/src/benchmark/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ export type Task = {
33
description: string;
44
operation: () => Promise<void>;
55
};
6+
7+
export type Callback = () => void | Promise<void>;

0 commit comments

Comments
 (0)