modestbench 0.3.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/README.md +45 -2
- package/dist/adapters/ava-adapter.cjs +421 -0
- package/dist/adapters/ava-adapter.cjs.map +1 -0
- package/dist/adapters/ava-adapter.d.cts +39 -0
- package/dist/adapters/ava-adapter.d.cts.map +1 -0
- package/dist/adapters/ava-adapter.d.ts +39 -0
- package/dist/adapters/ava-adapter.d.ts.map +1 -0
- package/dist/adapters/ava-adapter.js +384 -0
- package/dist/adapters/ava-adapter.js.map +1 -0
- package/dist/adapters/ava-hooks.cjs +66 -0
- package/dist/adapters/ava-hooks.cjs.map +1 -0
- package/dist/adapters/ava-hooks.d.cts +24 -0
- package/dist/adapters/ava-hooks.d.cts.map +1 -0
- package/dist/adapters/ava-hooks.d.ts +24 -0
- package/dist/adapters/ava-hooks.d.ts.map +1 -0
- package/dist/adapters/ava-hooks.js +61 -0
- package/dist/adapters/ava-hooks.js.map +1 -0
- package/dist/adapters/ava-register.cjs +16 -0
- package/dist/adapters/ava-register.cjs.map +1 -0
- package/dist/adapters/ava-register.d.cts +11 -0
- package/dist/adapters/ava-register.d.cts.map +1 -0
- package/dist/adapters/ava-register.d.ts +11 -0
- package/dist/adapters/ava-register.d.ts.map +1 -0
- package/dist/adapters/ava-register.js +14 -0
- package/dist/adapters/ava-register.js.map +1 -0
- package/dist/adapters/mocha-adapter.cjs +254 -0
- package/dist/adapters/mocha-adapter.cjs.map +1 -0
- package/dist/adapters/mocha-adapter.d.cts +26 -0
- package/dist/adapters/mocha-adapter.d.cts.map +1 -0
- package/dist/adapters/mocha-adapter.d.ts +26 -0
- package/dist/adapters/mocha-adapter.d.ts.map +1 -0
- package/dist/adapters/mocha-adapter.js +217 -0
- package/dist/adapters/mocha-adapter.js.map +1 -0
- package/dist/adapters/node-test-adapter.cjs +335 -0
- package/dist/adapters/node-test-adapter.cjs.map +1 -0
- package/dist/adapters/node-test-adapter.d.cts +41 -0
- package/dist/adapters/node-test-adapter.d.cts.map +1 -0
- package/dist/adapters/node-test-adapter.d.ts +41 -0
- package/dist/adapters/node-test-adapter.d.ts.map +1 -0
- package/dist/adapters/node-test-adapter.js +298 -0
- package/dist/adapters/node-test-adapter.js.map +1 -0
- package/dist/adapters/node-test-hooks.cjs +72 -0
- package/dist/adapters/node-test-hooks.cjs.map +1 -0
- package/dist/adapters/node-test-hooks.d.cts +24 -0
- package/dist/adapters/node-test-hooks.d.cts.map +1 -0
- package/dist/adapters/node-test-hooks.d.ts +24 -0
- package/dist/adapters/node-test-hooks.d.ts.map +1 -0
- package/dist/adapters/node-test-hooks.js +67 -0
- package/dist/adapters/node-test-hooks.js.map +1 -0
- package/dist/adapters/node-test-register.cjs +7 -0
- package/dist/adapters/node-test-register.cjs.map +1 -0
- package/dist/adapters/node-test-register.d.cts +2 -0
- package/dist/adapters/node-test-register.d.cts.map +1 -0
- package/dist/adapters/node-test-register.d.ts +2 -0
- package/dist/adapters/node-test-register.d.ts.map +1 -0
- package/dist/adapters/node-test-register.js +5 -0
- package/dist/adapters/node-test-register.js.map +1 -0
- package/dist/adapters/types.cjs +152 -0
- package/dist/adapters/types.cjs.map +1 -0
- package/dist/adapters/types.d.cts +112 -0
- package/dist/adapters/types.d.cts.map +1 -0
- package/dist/adapters/types.d.ts +112 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +148 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/cli/commands/init.cjs +21 -17
- package/dist/cli/commands/init.cjs.map +1 -1
- package/dist/cli/commands/init.d.cts.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +21 -17
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/run.cjs +6 -2
- package/dist/cli/commands/run.cjs.map +1 -1
- package/dist/cli/commands/run.js +6 -2
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/test.cjs +392 -0
- package/dist/cli/commands/test.cjs.map +1 -0
- package/dist/cli/commands/test.d.cts +38 -0
- package/dist/cli/commands/test.d.cts.map +1 -0
- package/dist/cli/commands/test.d.ts +38 -0
- package/dist/cli/commands/test.d.ts.map +1 -0
- package/dist/cli/commands/test.js +388 -0
- package/dist/cli/commands/test.js.map +1 -0
- package/dist/cli/index.cjs +72 -1
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +73 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/constants.cjs +13 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +12 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.ts +12 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +12 -0
- package/dist/constants.js.map +1 -1
- package/dist/core/engine.cjs +4 -0
- package/dist/core/engine.cjs.map +1 -1
- package/dist/core/engine.d.cts.map +1 -1
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +4 -0
- package/dist/core/engine.js.map +1 -1
- package/dist/core/engines/tinybench-engine.cjs +163 -131
- package/dist/core/engines/tinybench-engine.cjs.map +1 -1
- package/dist/core/engines/tinybench-engine.d.cts +6 -0
- package/dist/core/engines/tinybench-engine.d.cts.map +1 -1
- package/dist/core/engines/tinybench-engine.d.ts +6 -0
- package/dist/core/engines/tinybench-engine.d.ts.map +1 -1
- package/dist/core/engines/tinybench-engine.js +163 -131
- package/dist/core/engines/tinybench-engine.js.map +1 -1
- package/dist/core/stats-utils.cjs +4 -2
- package/dist/core/stats-utils.cjs.map +1 -1
- package/dist/core/stats-utils.d.cts +1 -1
- package/dist/core/stats-utils.d.cts.map +1 -1
- package/dist/core/stats-utils.d.ts +1 -1
- package/dist/core/stats-utils.d.ts.map +1 -1
- package/dist/core/stats-utils.js +4 -2
- package/dist/core/stats-utils.js.map +1 -1
- package/dist/errors/base.cjs +2 -1
- package/dist/errors/base.cjs.map +1 -1
- package/dist/errors/base.d.cts.map +1 -1
- package/dist/errors/base.d.ts.map +1 -1
- package/dist/errors/base.js +2 -1
- package/dist/errors/base.js.map +1 -1
- package/dist/formatters/history/compare.cjs.map +1 -1
- package/dist/formatters/history/compare.d.cts.map +1 -1
- package/dist/formatters/history/compare.d.ts.map +1 -1
- package/dist/formatters/history/compare.js.map +1 -1
- package/dist/formatters/history/list.cjs.map +1 -1
- package/dist/formatters/history/list.d.cts.map +1 -1
- package/dist/formatters/history/list.d.ts.map +1 -1
- package/dist/formatters/history/list.js.map +1 -1
- package/dist/reporters/human.cjs +83 -27
- package/dist/reporters/human.cjs.map +1 -1
- package/dist/reporters/human.d.cts +1 -0
- package/dist/reporters/human.d.cts.map +1 -1
- package/dist/reporters/human.d.ts +1 -0
- package/dist/reporters/human.d.ts.map +1 -1
- package/dist/reporters/human.js +83 -27
- package/dist/reporters/human.js.map +1 -1
- package/dist/reporters/simple.cjs +68 -21
- package/dist/reporters/simple.cjs.map +1 -1
- package/dist/reporters/simple.d.cts +1 -0
- package/dist/reporters/simple.d.cts.map +1 -1
- package/dist/reporters/simple.d.ts +1 -0
- package/dist/reporters/simple.d.ts.map +1 -1
- package/dist/reporters/simple.js +68 -21
- package/dist/reporters/simple.js.map +1 -1
- package/dist/services/config-manager.cjs +1 -1
- package/dist/services/config-manager.cjs.map +1 -1
- package/dist/services/config-manager.d.cts.map +1 -1
- package/dist/services/config-manager.d.ts.map +1 -1
- package/dist/services/config-manager.js +2 -2
- package/dist/services/config-manager.js.map +1 -1
- package/dist/services/file-loader.cjs.map +1 -1
- package/dist/services/file-loader.d.cts.map +1 -1
- package/dist/services/file-loader.d.ts.map +1 -1
- package/dist/services/file-loader.js.map +1 -1
- package/package.json +63 -35
- package/src/adapters/ava-adapter.ts +553 -0
- package/src/adapters/ava-hooks.ts +65 -0
- package/src/adapters/ava-register.ts +15 -0
- package/src/adapters/mocha-adapter.ts +284 -0
- package/src/adapters/node-test-adapter.ts +391 -0
- package/src/adapters/node-test-hooks.ts +71 -0
- package/src/adapters/node-test-register.ts +5 -0
- package/src/adapters/types.ts +281 -0
- package/src/cli/commands/init.ts +25 -17
- package/src/cli/commands/run.ts +9 -2
- package/src/cli/commands/test.ts +546 -0
- package/src/cli/index.ts +81 -1
- package/src/constants.ts +15 -0
- package/src/core/engine.ts +5 -0
- package/src/core/engines/tinybench-engine.ts +213 -141
- package/src/core/stats-utils.ts +5 -3
- package/src/errors/base.ts +3 -2
- package/src/formatters/history/compare.ts +1 -3
- package/src/formatters/history/list.ts +1 -3
- package/src/reporters/human.ts +107 -36
- package/src/reporters/simple.ts +81 -22
- package/src/services/config-manager.ts +4 -5
- package/src/services/file-loader.ts +2 -3
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ModestBench Test Framework Adapter Types
|
|
4
|
+
*
|
|
5
|
+
* Shared types for capturing test definitions from various test frameworks
|
|
6
|
+
* (Mocha, node:test, AVA) and converting them to modestbench benchmark format.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.capturedToBenchmark = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* Convert captured test file to modestbench benchmark definition
|
|
12
|
+
*
|
|
13
|
+
* Transforms the CapturedTestFile structure into the BenchmarkDefinition format
|
|
14
|
+
* that modestbench's engine can execute.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
*
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const captured = await adapter.capture('/path/to/test.js');
|
|
20
|
+
* const benchmark = capturedToBenchmark(captured);
|
|
21
|
+
* // benchmark.suites contains test suites converted to benchmark suites
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @param captured - The captured test file structure from a test framework
|
|
25
|
+
* adapter
|
|
26
|
+
* @returns A BenchmarkDefinition with suites containing benchmarks derived from
|
|
27
|
+
* tests
|
|
28
|
+
*/
|
|
29
|
+
const capturedToBenchmark = (captured) => {
|
|
30
|
+
const suites = {};
|
|
31
|
+
// Convert root-level tests to a default suite (AVA-style)
|
|
32
|
+
if (captured.rootTests.length > 0) {
|
|
33
|
+
suites['default'] = {
|
|
34
|
+
benchmarks: Object.fromEntries(captured.rootTests
|
|
35
|
+
.filter((t) => !t.skip)
|
|
36
|
+
.map((test) => [test.name, { fn: test.fn }])),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// Convert captured suites to benchmark suites
|
|
40
|
+
for (const suite of captured.rootSuites) {
|
|
41
|
+
const converted = convertSuite(suite);
|
|
42
|
+
if (converted) {
|
|
43
|
+
suites[suite.name] = converted;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { suites };
|
|
47
|
+
};
|
|
48
|
+
exports.capturedToBenchmark = capturedToBenchmark;
|
|
49
|
+
/**
|
|
50
|
+
* Convert a captured suite to benchmark suite format
|
|
51
|
+
*/
|
|
52
|
+
const convertSuite = (suite) => {
|
|
53
|
+
// Skip empty suites
|
|
54
|
+
const nonSkippedTests = suite.tests.filter((t) => !t.skip);
|
|
55
|
+
if (nonSkippedTests.length === 0 && suite.children.length === 0) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return suiteToRecord(suite);
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Create a wrapped test function that runs beforeEach/afterEach hooks
|
|
62
|
+
*
|
|
63
|
+
* The hooks run with each benchmark iteration, matching test framework
|
|
64
|
+
* semantics where beforeEach runs before each test execution.
|
|
65
|
+
*
|
|
66
|
+
* Hook ordering follows standard test framework conventions:
|
|
67
|
+
*
|
|
68
|
+
* - BeforeEach: runs in declaration order (FIFO)
|
|
69
|
+
* - AfterEach: runs in reverse declaration order (LIFO)
|
|
70
|
+
*/
|
|
71
|
+
const createWrappedTestFn = (testFn, hooks) => {
|
|
72
|
+
// If no per-test hooks, return original function
|
|
73
|
+
if (hooks.beforeEach.length === 0 && hooks.afterEach.length === 0) {
|
|
74
|
+
return testFn;
|
|
75
|
+
}
|
|
76
|
+
// Wrap with hooks
|
|
77
|
+
return async () => {
|
|
78
|
+
// Run beforeEach hooks in declaration order (FIFO)
|
|
79
|
+
for (const hook of hooks.beforeEach) {
|
|
80
|
+
await hook();
|
|
81
|
+
}
|
|
82
|
+
// Run test
|
|
83
|
+
await testFn();
|
|
84
|
+
// Run afterEach hooks in reverse order (LIFO), like most test frameworks
|
|
85
|
+
for (const hook of [...hooks.afterEach].reverse()) {
|
|
86
|
+
await hook();
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Flatten nested suites into a list of [prefixed-name, wrapped-fn] pairs
|
|
92
|
+
*/
|
|
93
|
+
const flattenSuiteTests = (suite, prefix) => {
|
|
94
|
+
const results = [];
|
|
95
|
+
// Add direct tests with prefix
|
|
96
|
+
for (const test of suite.tests) {
|
|
97
|
+
if (!test.skip) {
|
|
98
|
+
const wrappedFn = createWrappedTestFn(test.fn, suite.hooks);
|
|
99
|
+
results.push([`${prefix} > ${test.name}`, wrappedFn]);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Recursively add nested suite tests
|
|
103
|
+
for (const child of suite.children) {
|
|
104
|
+
const childResults = flattenSuiteTests(child, `${prefix} > ${child.name}`);
|
|
105
|
+
results.push(...childResults);
|
|
106
|
+
}
|
|
107
|
+
return results;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Helper to build the suite record structure
|
|
111
|
+
*/
|
|
112
|
+
const suiteToRecord = (suite) => {
|
|
113
|
+
const benchmarks = {};
|
|
114
|
+
// Add tests as benchmarks
|
|
115
|
+
for (const test of suite.tests) {
|
|
116
|
+
if (!test.skip) {
|
|
117
|
+
// Wrap test function with beforeEach/afterEach hooks
|
|
118
|
+
const wrappedFn = createWrappedTestFn(test.fn, suite.hooks);
|
|
119
|
+
benchmarks[test.name] = { fn: wrappedFn };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Flatten nested suites into flat benchmark names
|
|
123
|
+
// e.g., "Parent > Child > test" becomes "Child > test"
|
|
124
|
+
for (const child of suite.children) {
|
|
125
|
+
const childBenchmarks = flattenSuiteTests(child, child.name);
|
|
126
|
+
for (const [name, fn] of childBenchmarks) {
|
|
127
|
+
benchmarks[name] = { fn };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Combine before hooks into a single setup function
|
|
131
|
+
const setup = suite.hooks.before.length > 0
|
|
132
|
+
? async () => {
|
|
133
|
+
for (const hook of suite.hooks.before) {
|
|
134
|
+
await hook();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
: undefined;
|
|
138
|
+
// Combine after hooks into a single teardown function
|
|
139
|
+
const teardown = suite.hooks.after.length > 0
|
|
140
|
+
? async () => {
|
|
141
|
+
for (const hook of suite.hooks.after) {
|
|
142
|
+
await hook();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
: undefined;
|
|
146
|
+
return {
|
|
147
|
+
benchmarks,
|
|
148
|
+
...(setup && { setup }),
|
|
149
|
+
...(teardown && { teardown }),
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModestBench Test Framework Adapter Types
|
|
3
|
+
*
|
|
4
|
+
* Shared types for capturing test definitions from various test frameworks
|
|
5
|
+
* (Mocha, node:test, AVA) and converting them to modestbench benchmark format.
|
|
6
|
+
*/
|
|
7
|
+
import type { BenchmarkDefinition, BenchmarkSuite } from "../core/benchmark-schema.cjs";
|
|
8
|
+
/**
|
|
9
|
+
* A captured test suite (describe block) from a test framework
|
|
10
|
+
*/
|
|
11
|
+
export interface CapturedSuite {
|
|
12
|
+
/** Nested child suites */
|
|
13
|
+
readonly children: CapturedSuite[];
|
|
14
|
+
/** Lifecycle hooks for the suite */
|
|
15
|
+
readonly hooks: SuiteHooks;
|
|
16
|
+
/** Suite name */
|
|
17
|
+
readonly name: string;
|
|
18
|
+
/** Tests in this suite */
|
|
19
|
+
readonly tests: CapturedTest[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A captured test function from a test framework
|
|
23
|
+
*/
|
|
24
|
+
export interface CapturedTest {
|
|
25
|
+
/** Test function body */
|
|
26
|
+
readonly fn: () => Promise<void> | void;
|
|
27
|
+
/** Test name */
|
|
28
|
+
readonly name: string;
|
|
29
|
+
/** Whether this test is marked .only */
|
|
30
|
+
readonly only?: boolean;
|
|
31
|
+
/** Whether this test is marked .skip */
|
|
32
|
+
readonly skip?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Result of capturing tests from a single file
|
|
36
|
+
*/
|
|
37
|
+
export interface CapturedTestFile {
|
|
38
|
+
/** File path */
|
|
39
|
+
readonly filePath: string;
|
|
40
|
+
/** Test framework detected/used */
|
|
41
|
+
readonly framework: TestFramework;
|
|
42
|
+
/** Root-level suites (describe blocks) */
|
|
43
|
+
readonly rootSuites: CapturedSuite[];
|
|
44
|
+
/** Root-level tests (not in any describe block - e.g., AVA) */
|
|
45
|
+
readonly rootTests: CapturedTest[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Converted benchmark suite structure
|
|
49
|
+
*
|
|
50
|
+
* This is what capturedToBenchmark produces for each suite.
|
|
51
|
+
*/
|
|
52
|
+
export type ConvertedBenchmarkSuite = Pick<BenchmarkSuite, 'benchmarks' | 'setup' | 'teardown'>;
|
|
53
|
+
/**
|
|
54
|
+
* Lifecycle hooks captured from a test suite
|
|
55
|
+
*/
|
|
56
|
+
export interface SuiteHooks {
|
|
57
|
+
/** Hooks to run once after all tests in suite */
|
|
58
|
+
readonly after: Array<() => Promise<void> | void>;
|
|
59
|
+
/** Hooks to run after each test */
|
|
60
|
+
readonly afterEach: Array<() => Promise<void> | void>;
|
|
61
|
+
/** Hooks to run once before all tests in suite */
|
|
62
|
+
readonly before: Array<() => Promise<void> | void>;
|
|
63
|
+
/** Hooks to run before each test */
|
|
64
|
+
readonly beforeEach: Array<() => Promise<void> | void>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Supported test frameworks
|
|
68
|
+
*/
|
|
69
|
+
export type TestFramework = 'ava' | 'mocha' | 'node-test';
|
|
70
|
+
/**
|
|
71
|
+
* Interface for test framework adapters
|
|
72
|
+
*
|
|
73
|
+
* Each adapter is responsible for:
|
|
74
|
+
*
|
|
75
|
+
* 1. Capturing test definitions from a test file
|
|
76
|
+
* 2. Normalizing them to the CapturedTestFile format
|
|
77
|
+
*/
|
|
78
|
+
export interface TestFrameworkAdapter {
|
|
79
|
+
/**
|
|
80
|
+
* Capture test definitions from a file
|
|
81
|
+
*
|
|
82
|
+
* This method loads the test file with appropriate hooks/mocks in place to
|
|
83
|
+
* capture test function definitions without executing the tests.
|
|
84
|
+
*
|
|
85
|
+
* @param filePath - Absolute path to the test file
|
|
86
|
+
* @returns Captured test structure
|
|
87
|
+
*/
|
|
88
|
+
capture(filePath: string): Promise<CapturedTestFile>;
|
|
89
|
+
/** Framework this adapter handles */
|
|
90
|
+
readonly framework: TestFramework;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Convert captured test file to modestbench benchmark definition
|
|
94
|
+
*
|
|
95
|
+
* Transforms the CapturedTestFile structure into the BenchmarkDefinition format
|
|
96
|
+
* that modestbench's engine can execute.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
*
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const captured = await adapter.capture('/path/to/test.js');
|
|
102
|
+
* const benchmark = capturedToBenchmark(captured);
|
|
103
|
+
* // benchmark.suites contains test suites converted to benchmark suites
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @param captured - The captured test file structure from a test framework
|
|
107
|
+
* adapter
|
|
108
|
+
* @returns A BenchmarkDefinition with suites containing benchmarks derived from
|
|
109
|
+
* tests
|
|
110
|
+
*/
|
|
111
|
+
export declare const capturedToBenchmark: (captured: CapturedTestFile) => BenchmarkDefinition;
|
|
112
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACf,qCAAoC;AAErC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC;IACnC,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,iBAAiB;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,gBAAgB;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB;IAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,0CAA0C;IAC1C,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,CAAC;IACrC,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,YAAY,EAAE,CAAC;CACpC;AAED;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,cAAc,EACd,YAAY,GAAG,OAAO,GAAG,UAAU,CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAClD,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACtD,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACnD,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,OAAO,GAAG,WAAW,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAErD,qCAAqC;IACrC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU,gBAAgB,KACzB,mBAuBF,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModestBench Test Framework Adapter Types
|
|
3
|
+
*
|
|
4
|
+
* Shared types for capturing test definitions from various test frameworks
|
|
5
|
+
* (Mocha, node:test, AVA) and converting them to modestbench benchmark format.
|
|
6
|
+
*/
|
|
7
|
+
import type { BenchmarkDefinition, BenchmarkSuite } from "../core/benchmark-schema.js";
|
|
8
|
+
/**
|
|
9
|
+
* A captured test suite (describe block) from a test framework
|
|
10
|
+
*/
|
|
11
|
+
export interface CapturedSuite {
|
|
12
|
+
/** Nested child suites */
|
|
13
|
+
readonly children: CapturedSuite[];
|
|
14
|
+
/** Lifecycle hooks for the suite */
|
|
15
|
+
readonly hooks: SuiteHooks;
|
|
16
|
+
/** Suite name */
|
|
17
|
+
readonly name: string;
|
|
18
|
+
/** Tests in this suite */
|
|
19
|
+
readonly tests: CapturedTest[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A captured test function from a test framework
|
|
23
|
+
*/
|
|
24
|
+
export interface CapturedTest {
|
|
25
|
+
/** Test function body */
|
|
26
|
+
readonly fn: () => Promise<void> | void;
|
|
27
|
+
/** Test name */
|
|
28
|
+
readonly name: string;
|
|
29
|
+
/** Whether this test is marked .only */
|
|
30
|
+
readonly only?: boolean;
|
|
31
|
+
/** Whether this test is marked .skip */
|
|
32
|
+
readonly skip?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Result of capturing tests from a single file
|
|
36
|
+
*/
|
|
37
|
+
export interface CapturedTestFile {
|
|
38
|
+
/** File path */
|
|
39
|
+
readonly filePath: string;
|
|
40
|
+
/** Test framework detected/used */
|
|
41
|
+
readonly framework: TestFramework;
|
|
42
|
+
/** Root-level suites (describe blocks) */
|
|
43
|
+
readonly rootSuites: CapturedSuite[];
|
|
44
|
+
/** Root-level tests (not in any describe block - e.g., AVA) */
|
|
45
|
+
readonly rootTests: CapturedTest[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Converted benchmark suite structure
|
|
49
|
+
*
|
|
50
|
+
* This is what capturedToBenchmark produces for each suite.
|
|
51
|
+
*/
|
|
52
|
+
export type ConvertedBenchmarkSuite = Pick<BenchmarkSuite, 'benchmarks' | 'setup' | 'teardown'>;
|
|
53
|
+
/**
|
|
54
|
+
* Lifecycle hooks captured from a test suite
|
|
55
|
+
*/
|
|
56
|
+
export interface SuiteHooks {
|
|
57
|
+
/** Hooks to run once after all tests in suite */
|
|
58
|
+
readonly after: Array<() => Promise<void> | void>;
|
|
59
|
+
/** Hooks to run after each test */
|
|
60
|
+
readonly afterEach: Array<() => Promise<void> | void>;
|
|
61
|
+
/** Hooks to run once before all tests in suite */
|
|
62
|
+
readonly before: Array<() => Promise<void> | void>;
|
|
63
|
+
/** Hooks to run before each test */
|
|
64
|
+
readonly beforeEach: Array<() => Promise<void> | void>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Supported test frameworks
|
|
68
|
+
*/
|
|
69
|
+
export type TestFramework = 'ava' | 'mocha' | 'node-test';
|
|
70
|
+
/**
|
|
71
|
+
* Interface for test framework adapters
|
|
72
|
+
*
|
|
73
|
+
* Each adapter is responsible for:
|
|
74
|
+
*
|
|
75
|
+
* 1. Capturing test definitions from a test file
|
|
76
|
+
* 2. Normalizing them to the CapturedTestFile format
|
|
77
|
+
*/
|
|
78
|
+
export interface TestFrameworkAdapter {
|
|
79
|
+
/**
|
|
80
|
+
* Capture test definitions from a file
|
|
81
|
+
*
|
|
82
|
+
* This method loads the test file with appropriate hooks/mocks in place to
|
|
83
|
+
* capture test function definitions without executing the tests.
|
|
84
|
+
*
|
|
85
|
+
* @param filePath - Absolute path to the test file
|
|
86
|
+
* @returns Captured test structure
|
|
87
|
+
*/
|
|
88
|
+
capture(filePath: string): Promise<CapturedTestFile>;
|
|
89
|
+
/** Framework this adapter handles */
|
|
90
|
+
readonly framework: TestFramework;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Convert captured test file to modestbench benchmark definition
|
|
94
|
+
*
|
|
95
|
+
* Transforms the CapturedTestFile structure into the BenchmarkDefinition format
|
|
96
|
+
* that modestbench's engine can execute.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
*
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const captured = await adapter.capture('/path/to/test.js');
|
|
102
|
+
* const benchmark = capturedToBenchmark(captured);
|
|
103
|
+
* // benchmark.suites contains test suites converted to benchmark suites
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @param captured - The captured test file structure from a test framework
|
|
107
|
+
* adapter
|
|
108
|
+
* @returns A BenchmarkDefinition with suites containing benchmarks derived from
|
|
109
|
+
* tests
|
|
110
|
+
*/
|
|
111
|
+
export declare const capturedToBenchmark: (captured: CapturedTestFile) => BenchmarkDefinition;
|
|
112
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACf,oCAAoC;AAErC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC;IACnC,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,iBAAiB;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,gBAAgB;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB;IAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,0CAA0C;IAC1C,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,CAAC;IACrC,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,YAAY,EAAE,CAAC;CACpC;AAED;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,cAAc,EACd,YAAY,GAAG,OAAO,GAAG,UAAU,CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAClD,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACtD,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACnD,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,OAAO,GAAG,WAAW,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAErD,qCAAqC;IACrC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU,gBAAgB,KACzB,mBAuBF,CAAC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModestBench Test Framework Adapter Types
|
|
3
|
+
*
|
|
4
|
+
* Shared types for capturing test definitions from various test frameworks
|
|
5
|
+
* (Mocha, node:test, AVA) and converting them to modestbench benchmark format.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Convert captured test file to modestbench benchmark definition
|
|
9
|
+
*
|
|
10
|
+
* Transforms the CapturedTestFile structure into the BenchmarkDefinition format
|
|
11
|
+
* that modestbench's engine can execute.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
*
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const captured = await adapter.capture('/path/to/test.js');
|
|
17
|
+
* const benchmark = capturedToBenchmark(captured);
|
|
18
|
+
* // benchmark.suites contains test suites converted to benchmark suites
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @param captured - The captured test file structure from a test framework
|
|
22
|
+
* adapter
|
|
23
|
+
* @returns A BenchmarkDefinition with suites containing benchmarks derived from
|
|
24
|
+
* tests
|
|
25
|
+
*/
|
|
26
|
+
export const capturedToBenchmark = (captured) => {
|
|
27
|
+
const suites = {};
|
|
28
|
+
// Convert root-level tests to a default suite (AVA-style)
|
|
29
|
+
if (captured.rootTests.length > 0) {
|
|
30
|
+
suites['default'] = {
|
|
31
|
+
benchmarks: Object.fromEntries(captured.rootTests
|
|
32
|
+
.filter((t) => !t.skip)
|
|
33
|
+
.map((test) => [test.name, { fn: test.fn }])),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// Convert captured suites to benchmark suites
|
|
37
|
+
for (const suite of captured.rootSuites) {
|
|
38
|
+
const converted = convertSuite(suite);
|
|
39
|
+
if (converted) {
|
|
40
|
+
suites[suite.name] = converted;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { suites };
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Convert a captured suite to benchmark suite format
|
|
47
|
+
*/
|
|
48
|
+
const convertSuite = (suite) => {
|
|
49
|
+
// Skip empty suites
|
|
50
|
+
const nonSkippedTests = suite.tests.filter((t) => !t.skip);
|
|
51
|
+
if (nonSkippedTests.length === 0 && suite.children.length === 0) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return suiteToRecord(suite);
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Create a wrapped test function that runs beforeEach/afterEach hooks
|
|
58
|
+
*
|
|
59
|
+
* The hooks run with each benchmark iteration, matching test framework
|
|
60
|
+
* semantics where beforeEach runs before each test execution.
|
|
61
|
+
*
|
|
62
|
+
* Hook ordering follows standard test framework conventions:
|
|
63
|
+
*
|
|
64
|
+
* - BeforeEach: runs in declaration order (FIFO)
|
|
65
|
+
* - AfterEach: runs in reverse declaration order (LIFO)
|
|
66
|
+
*/
|
|
67
|
+
const createWrappedTestFn = (testFn, hooks) => {
|
|
68
|
+
// If no per-test hooks, return original function
|
|
69
|
+
if (hooks.beforeEach.length === 0 && hooks.afterEach.length === 0) {
|
|
70
|
+
return testFn;
|
|
71
|
+
}
|
|
72
|
+
// Wrap with hooks
|
|
73
|
+
return async () => {
|
|
74
|
+
// Run beforeEach hooks in declaration order (FIFO)
|
|
75
|
+
for (const hook of hooks.beforeEach) {
|
|
76
|
+
await hook();
|
|
77
|
+
}
|
|
78
|
+
// Run test
|
|
79
|
+
await testFn();
|
|
80
|
+
// Run afterEach hooks in reverse order (LIFO), like most test frameworks
|
|
81
|
+
for (const hook of [...hooks.afterEach].reverse()) {
|
|
82
|
+
await hook();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Flatten nested suites into a list of [prefixed-name, wrapped-fn] pairs
|
|
88
|
+
*/
|
|
89
|
+
const flattenSuiteTests = (suite, prefix) => {
|
|
90
|
+
const results = [];
|
|
91
|
+
// Add direct tests with prefix
|
|
92
|
+
for (const test of suite.tests) {
|
|
93
|
+
if (!test.skip) {
|
|
94
|
+
const wrappedFn = createWrappedTestFn(test.fn, suite.hooks);
|
|
95
|
+
results.push([`${prefix} > ${test.name}`, wrappedFn]);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Recursively add nested suite tests
|
|
99
|
+
for (const child of suite.children) {
|
|
100
|
+
const childResults = flattenSuiteTests(child, `${prefix} > ${child.name}`);
|
|
101
|
+
results.push(...childResults);
|
|
102
|
+
}
|
|
103
|
+
return results;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Helper to build the suite record structure
|
|
107
|
+
*/
|
|
108
|
+
const suiteToRecord = (suite) => {
|
|
109
|
+
const benchmarks = {};
|
|
110
|
+
// Add tests as benchmarks
|
|
111
|
+
for (const test of suite.tests) {
|
|
112
|
+
if (!test.skip) {
|
|
113
|
+
// Wrap test function with beforeEach/afterEach hooks
|
|
114
|
+
const wrappedFn = createWrappedTestFn(test.fn, suite.hooks);
|
|
115
|
+
benchmarks[test.name] = { fn: wrappedFn };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Flatten nested suites into flat benchmark names
|
|
119
|
+
// e.g., "Parent > Child > test" becomes "Child > test"
|
|
120
|
+
for (const child of suite.children) {
|
|
121
|
+
const childBenchmarks = flattenSuiteTests(child, child.name);
|
|
122
|
+
for (const [name, fn] of childBenchmarks) {
|
|
123
|
+
benchmarks[name] = { fn };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Combine before hooks into a single setup function
|
|
127
|
+
const setup = suite.hooks.before.length > 0
|
|
128
|
+
? async () => {
|
|
129
|
+
for (const hook of suite.hooks.before) {
|
|
130
|
+
await hook();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
: undefined;
|
|
134
|
+
// Combine after hooks into a single teardown function
|
|
135
|
+
const teardown = suite.hooks.after.length > 0
|
|
136
|
+
? async () => {
|
|
137
|
+
for (const hook of suite.hooks.after) {
|
|
138
|
+
await hook();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
: undefined;
|
|
142
|
+
return {
|
|
143
|
+
benchmarks,
|
|
144
|
+
...(setup && { setup }),
|
|
145
|
+
...(teardown && { teardown }),
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ exports.handleInitCommand = void 0;
|
|
|
10
10
|
const promises_1 = require("node:fs/promises");
|
|
11
11
|
const node_path_1 = require("node:path");
|
|
12
12
|
const node_readline_1 = require("node:readline");
|
|
13
|
+
const constants_js_1 = require("../../constants.cjs");
|
|
13
14
|
const index_js_1 = require("../../errors/index.cjs");
|
|
14
15
|
/**
|
|
15
16
|
* Project templates for different initialization types
|
|
@@ -18,40 +19,44 @@ const PROJECT_TEMPLATES = {
|
|
|
18
19
|
advanced: {
|
|
19
20
|
configOptions: {
|
|
20
21
|
iterations: 1000,
|
|
21
|
-
outputDir:
|
|
22
|
-
pattern:
|
|
22
|
+
outputDir: constants_js_1.DEFAULT_OUTPUT_DIR,
|
|
23
|
+
pattern: `${constants_js_1.DEFAULT_BENCHMARK_DIR}/**/*.bench.{js,ts}`,
|
|
23
24
|
reporters: ['human', 'json'],
|
|
24
25
|
time: 10000,
|
|
25
26
|
warmup: 50,
|
|
26
27
|
},
|
|
27
28
|
description: 'Feature-rich setup with multiple reporters and configuration',
|
|
28
|
-
directories: [
|
|
29
|
+
directories: [constants_js_1.DEFAULT_BENCHMARK_DIR, constants_js_1.DEFAULT_OUTPUT_DIR],
|
|
29
30
|
name: 'Advanced Project',
|
|
30
31
|
},
|
|
31
32
|
basic: {
|
|
32
33
|
configOptions: {
|
|
33
34
|
iterations: 100,
|
|
34
|
-
outputDir:
|
|
35
|
-
pattern:
|
|
35
|
+
outputDir: constants_js_1.DEFAULT_OUTPUT_DIR,
|
|
36
|
+
pattern: `${constants_js_1.DEFAULT_BENCHMARK_DIR}/**/*.bench.{js,ts}`,
|
|
36
37
|
reporters: ['human'],
|
|
37
38
|
time: 5000,
|
|
38
39
|
},
|
|
39
40
|
description: 'Simple benchmark setup for small projects',
|
|
40
|
-
directories: [
|
|
41
|
+
directories: [constants_js_1.DEFAULT_BENCHMARK_DIR, constants_js_1.DEFAULT_OUTPUT_DIR],
|
|
41
42
|
name: 'Basic Project',
|
|
42
43
|
},
|
|
43
44
|
library: {
|
|
44
45
|
configOptions: {
|
|
45
46
|
bail: false,
|
|
46
47
|
iterations: 5000,
|
|
47
|
-
outputDir:
|
|
48
|
-
pattern:
|
|
48
|
+
outputDir: constants_js_1.DEFAULT_OUTPUT_DIR,
|
|
49
|
+
pattern: `${constants_js_1.DEFAULT_BENCHMARK_DIR}/**/*.bench.{js,ts}`,
|
|
49
50
|
reporters: ['human', 'json'],
|
|
50
51
|
time: 15000,
|
|
51
52
|
warmup: 100,
|
|
52
53
|
},
|
|
53
54
|
description: 'Optimized for library performance testing',
|
|
54
|
-
directories: [
|
|
55
|
+
directories: [
|
|
56
|
+
constants_js_1.DEFAULT_BENCHMARK_DIR,
|
|
57
|
+
`${constants_js_1.DEFAULT_BENCHMARK_DIR}/suites`,
|
|
58
|
+
constants_js_1.DEFAULT_OUTPUT_DIR,
|
|
59
|
+
],
|
|
55
60
|
name: 'Library Project',
|
|
56
61
|
},
|
|
57
62
|
};
|
|
@@ -317,7 +322,7 @@ const createAdditionalFiles = async (cwd, options) => {
|
|
|
317
322
|
// Create README.md
|
|
318
323
|
const readmeContent = `# Benchmark Project
|
|
319
324
|
|
|
320
|
-
This project uses [ModestBench](
|
|
325
|
+
This project uses [ModestBench](${constants_js_1.SITE_URL}) for performance testing.
|
|
321
326
|
|
|
322
327
|
## Getting Started
|
|
323
328
|
|
|
@@ -328,7 +333,7 @@ modestbench run
|
|
|
328
333
|
|
|
329
334
|
Run specific benchmarks:
|
|
330
335
|
\`\`\`bash
|
|
331
|
-
modestbench run "
|
|
336
|
+
modestbench run "${constants_js_1.DEFAULT_BENCHMARK_DIR}/array-*.bench.js"
|
|
332
337
|
\`\`\`
|
|
333
338
|
|
|
334
339
|
View benchmark history:
|
|
@@ -342,7 +347,7 @@ See \`modestbench.config.*\` for benchmark configuration options.
|
|
|
342
347
|
|
|
343
348
|
## Writing Benchmarks
|
|
344
349
|
|
|
345
|
-
Create new benchmark files in the
|
|
350
|
+
Create new benchmark files in the \`${constants_js_1.DEFAULT_BENCHMARK_DIR}/\` directory. See the examples for the expected format.
|
|
346
351
|
`;
|
|
347
352
|
try {
|
|
348
353
|
const readmePath = (0, node_path_1.resolve)(cwd, 'README.md');
|
|
@@ -360,7 +365,7 @@ Create new benchmark files in the \`bench/\` directory. See the examples for the
|
|
|
360
365
|
*/
|
|
361
366
|
const createOrUpdateGitignore = async (cwd, options) => {
|
|
362
367
|
const gitignorePath = (0, node_path_1.resolve)(cwd, '.gitignore');
|
|
363
|
-
const modestbenchEntry =
|
|
368
|
+
const modestbenchEntry = `${constants_js_1.DEFAULT_OUTPUT_DIR}/`;
|
|
364
369
|
const modestbenchSection = `\n# ModestBench history\n${modestbenchEntry}\n`;
|
|
365
370
|
try {
|
|
366
371
|
// Check if .gitignore exists
|
|
@@ -372,12 +377,12 @@ const createOrUpdateGitignore = async (cwd, options) => {
|
|
|
372
377
|
// File doesn't exist, will create new one
|
|
373
378
|
}
|
|
374
379
|
if (existingContent) {
|
|
375
|
-
// File exists, check if
|
|
380
|
+
// File exists, check if ${DEFAULT_OUTPUT_DIR}/ is already present
|
|
376
381
|
if (existingContent.includes(modestbenchEntry)) {
|
|
377
382
|
// Already present, nothing to do
|
|
378
383
|
return;
|
|
379
384
|
}
|
|
380
|
-
// Append
|
|
385
|
+
// Append default output dir entry (--yes or --quiet means auto-accept)
|
|
381
386
|
if (options?.yes || options?.quiet) {
|
|
382
387
|
// Ensure content ends with newline
|
|
383
388
|
const contentToAppend = existingContent.endsWith('\n')
|
|
@@ -400,7 +405,6 @@ build/
|
|
|
400
405
|
coverage/
|
|
401
406
|
|
|
402
407
|
# Benchmark output
|
|
403
|
-
benchmark-results/
|
|
404
408
|
${modestbenchSection}`;
|
|
405
409
|
await (0, promises_1.writeFile)(gitignorePath, newContent, 'utf8');
|
|
406
410
|
}
|
|
@@ -464,7 +468,7 @@ const createDirectories = async (directories, cwd) => {
|
|
|
464
468
|
* Create example benchmark files
|
|
465
469
|
*/
|
|
466
470
|
const createExampleBenchmarks = async (cwd) => {
|
|
467
|
-
const benchmarksDir = (0, node_path_1.resolve)(cwd,
|
|
471
|
+
const benchmarksDir = (0, node_path_1.resolve)(cwd, constants_js_1.DEFAULT_BENCHMARK_DIR);
|
|
468
472
|
for (const [name, example] of Object.entries(EXAMPLE_BENCHMARKS)) {
|
|
469
473
|
const filePath = (0, node_path_1.join)(benchmarksDir, example.filename);
|
|
470
474
|
try {
|