modestbench 0.0.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 +45 -0
- package/LICENSE.md +55 -0
- package/README.md +699 -0
- package/dist/bootstrap.cjs +37 -0
- package/dist/bootstrap.cjs.map +1 -0
- package/dist/bootstrap.d.cts +17 -0
- package/dist/bootstrap.d.cts.map +1 -0
- package/dist/bootstrap.d.ts +17 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +33 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli/commands/history.cjs +459 -0
- package/dist/cli/commands/history.cjs.map +1 -0
- package/dist/cli/commands/history.d.cts +34 -0
- package/dist/cli/commands/history.d.cts.map +1 -0
- package/dist/cli/commands/history.d.ts +34 -0
- package/dist/cli/commands/history.d.ts.map +1 -0
- package/dist/cli/commands/history.js +422 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/init.cjs +566 -0
- package/dist/cli/commands/init.cjs.map +1 -0
- package/dist/cli/commands/init.d.cts +26 -0
- package/dist/cli/commands/init.d.cts.map +1 -0
- package/dist/cli/commands/init.d.ts +26 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +562 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/run.cjs +285 -0
- package/dist/cli/commands/run.cjs.map +1 -0
- package/dist/cli/commands/run.d.cts +37 -0
- package/dist/cli/commands/run.d.cts.map +1 -0
- package/dist/cli/commands/run.d.ts +37 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +248 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/index.cjs +523 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +58 -0
- package/dist/cli/index.d.cts.map +1 -0
- package/dist/cli/index.d.ts +58 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +515 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/manager.cjs +370 -0
- package/dist/config/manager.cjs.map +1 -0
- package/dist/config/manager.d.cts +46 -0
- package/dist/config/manager.d.cts.map +1 -0
- package/dist/config/manager.d.ts +46 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +333 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/schema.cjs +182 -0
- package/dist/config/schema.cjs.map +1 -0
- package/dist/config/schema.d.cts +51 -0
- package/dist/config/schema.d.cts.map +1 -0
- package/dist/config/schema.d.ts +51 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +145 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/constants.cjs +22 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.d.cts +10 -0
- package/dist/constants.d.cts.map +1 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +19 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/benchmark-schema.cjs +135 -0
- package/dist/core/benchmark-schema.cjs.map +1 -0
- package/dist/core/benchmark-schema.d.cts +139 -0
- package/dist/core/benchmark-schema.d.cts.map +1 -0
- package/dist/core/benchmark-schema.d.ts +139 -0
- package/dist/core/benchmark-schema.d.ts.map +1 -0
- package/dist/core/benchmark-schema.js +132 -0
- package/dist/core/benchmark-schema.js.map +1 -0
- package/dist/core/engine.cjs +669 -0
- package/dist/core/engine.cjs.map +1 -0
- package/dist/core/engine.d.cts +128 -0
- package/dist/core/engine.d.cts.map +1 -0
- package/dist/core/engine.d.ts +128 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +632 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/engines/accurate-engine.cjs +292 -0
- package/dist/core/engines/accurate-engine.cjs.map +1 -0
- package/dist/core/engines/accurate-engine.d.cts +63 -0
- package/dist/core/engines/accurate-engine.d.cts.map +1 -0
- package/dist/core/engines/accurate-engine.d.ts +63 -0
- package/dist/core/engines/accurate-engine.d.ts.map +1 -0
- package/dist/core/engines/accurate-engine.js +288 -0
- package/dist/core/engines/accurate-engine.js.map +1 -0
- package/dist/core/engines/index.cjs +21 -0
- package/dist/core/engines/index.cjs.map +1 -0
- package/dist/core/engines/index.d.cts +16 -0
- package/dist/core/engines/index.d.cts.map +1 -0
- package/dist/core/engines/index.d.ts +16 -0
- package/dist/core/engines/index.d.ts.map +1 -0
- package/dist/core/engines/index.js +16 -0
- package/dist/core/engines/index.js.map +1 -0
- package/dist/core/engines/tinybench-engine.cjs +286 -0
- package/dist/core/engines/tinybench-engine.cjs.map +1 -0
- package/dist/core/engines/tinybench-engine.d.cts +18 -0
- package/dist/core/engines/tinybench-engine.d.cts.map +1 -0
- package/dist/core/engines/tinybench-engine.d.ts +18 -0
- package/dist/core/engines/tinybench-engine.d.ts.map +1 -0
- package/dist/core/engines/tinybench-engine.js +282 -0
- package/dist/core/engines/tinybench-engine.js.map +1 -0
- package/dist/core/error-manager.cjs +303 -0
- package/dist/core/error-manager.cjs.map +1 -0
- package/dist/core/error-manager.d.cts +77 -0
- package/dist/core/error-manager.d.cts.map +1 -0
- package/dist/core/error-manager.d.ts +77 -0
- package/dist/core/error-manager.d.ts.map +1 -0
- package/dist/core/error-manager.js +299 -0
- package/dist/core/error-manager.js.map +1 -0
- package/dist/core/loader.cjs +287 -0
- package/dist/core/loader.cjs.map +1 -0
- package/dist/core/loader.d.cts +55 -0
- package/dist/core/loader.d.cts.map +1 -0
- package/dist/core/loader.d.ts +55 -0
- package/dist/core/loader.d.ts.map +1 -0
- package/dist/core/loader.js +250 -0
- package/dist/core/loader.js.map +1 -0
- package/dist/core/stats-utils.cjs +99 -0
- package/dist/core/stats-utils.cjs.map +1 -0
- package/dist/core/stats-utils.d.cts +50 -0
- package/dist/core/stats-utils.d.cts.map +1 -0
- package/dist/core/stats-utils.d.ts +50 -0
- package/dist/core/stats-utils.d.ts.map +1 -0
- package/dist/core/stats-utils.js +94 -0
- package/dist/core/stats-utils.js.map +1 -0
- package/dist/index.cjs +64 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/progress/manager.cjs +325 -0
- package/dist/progress/manager.cjs.map +1 -0
- package/dist/progress/manager.d.cts +125 -0
- package/dist/progress/manager.d.cts.map +1 -0
- package/dist/progress/manager.d.ts +125 -0
- package/dist/progress/manager.d.ts.map +1 -0
- package/dist/progress/manager.js +321 -0
- package/dist/progress/manager.js.map +1 -0
- package/dist/reporters/csv.cjs +250 -0
- package/dist/reporters/csv.cjs.map +1 -0
- package/dist/reporters/csv.d.cts +92 -0
- package/dist/reporters/csv.d.cts.map +1 -0
- package/dist/reporters/csv.d.ts +92 -0
- package/dist/reporters/csv.d.ts.map +1 -0
- package/dist/reporters/csv.js +246 -0
- package/dist/reporters/csv.js.map +1 -0
- package/dist/reporters/human.cjs +516 -0
- package/dist/reporters/human.cjs.map +1 -0
- package/dist/reporters/human.d.cts +86 -0
- package/dist/reporters/human.d.cts.map +1 -0
- package/dist/reporters/human.d.ts +86 -0
- package/dist/reporters/human.d.ts.map +1 -0
- package/dist/reporters/human.js +509 -0
- package/dist/reporters/human.js.map +1 -0
- package/dist/reporters/index.cjs +17 -0
- package/dist/reporters/index.cjs.map +1 -0
- package/dist/reporters/index.d.cts +10 -0
- package/dist/reporters/index.d.cts.map +1 -0
- package/dist/reporters/index.d.ts +10 -0
- package/dist/reporters/index.d.ts.map +1 -0
- package/dist/reporters/index.js +10 -0
- package/dist/reporters/index.js.map +1 -0
- package/dist/reporters/json.cjs +215 -0
- package/dist/reporters/json.cjs.map +1 -0
- package/dist/reporters/json.d.cts +79 -0
- package/dist/reporters/json.d.cts.map +1 -0
- package/dist/reporters/json.d.ts +79 -0
- package/dist/reporters/json.d.ts.map +1 -0
- package/dist/reporters/json.js +211 -0
- package/dist/reporters/json.js.map +1 -0
- package/dist/reporters/registry.cjs +255 -0
- package/dist/reporters/registry.cjs.map +1 -0
- package/dist/reporters/registry.d.cts +155 -0
- package/dist/reporters/registry.d.cts.map +1 -0
- package/dist/reporters/registry.d.ts +155 -0
- package/dist/reporters/registry.d.ts.map +1 -0
- package/dist/reporters/registry.js +249 -0
- package/dist/reporters/registry.js.map +1 -0
- package/dist/reporters/simple.cjs +328 -0
- package/dist/reporters/simple.cjs.map +1 -0
- package/dist/reporters/simple.d.cts +51 -0
- package/dist/reporters/simple.d.cts.map +1 -0
- package/dist/reporters/simple.d.ts +51 -0
- package/dist/reporters/simple.d.ts.map +1 -0
- package/dist/reporters/simple.js +321 -0
- package/dist/reporters/simple.js.map +1 -0
- package/dist/schema/modestbench-config.schema.json +162 -0
- package/dist/storage/history.cjs +456 -0
- package/dist/storage/history.cjs.map +1 -0
- package/dist/storage/history.d.cts +99 -0
- package/dist/storage/history.d.cts.map +1 -0
- package/dist/storage/history.d.ts +99 -0
- package/dist/storage/history.d.ts.map +1 -0
- package/dist/storage/history.js +452 -0
- package/dist/storage/history.js.map +1 -0
- package/dist/types/cli.cjs +21 -0
- package/dist/types/cli.cjs.map +1 -0
- package/dist/types/cli.d.cts +296 -0
- package/dist/types/cli.d.cts.map +1 -0
- package/dist/types/cli.d.ts +296 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +18 -0
- package/dist/types/cli.js.map +1 -0
- package/dist/types/core.cjs +14 -0
- package/dist/types/core.cjs.map +1 -0
- package/dist/types/core.d.cts +380 -0
- package/dist/types/core.d.cts.map +1 -0
- package/dist/types/core.d.ts +380 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +13 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/index.cjs +27 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +11 -0
- package/dist/types/index.d.cts.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/interfaces.cjs +10 -0
- package/dist/types/interfaces.cjs.map +1 -0
- package/dist/types/interfaces.d.cts +381 -0
- package/dist/types/interfaces.d.cts.map +1 -0
- package/dist/types/interfaces.d.ts +381 -0
- package/dist/types/interfaces.d.ts.map +1 -0
- package/dist/types/interfaces.js +9 -0
- package/dist/types/interfaces.js.map +1 -0
- package/dist/types/utility.cjs +92 -0
- package/dist/types/utility.cjs.map +1 -0
- package/dist/types/utility.d.cts +330 -0
- package/dist/types/utility.d.cts.map +1 -0
- package/dist/types/utility.d.ts +330 -0
- package/dist/types/utility.d.ts.map +1 -0
- package/dist/types/utility.js +78 -0
- package/dist/types/utility.js.map +1 -0
- package/package.json +211 -0
- package/src/bootstrap.ts +35 -0
- package/src/cli/commands/history.ts +569 -0
- package/src/cli/commands/init.ts +658 -0
- package/src/cli/commands/run.ts +346 -0
- package/src/cli/index.ts +642 -0
- package/src/config/manager.ts +387 -0
- package/src/config/schema.ts +188 -0
- package/src/constants.ts +21 -0
- package/src/core/benchmark-schema.ts +185 -0
- package/src/core/engine.ts +888 -0
- package/src/core/engines/accurate-engine.ts +408 -0
- package/src/core/engines/index.ts +16 -0
- package/src/core/engines/tinybench-engine.ts +335 -0
- package/src/core/error-manager.ts +372 -0
- package/src/core/loader.ts +324 -0
- package/src/core/stats-utils.ts +135 -0
- package/src/index.ts +46 -0
- package/src/progress/manager.ts +415 -0
- package/src/reporters/csv.ts +368 -0
- package/src/reporters/human.ts +707 -0
- package/src/reporters/index.ts +10 -0
- package/src/reporters/json.ts +302 -0
- package/src/reporters/registry.ts +349 -0
- package/src/reporters/simple.ts +459 -0
- package/src/storage/history.ts +600 -0
- package/src/types/cli.ts +312 -0
- package/src/types/core.ts +414 -0
- package/src/types/index.ts +18 -0
- package/src/types/interfaces.ts +451 -0
- package/src/types/utility.ts +446 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModestBench Simple Console Reporter
|
|
3
|
+
*
|
|
4
|
+
* Provides plain text output without colors, ANSI codes, or decorative
|
|
5
|
+
* elements. Ideal for CI/CD environments, piping, or non-TTY outputs.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
BenchmarkRun,
|
|
12
|
+
FileResult,
|
|
13
|
+
ProgressState,
|
|
14
|
+
SuiteResult,
|
|
15
|
+
TaskResult,
|
|
16
|
+
} from '../types/index.js';
|
|
17
|
+
|
|
18
|
+
import { BaseReporter } from './registry.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Basic symbols for plain text output
|
|
22
|
+
*/
|
|
23
|
+
const symbols = {
|
|
24
|
+
approx: '≈',
|
|
25
|
+
checkmark: '√',
|
|
26
|
+
cross: '×',
|
|
27
|
+
plusMinus: '±',
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Simple console reporter with plain text output (no colors or progress bars)
|
|
32
|
+
*/
|
|
33
|
+
export class SimpleReporter extends BaseReporter {
|
|
34
|
+
private currentFile = '';
|
|
35
|
+
|
|
36
|
+
private currentSuite = '';
|
|
37
|
+
|
|
38
|
+
private failures: Array<{
|
|
39
|
+
error: string;
|
|
40
|
+
file: string;
|
|
41
|
+
suite: string;
|
|
42
|
+
task: string;
|
|
43
|
+
}> = [];
|
|
44
|
+
|
|
45
|
+
private readonly quiet: boolean;
|
|
46
|
+
|
|
47
|
+
private startTime = 0;
|
|
48
|
+
|
|
49
|
+
private suiteResults: TaskResult[] = [];
|
|
50
|
+
|
|
51
|
+
private readonly verbose: boolean;
|
|
52
|
+
|
|
53
|
+
constructor(
|
|
54
|
+
options: {
|
|
55
|
+
quiet?: boolean;
|
|
56
|
+
verbose?: boolean;
|
|
57
|
+
} = {},
|
|
58
|
+
) {
|
|
59
|
+
super('simple', options);
|
|
60
|
+
|
|
61
|
+
this.verbose = options.verbose ?? false;
|
|
62
|
+
this.quiet = options.quiet ?? false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
onEnd(run: BenchmarkRun): void {
|
|
66
|
+
if (this.quiet) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const duration = Date.now() - this.startTime;
|
|
71
|
+
const totalFiles = run.files.length;
|
|
72
|
+
|
|
73
|
+
// Calculate totals across all files
|
|
74
|
+
let totalSuites = 0;
|
|
75
|
+
let totalPassed = 0;
|
|
76
|
+
let totalFailed = 0;
|
|
77
|
+
|
|
78
|
+
for (const file of run.files) {
|
|
79
|
+
totalSuites += file.suites.length;
|
|
80
|
+
for (const suite of file.suites) {
|
|
81
|
+
totalPassed += suite.tasks.filter((t: TaskResult) => !t.error).length;
|
|
82
|
+
totalFailed += suite.tasks.filter((t: TaskResult) => t.error).length;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Results header
|
|
87
|
+
console.log('== Results');
|
|
88
|
+
console.log();
|
|
89
|
+
|
|
90
|
+
if (totalFailed > 0) {
|
|
91
|
+
console.log(`${symbols.cross} Failed: ${totalFailed}`);
|
|
92
|
+
console.log(`${symbols.checkmark} Passed: ${totalPassed}`);
|
|
93
|
+
} else {
|
|
94
|
+
console.log(`${symbols.checkmark} All tests passed: ${totalPassed}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.log(`- Files: ${totalFiles}`);
|
|
98
|
+
console.log(`- Suites: ${totalSuites}`);
|
|
99
|
+
console.log(
|
|
100
|
+
`${symbols.approx} Duration: ${this.formatDuration(duration * 1e6)}`,
|
|
101
|
+
);
|
|
102
|
+
console.log();
|
|
103
|
+
|
|
104
|
+
if (totalFailed > 0) {
|
|
105
|
+
console.log(`${symbols.cross.repeat(3)} Some benchmarks failed`);
|
|
106
|
+
|
|
107
|
+
// Display failed tasks with details
|
|
108
|
+
if (this.failures.length > 0) {
|
|
109
|
+
console.log();
|
|
110
|
+
console.log('Failed Tasks:');
|
|
111
|
+
console.log();
|
|
112
|
+
|
|
113
|
+
for (const failure of this.failures) {
|
|
114
|
+
const displayPath = this.formatPath(failure.file);
|
|
115
|
+
console.log(` ${displayPath} > ${failure.suite} > ${failure.task}`);
|
|
116
|
+
console.log(` ${failure.error}`);
|
|
117
|
+
console.log();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
console.log('All benchmarks completed successfully!');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
onError(error: Error): void {
|
|
126
|
+
if (this.quiet) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
console.error(`${symbols.cross.repeat(3)} Error:`, error.message);
|
|
131
|
+
|
|
132
|
+
if (this.verbose && error.stack) {
|
|
133
|
+
console.error(error.stack);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
onFileEnd(result: FileResult): void {
|
|
138
|
+
if (this.quiet) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const totalTasks = result.suites.reduce(
|
|
143
|
+
(sum, suite) => sum + suite.tasks.length,
|
|
144
|
+
0,
|
|
145
|
+
);
|
|
146
|
+
const totalPassed = result.suites.reduce(
|
|
147
|
+
(sum, suite) => sum + suite.tasks.filter((t) => !t.error).length,
|
|
148
|
+
0,
|
|
149
|
+
);
|
|
150
|
+
const totalFailed = totalTasks - totalPassed;
|
|
151
|
+
|
|
152
|
+
if (totalFailed > 0) {
|
|
153
|
+
console.log(
|
|
154
|
+
` ${symbols.cross} ${totalFailed} failed, ${totalPassed} passed`,
|
|
155
|
+
);
|
|
156
|
+
} else {
|
|
157
|
+
console.log(
|
|
158
|
+
` ${symbols.checkmark} ${totalPassed > 1 ? 'All ' : ''}${totalPassed} ${this.pluralize('task', totalPassed)} passed`,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
console.log();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
onFileStart(file: string): void {
|
|
166
|
+
this.currentFile = file;
|
|
167
|
+
|
|
168
|
+
if (this.quiet) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const displayPath = this.formatPath(file);
|
|
173
|
+
console.log(`-- ${displayPath}`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
onProgress(_state: ProgressState): void {
|
|
177
|
+
// Simple reporter does not display progress bars
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
onStart(run: BenchmarkRun): void {
|
|
182
|
+
this.startTime = Date.now();
|
|
183
|
+
this.failures = []; // Reset failures for new run
|
|
184
|
+
|
|
185
|
+
if (this.quiet) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
console.log('modestbench');
|
|
190
|
+
console.log();
|
|
191
|
+
|
|
192
|
+
if (run.environment) {
|
|
193
|
+
console.log(` node.js: ${run.environment.nodeVersion}`);
|
|
194
|
+
console.log(
|
|
195
|
+
` platform: ${run.environment.platform} ${run.environment.arch}`,
|
|
196
|
+
);
|
|
197
|
+
console.log(
|
|
198
|
+
` cpu: ${run.environment.cpu.model} (${run.environment.cpu.cores} cores)`,
|
|
199
|
+
);
|
|
200
|
+
console.log(` mem: ${this.formatBytes(run.environment.memory.total)}`);
|
|
201
|
+
console.log();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (run.git) {
|
|
205
|
+
console.log(` Git: ${run.git.commit}`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (run.ci) {
|
|
209
|
+
console.log(` CI: ${run.ci.provider}`);
|
|
210
|
+
console.log();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
onSuiteEnd(result: SuiteResult): void {
|
|
215
|
+
if (this.quiet) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Print all buffered task results with aligned columns
|
|
220
|
+
this.printAlignedSuiteResults();
|
|
221
|
+
|
|
222
|
+
// Skip displaying summary for the implicit "default" suite
|
|
223
|
+
if (result.name === 'default') {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const passed = result.tasks.filter((t) => !t.error).length;
|
|
228
|
+
const failed = result.tasks.filter((t) => t.error).length;
|
|
229
|
+
|
|
230
|
+
if (failed > 0) {
|
|
231
|
+
console.log(` ${symbols.cross} ${failed} failed, ${passed} passed`);
|
|
232
|
+
} else {
|
|
233
|
+
console.log(
|
|
234
|
+
` ${symbols.checkmark} ${passed} ${this.pluralize('task', passed)} passed`,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
console.log();
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
onSuiteStart(suite: string): void {
|
|
241
|
+
this.currentSuite = suite;
|
|
242
|
+
|
|
243
|
+
if (this.quiet) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
this.suiteResults = []; // Reset buffer for new suite
|
|
248
|
+
|
|
249
|
+
// Skip displaying the implicit "default" suite header
|
|
250
|
+
if (suite === 'default') {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
console.log();
|
|
255
|
+
console.log(` -- ${suite}`);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
onTaskResult(result: TaskResult): void {
|
|
259
|
+
if (this.quiet) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Buffer the result for later printing with proper alignment
|
|
264
|
+
this.suiteResults.push(result);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
onTaskStart(task: string): void {
|
|
268
|
+
if (this.quiet) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Only show static markers in verbose mode
|
|
273
|
+
if (this.verbose) {
|
|
274
|
+
console.log(` - ${task}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Format bytes in human-readable format
|
|
280
|
+
*/
|
|
281
|
+
private formatBytes(bytes: number): string {
|
|
282
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
283
|
+
let size = bytes;
|
|
284
|
+
let unitIndex = 0;
|
|
285
|
+
|
|
286
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
287
|
+
size /= 1024;
|
|
288
|
+
unitIndex++;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return `${size.toFixed(1)} ${units[unitIndex]}`;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Format file path - show relative path if within CWD, otherwise absolute
|
|
296
|
+
*/
|
|
297
|
+
private formatPath(filePath: string): string {
|
|
298
|
+
const cwd = process.cwd();
|
|
299
|
+
const absolutePath = path.resolve(filePath);
|
|
300
|
+
|
|
301
|
+
// Check if the file is within the current working directory
|
|
302
|
+
if (absolutePath.startsWith(cwd + path.sep) || absolutePath === cwd) {
|
|
303
|
+
return path.relative(cwd, absolutePath);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return absolutePath;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Simple pluralization helper
|
|
311
|
+
*/
|
|
312
|
+
private pluralize(str: string, count: number): string {
|
|
313
|
+
return count === 1 ? str : `${str}s`;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Print all task results in a suite with aligned columns
|
|
318
|
+
*/
|
|
319
|
+
private printAlignedSuiteResults(): void {
|
|
320
|
+
if (this.suiteResults.length === 0) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const MAX_NAME_WIDTH = 60;
|
|
325
|
+
const BASE_INDENT = ' '; // 4 spaces
|
|
326
|
+
const separator = '-'; // Simple text separator instead of bullet
|
|
327
|
+
|
|
328
|
+
// Prepare formatted data for each task
|
|
329
|
+
interface FormattedTask {
|
|
330
|
+
durationLen: number;
|
|
331
|
+
durationStr: string;
|
|
332
|
+
error: boolean;
|
|
333
|
+
errorMessage?: string;
|
|
334
|
+
iterations: number;
|
|
335
|
+
name: string;
|
|
336
|
+
nameLength: number;
|
|
337
|
+
opsPerSecLen: number;
|
|
338
|
+
opsPerSecStr: string;
|
|
339
|
+
rmeLen: number;
|
|
340
|
+
rmeStr: string;
|
|
341
|
+
status: string;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const formatted: FormattedTask[] = this.suiteResults.map((result) => {
|
|
345
|
+
const status = result.error ? symbols.cross : symbols.checkmark;
|
|
346
|
+
|
|
347
|
+
const name = result.name.trim();
|
|
348
|
+
const nameLength = name.length;
|
|
349
|
+
|
|
350
|
+
if (result.error) {
|
|
351
|
+
return {
|
|
352
|
+
durationLen: 0,
|
|
353
|
+
durationStr: '',
|
|
354
|
+
error: true,
|
|
355
|
+
errorMessage: result.error?.message || String(result.error),
|
|
356
|
+
iterations: 0,
|
|
357
|
+
name,
|
|
358
|
+
nameLength,
|
|
359
|
+
opsPerSecLen: 0,
|
|
360
|
+
opsPerSecStr: '',
|
|
361
|
+
rmeLen: 0,
|
|
362
|
+
rmeStr: '',
|
|
363
|
+
status,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const duration = this.formatDuration(result.mean * 1e9);
|
|
368
|
+
const opsPerSec = this.formatOpsPerSecond(result.opsPerSecond);
|
|
369
|
+
const rme = this.formatPercentage(result.marginOfError * 100);
|
|
370
|
+
|
|
371
|
+
return {
|
|
372
|
+
durationLen: duration.length,
|
|
373
|
+
durationStr: duration,
|
|
374
|
+
error: false,
|
|
375
|
+
iterations: result.iterations,
|
|
376
|
+
name,
|
|
377
|
+
nameLength,
|
|
378
|
+
opsPerSecLen: opsPerSec.length,
|
|
379
|
+
opsPerSecStr: opsPerSec,
|
|
380
|
+
rmeLen: rme.length,
|
|
381
|
+
rmeStr: rme,
|
|
382
|
+
status,
|
|
383
|
+
};
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// Find max widths
|
|
387
|
+
const nonWrappingTasks = formatted.filter(
|
|
388
|
+
(t) => t.nameLength <= MAX_NAME_WIDTH,
|
|
389
|
+
);
|
|
390
|
+
const maxNameLen =
|
|
391
|
+
nonWrappingTasks.length > 0
|
|
392
|
+
? Math.max(...nonWrappingTasks.map((t) => t.nameLength))
|
|
393
|
+
: 40; // Default if all tasks wrap
|
|
394
|
+
|
|
395
|
+
const maxDurationLen = Math.max(
|
|
396
|
+
...formatted.filter((t) => !t.error).map((t) => t.durationLen),
|
|
397
|
+
0,
|
|
398
|
+
);
|
|
399
|
+
const maxRmeLen = Math.max(
|
|
400
|
+
...formatted.filter((t) => !t.error).map((t) => t.rmeLen),
|
|
401
|
+
0,
|
|
402
|
+
);
|
|
403
|
+
const maxOpsLen = Math.max(
|
|
404
|
+
...formatted.filter((t) => !t.error).map((t) => t.opsPerSecLen),
|
|
405
|
+
0,
|
|
406
|
+
);
|
|
407
|
+
|
|
408
|
+
// Calculate the position where numbers start for unwrapped lines
|
|
409
|
+
// BASE_INDENT (4) + status (1 char) + space (1) + maxNameLen + ": " (2) = 8 + maxNameLen
|
|
410
|
+
const numbersStartPos = BASE_INDENT.length + 2 + maxNameLen + 2;
|
|
411
|
+
|
|
412
|
+
// Print each task with aligned columns
|
|
413
|
+
for (const task of formatted) {
|
|
414
|
+
if (task.error) {
|
|
415
|
+
// Track failure for end summary
|
|
416
|
+
this.failures.push({
|
|
417
|
+
error: task.errorMessage || 'Unknown error',
|
|
418
|
+
file: this.currentFile,
|
|
419
|
+
suite: this.currentSuite,
|
|
420
|
+
task: task.name,
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
console.log(`${BASE_INDENT}${task.status} ${task.name} FAILED`);
|
|
424
|
+
} else if (task.nameLength > MAX_NAME_WIDTH) {
|
|
425
|
+
// Long name - wrap to next line, but align numbers with unwrapped lines
|
|
426
|
+
console.log(`${BASE_INDENT}${task.status} ${task.name}:`);
|
|
427
|
+
|
|
428
|
+
// Calculate padding to align with unwrapped lines
|
|
429
|
+
// We need to get to numbersStartPos from the beginning of the line
|
|
430
|
+
const leadingPad = ' '.repeat(numbersStartPos);
|
|
431
|
+
const durationPad = ' '.repeat(maxDurationLen - task.durationLen);
|
|
432
|
+
const rmePad = ' '.repeat(maxRmeLen - task.rmeLen);
|
|
433
|
+
const opsPad = ' '.repeat(maxOpsLen - task.opsPerSecLen);
|
|
434
|
+
|
|
435
|
+
console.log(
|
|
436
|
+
`${leadingPad}${durationPad}${task.durationStr} ${separator} ${symbols.plusMinus}${rmePad}${task.rmeStr} ${separator} ${opsPad}${task.opsPerSecStr}`,
|
|
437
|
+
);
|
|
438
|
+
|
|
439
|
+
if (this.verbose && task.iterations > 0) {
|
|
440
|
+
console.log(` ${task.iterations} iterations`);
|
|
441
|
+
}
|
|
442
|
+
} else {
|
|
443
|
+
// Normal length - align on same line
|
|
444
|
+
const namePad = ' '.repeat(maxNameLen - task.nameLength);
|
|
445
|
+
const durationPad = ' '.repeat(maxDurationLen - task.durationLen);
|
|
446
|
+
const rmePad = ' '.repeat(maxRmeLen - task.rmeLen);
|
|
447
|
+
const opsPad = ' '.repeat(maxOpsLen - task.opsPerSecLen);
|
|
448
|
+
|
|
449
|
+
console.log(
|
|
450
|
+
`${BASE_INDENT}${task.status} ${task.name}${namePad}: ${durationPad}${task.durationStr} ${separator} ${symbols.plusMinus}${rmePad}${task.rmeStr} ${separator} ${opsPad}${task.opsPerSecStr}`,
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
if (this.verbose && task.iterations > 0) {
|
|
454
|
+
console.log(` ${task.iterations} iterations`);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|