modestbench 0.2.0 → 0.3.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 +27 -0
- package/README.md +131 -34
- package/dist/cli/commands/analyze.cjs +60 -0
- package/dist/cli/commands/analyze.cjs.map +1 -0
- package/dist/cli/commands/analyze.d.cts +35 -0
- package/dist/cli/commands/analyze.d.cts.map +1 -0
- package/dist/cli/commands/analyze.d.ts +35 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +56 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/baseline.cjs +404 -0
- package/dist/cli/commands/baseline.cjs.map +1 -0
- package/dist/cli/commands/baseline.d.cts +72 -0
- package/dist/cli/commands/baseline.d.cts.map +1 -0
- package/dist/cli/commands/baseline.d.ts +72 -0
- package/dist/cli/commands/baseline.d.ts.map +1 -0
- package/dist/cli/commands/baseline.js +396 -0
- package/dist/cli/commands/baseline.js.map +1 -0
- package/dist/cli/commands/history.d.cts +1 -1
- package/dist/cli/commands/history.d.cts.map +1 -1
- package/dist/cli/commands/history.d.ts +1 -1
- package/dist/cli/commands/history.d.ts.map +1 -1
- package/dist/cli/commands/init.cjs +99 -166
- package/dist/cli/commands/init.cjs.map +1 -1
- package/dist/cli/commands/init.d.cts +4 -4
- package/dist/cli/commands/init.d.cts.map +1 -1
- package/dist/cli/commands/init.d.ts +4 -4
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +99 -166
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/run.cjs +146 -127
- package/dist/cli/commands/run.cjs.map +1 -1
- package/dist/cli/commands/run.d.cts +16 -3
- package/dist/cli/commands/run.d.cts.map +1 -1
- package/dist/cli/commands/run.d.ts +16 -3
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +145 -93
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/index.cjs +583 -394
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +4 -16
- package/dist/cli/index.d.cts.map +1 -1
- package/dist/cli/index.d.ts +4 -16
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +575 -386
- package/dist/cli/index.js.map +1 -1
- package/dist/config/budget-schema.cjs +172 -0
- package/dist/config/budget-schema.cjs.map +1 -0
- package/dist/config/budget-schema.d.cts +59 -0
- package/dist/config/budget-schema.d.cts.map +1 -0
- package/dist/config/budget-schema.d.ts +59 -0
- package/dist/config/budget-schema.d.ts.map +1 -0
- package/dist/config/budget-schema.js +166 -0
- package/dist/config/budget-schema.js.map +1 -0
- package/dist/config/schema.cjs +182 -2
- package/dist/config/schema.cjs.map +1 -1
- package/dist/config/schema.d.cts +122 -3
- package/dist/config/schema.d.cts.map +1 -1
- package/dist/config/schema.d.ts +122 -3
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +180 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/constants.cjs +45 -2
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +41 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.ts +41 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +44 -1
- package/dist/constants.js.map +1 -1
- package/dist/core/engine.cjs +114 -23
- package/dist/core/engine.cjs.map +1 -1
- package/dist/core/engine.d.cts +7 -7
- package/dist/core/engine.d.cts.map +1 -1
- package/dist/core/engine.d.ts +7 -7
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +115 -24
- package/dist/core/engine.js.map +1 -1
- package/dist/core/engines/accurate-engine.cjs +171 -36
- package/dist/core/engines/accurate-engine.cjs.map +1 -1
- package/dist/core/engines/accurate-engine.d.cts +5 -0
- package/dist/core/engines/accurate-engine.d.cts.map +1 -1
- package/dist/core/engines/accurate-engine.d.ts +5 -0
- package/dist/core/engines/accurate-engine.d.ts.map +1 -1
- package/dist/core/engines/accurate-engine.js +171 -36
- package/dist/core/engines/accurate-engine.js.map +1 -1
- package/dist/core/engines/tinybench-engine.cjs +3 -2
- package/dist/core/engines/tinybench-engine.cjs.map +1 -1
- package/dist/core/engines/tinybench-engine.d.cts.map +1 -1
- package/dist/core/engines/tinybench-engine.d.ts.map +1 -1
- package/dist/core/engines/tinybench-engine.js +3 -2
- package/dist/core/engines/tinybench-engine.js.map +1 -1
- package/dist/core/output-path-resolver.cjs +8 -1
- package/dist/core/output-path-resolver.cjs.map +1 -1
- package/dist/core/output-path-resolver.d.cts.map +1 -1
- package/dist/core/output-path-resolver.d.ts.map +1 -1
- package/dist/core/output-path-resolver.js +9 -2
- package/dist/core/output-path-resolver.js.map +1 -1
- package/dist/errors/base.cjs +12 -3
- package/dist/errors/base.cjs.map +1 -1
- package/dist/errors/base.d.cts +7 -0
- package/dist/errors/base.d.cts.map +1 -1
- package/dist/errors/base.d.ts +7 -0
- package/dist/errors/base.d.ts.map +1 -1
- package/dist/errors/base.js +10 -2
- package/dist/errors/base.js.map +1 -1
- package/dist/errors/budget.cjs +37 -0
- package/dist/errors/budget.cjs.map +1 -0
- package/dist/errors/budget.d.cts +31 -0
- package/dist/errors/budget.d.cts.map +1 -0
- package/dist/errors/budget.d.ts +31 -0
- package/dist/errors/budget.d.ts.map +1 -0
- package/dist/errors/budget.js +33 -0
- package/dist/errors/budget.js.map +1 -0
- package/dist/errors/index.cjs +4 -1
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.cts +1 -0
- package/dist/errors/index.d.cts.map +1 -1
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -1
- package/dist/index.cjs +13 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/reporters/csv.cjs +37 -17
- package/dist/reporters/csv.cjs.map +1 -1
- package/dist/reporters/csv.d.cts +3 -6
- package/dist/reporters/csv.d.cts.map +1 -1
- package/dist/reporters/csv.d.ts +3 -6
- package/dist/reporters/csv.d.ts.map +1 -1
- package/dist/reporters/csv.js +37 -17
- package/dist/reporters/csv.js.map +1 -1
- package/dist/reporters/human.cjs +290 -67
- package/dist/reporters/human.cjs.map +1 -1
- package/dist/reporters/human.d.cts +25 -13
- package/dist/reporters/human.d.cts.map +1 -1
- package/dist/reporters/human.d.ts +25 -13
- package/dist/reporters/human.d.ts.map +1 -1
- package/dist/reporters/human.js +290 -67
- package/dist/reporters/human.js.map +1 -1
- package/dist/reporters/json.cjs +23 -48
- package/dist/reporters/json.cjs.map +1 -1
- package/dist/reporters/json.d.cts +2 -28
- package/dist/reporters/json.d.cts.map +1 -1
- package/dist/reporters/json.d.ts +2 -28
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +25 -50
- package/dist/reporters/json.js.map +1 -1
- package/dist/reporters/profile-human.cjs +154 -0
- package/dist/reporters/profile-human.cjs.map +1 -0
- package/dist/reporters/profile-human.d.cts +44 -0
- package/dist/reporters/profile-human.d.cts.map +1 -0
- package/dist/reporters/profile-human.d.ts +44 -0
- package/dist/reporters/profile-human.d.ts.map +1 -0
- package/dist/reporters/profile-human.js +147 -0
- package/dist/reporters/profile-human.js.map +1 -0
- package/dist/reporters/simple.cjs +67 -45
- package/dist/reporters/simple.cjs.map +1 -1
- package/dist/reporters/simple.d.cts +14 -14
- package/dist/reporters/simple.d.cts.map +1 -1
- package/dist/reporters/simple.d.ts +14 -14
- package/dist/reporters/simple.d.ts.map +1 -1
- package/dist/reporters/simple.js +67 -45
- package/dist/reporters/simple.js.map +1 -1
- package/dist/schema/modestbench-config.schema.json +153 -0
- package/dist/services/baseline-storage.cjs +151 -0
- package/dist/services/baseline-storage.cjs.map +1 -0
- package/dist/services/baseline-storage.d.cts +55 -0
- package/dist/services/baseline-storage.d.cts.map +1 -0
- package/dist/services/baseline-storage.d.ts +55 -0
- package/dist/services/baseline-storage.d.ts.map +1 -0
- package/dist/services/baseline-storage.js +147 -0
- package/dist/services/baseline-storage.js.map +1 -0
- package/dist/services/budget-evaluator.cjs +146 -0
- package/dist/services/budget-evaluator.cjs.map +1 -0
- package/dist/services/budget-evaluator.d.cts +29 -0
- package/dist/services/budget-evaluator.d.cts.map +1 -0
- package/dist/services/budget-evaluator.d.ts +29 -0
- package/dist/services/budget-evaluator.d.ts.map +1 -0
- package/dist/services/budget-evaluator.js +142 -0
- package/dist/services/budget-evaluator.js.map +1 -0
- package/dist/services/config-manager.cjs +24 -10
- package/dist/services/config-manager.cjs.map +1 -1
- package/dist/services/config-manager.d.cts +6 -1
- package/dist/services/config-manager.d.cts.map +1 -1
- package/dist/services/config-manager.d.ts +6 -1
- package/dist/services/config-manager.d.ts.map +1 -1
- package/dist/services/config-manager.js +24 -10
- package/dist/services/config-manager.js.map +1 -1
- package/dist/services/file-loader.cjs +3 -6
- 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 +3 -6
- package/dist/services/file-loader.js.map +1 -1
- package/dist/services/profiler/profile-filter.cjs +116 -0
- package/dist/services/profiler/profile-filter.cjs.map +1 -0
- package/dist/services/profiler/profile-filter.d.cts +20 -0
- package/dist/services/profiler/profile-filter.d.cts.map +1 -0
- package/dist/services/profiler/profile-filter.d.ts +20 -0
- package/dist/services/profiler/profile-filter.d.ts.map +1 -0
- package/dist/services/profiler/profile-filter.js +112 -0
- package/dist/services/profiler/profile-filter.js.map +1 -0
- package/dist/services/profiler/profile-parser.cjs +139 -0
- package/dist/services/profiler/profile-parser.cjs.map +1 -0
- package/dist/services/profiler/profile-parser.d.cts +18 -0
- package/dist/services/profiler/profile-parser.d.cts.map +1 -0
- package/dist/services/profiler/profile-parser.d.ts +18 -0
- package/dist/services/profiler/profile-parser.d.ts.map +1 -0
- package/dist/services/profiler/profile-parser.js +132 -0
- package/dist/services/profiler/profile-parser.js.map +1 -0
- package/dist/services/profiler/profile-runner.cjs +90 -0
- package/dist/services/profiler/profile-runner.cjs.map +1 -0
- package/dist/services/profiler/profile-runner.d.cts +29 -0
- package/dist/services/profiler/profile-runner.d.cts.map +1 -0
- package/dist/services/profiler/profile-runner.d.ts +29 -0
- package/dist/services/profiler/profile-runner.d.ts.map +1 -0
- package/dist/services/profiler/profile-runner.js +86 -0
- package/dist/services/profiler/profile-runner.js.map +1 -0
- package/dist/services/progress-manager.cjs +10 -2
- package/dist/services/progress-manager.cjs.map +1 -1
- package/dist/services/progress-manager.d.cts +2 -0
- package/dist/services/progress-manager.d.cts.map +1 -1
- package/dist/services/progress-manager.d.ts +2 -0
- package/dist/services/progress-manager.d.ts.map +1 -1
- package/dist/services/progress-manager.js +10 -2
- package/dist/services/progress-manager.js.map +1 -1
- package/dist/services/reporter-registry.cjs +18 -24
- package/dist/services/reporter-registry.cjs.map +1 -1
- package/dist/services/reporter-registry.d.cts +18 -40
- package/dist/services/reporter-registry.d.cts.map +1 -1
- package/dist/services/reporter-registry.d.ts +18 -40
- package/dist/services/reporter-registry.d.ts.map +1 -1
- package/dist/services/reporter-registry.js +18 -24
- package/dist/services/reporter-registry.js.map +1 -1
- package/dist/types/budgets.cjs +8 -0
- package/dist/types/budgets.cjs.map +1 -0
- package/dist/types/budgets.d.cts +149 -0
- package/dist/types/budgets.d.cts.map +1 -0
- package/dist/types/budgets.d.ts +149 -0
- package/dist/types/budgets.d.ts.map +1 -0
- package/dist/types/budgets.js +7 -0
- package/dist/types/budgets.js.map +1 -0
- package/dist/types/cli.cjs +2 -11
- package/dist/types/cli.cjs.map +1 -1
- package/dist/types/cli.d.cts +3 -227
- package/dist/types/cli.d.cts.map +1 -1
- package/dist/types/cli.d.ts +3 -227
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/cli.js +2 -11
- package/dist/types/cli.js.map +1 -1
- package/dist/types/core.cjs +6 -1
- package/dist/types/core.cjs.map +1 -1
- package/dist/types/core.d.cts +15 -2
- package/dist/types/core.d.cts.map +1 -1
- package/dist/types/core.d.ts +15 -2
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/core.js +2 -1
- package/dist/types/core.js.map +1 -1
- package/dist/types/index.cjs +5 -0
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +2 -0
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/interfaces.d.cts +19 -8
- package/dist/types/interfaces.d.cts.map +1 -1
- package/dist/types/interfaces.d.ts +19 -8
- package/dist/types/interfaces.d.ts.map +1 -1
- package/dist/types/profiler.cjs +11 -0
- package/dist/types/profiler.cjs.map +1 -0
- package/dist/types/profiler.d.cts +102 -0
- package/dist/types/profiler.d.cts.map +1 -0
- package/dist/types/profiler.d.ts +102 -0
- package/dist/types/profiler.d.ts.map +1 -0
- package/dist/types/profiler.js +10 -0
- package/dist/types/profiler.js.map +1 -0
- package/dist/types/utility.cjs.map +1 -1
- package/dist/types/utility.d.cts +0 -8
- package/dist/types/utility.d.cts.map +1 -1
- package/dist/types/utility.d.ts +0 -8
- package/dist/types/utility.d.ts.map +1 -1
- package/dist/types/utility.js.map +1 -1
- package/dist/utils/identifiers.cjs +32 -0
- package/dist/utils/identifiers.cjs.map +1 -0
- package/dist/utils/identifiers.d.cts +32 -0
- package/dist/utils/identifiers.d.cts.map +1 -0
- package/dist/utils/identifiers.d.ts +32 -0
- package/dist/utils/identifiers.d.ts.map +1 -0
- package/dist/utils/identifiers.js +27 -0
- package/dist/utils/identifiers.js.map +1 -0
- package/dist/utils/package.cjs +40 -0
- package/dist/utils/package.cjs.map +1 -0
- package/dist/utils/package.d.cts +15 -0
- package/dist/utils/package.d.cts.map +1 -0
- package/dist/utils/package.d.ts +15 -0
- package/dist/utils/package.d.ts.map +1 -0
- package/dist/utils/package.js +33 -0
- package/dist/utils/package.js.map +1 -0
- package/dist/utils/type-guards.cjs +48 -0
- package/dist/utils/type-guards.cjs.map +1 -0
- package/dist/utils/type-guards.d.cts +22 -0
- package/dist/utils/type-guards.d.cts.map +1 -0
- package/dist/utils/type-guards.d.ts +22 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +43 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/package.json +18 -19
- package/src/cli/commands/analyze.ts +101 -0
- package/src/cli/commands/baseline.ts +577 -0
- package/src/cli/commands/history.ts +1 -1
- package/src/cli/commands/init.ts +116 -194
- package/src/cli/commands/run.ts +183 -113
- package/src/cli/index.ts +425 -183
- package/src/config/budget-schema.ts +189 -0
- package/src/config/schema.ts +260 -1
- package/src/constants.ts +53 -1
- package/src/core/engine.ts +169 -22
- package/src/core/engines/accurate-engine.ts +195 -44
- package/src/core/engines/tinybench-engine.ts +3 -2
- package/src/core/output-path-resolver.ts +10 -2
- package/src/errors/base.ts +11 -2
- package/src/errors/budget.ts +38 -0
- package/src/errors/index.ts +3 -0
- package/src/index.ts +9 -0
- package/src/reporters/csv.ts +54 -25
- package/src/reporters/human.ts +434 -115
- package/src/reporters/json.ts +26 -71
- package/src/reporters/profile-human.ts +210 -0
- package/src/reporters/simple.ts +88 -54
- package/src/services/baseline-storage.ts +199 -0
- package/src/services/budget-evaluator.ts +182 -0
- package/src/services/config-manager.ts +24 -9
- package/src/services/file-loader.ts +3 -6
- package/src/services/profiler/profile-filter.ts +147 -0
- package/src/services/profiler/profile-parser.ts +194 -0
- package/src/services/profiler/profile-runner.ts +121 -0
- package/src/services/progress-manager.ts +12 -2
- package/src/services/reporter-registry.ts +46 -81
- package/src/types/budgets.ts +180 -0
- package/src/types/cli.ts +5 -238
- package/src/types/core.ts +52 -10
- package/src/types/index.ts +5 -0
- package/src/types/interfaces.ts +24 -6
- package/src/types/profiler.ts +135 -0
- package/src/types/utility.ts +0 -10
- package/src/utils/identifiers.ts +58 -0
- package/src/utils/package.ts +35 -0
- package/src/utils/type-guards.ts +51 -0
package/src/reporters/json.ts
CHANGED
|
@@ -5,16 +5,11 @@
|
|
|
5
5
|
* processing, CI/CD integration, and data analysis.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
9
|
-
import { dirname } from 'node:path';
|
|
8
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
9
|
+
import { dirname, join } from 'node:path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
10
11
|
|
|
11
|
-
import type {
|
|
12
|
-
BenchmarkRun,
|
|
13
|
-
FileResult,
|
|
14
|
-
ProgressState,
|
|
15
|
-
SuiteResult,
|
|
16
|
-
TaskResult,
|
|
17
|
-
} from '../types/index.js';
|
|
12
|
+
import type { BenchmarkRun, TaskResult } from '../types/index.js';
|
|
18
13
|
|
|
19
14
|
import { ReporterOutputError } from '../errors/index.js';
|
|
20
15
|
import { BaseReporter } from '../services/reporter-registry.js';
|
|
@@ -40,12 +35,30 @@ interface JsonOutput {
|
|
|
40
35
|
};
|
|
41
36
|
}
|
|
42
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Cache the package version at module load time
|
|
40
|
+
*
|
|
41
|
+
* NOTE: This relies on package.json being at the same relative path from both
|
|
42
|
+
* src/ and dist/ directories (../../package.json). If the build output
|
|
43
|
+
* structure changes, this will break.
|
|
44
|
+
*/
|
|
45
|
+
const cachedPackageVersion = (() => {
|
|
46
|
+
try {
|
|
47
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
48
|
+
const pkgPath = join(__dirname, '..', '..', 'package.json');
|
|
49
|
+
const pkgContent = readFileSync(pkgPath, 'utf8');
|
|
50
|
+
const pkg = JSON.parse(pkgContent) as { version: string };
|
|
51
|
+
return pkg.version;
|
|
52
|
+
} catch {
|
|
53
|
+
// Fallback if package.json cannot be read (shouldn't happen in normal use)
|
|
54
|
+
return 'unknown';
|
|
55
|
+
}
|
|
56
|
+
})();
|
|
57
|
+
|
|
43
58
|
/**
|
|
44
59
|
* JSON reporter for structured output
|
|
45
60
|
*/
|
|
46
61
|
export class JsonReporter extends BaseReporter {
|
|
47
|
-
private currentRun?: BenchmarkRun;
|
|
48
|
-
|
|
49
62
|
private readonly includeMetadata: boolean;
|
|
50
63
|
|
|
51
64
|
private readonly includeStatistics: boolean;
|
|
@@ -54,8 +67,6 @@ export class JsonReporter extends BaseReporter {
|
|
|
54
67
|
|
|
55
68
|
private readonly prettyPrint: boolean;
|
|
56
69
|
|
|
57
|
-
private readonly quiet: boolean;
|
|
58
|
-
|
|
59
70
|
private statistics: {
|
|
60
71
|
fastestTask?: TaskResult;
|
|
61
72
|
slowestTask?: TaskResult;
|
|
@@ -74,8 +85,6 @@ export class JsonReporter extends BaseReporter {
|
|
|
74
85
|
includeStatistics?: boolean;
|
|
75
86
|
outputPath?: string;
|
|
76
87
|
prettyPrint?: boolean;
|
|
77
|
-
quiet?: boolean;
|
|
78
|
-
verbose?: boolean;
|
|
79
88
|
} = {},
|
|
80
89
|
) {
|
|
81
90
|
super('json', options);
|
|
@@ -84,35 +93,6 @@ export class JsonReporter extends BaseReporter {
|
|
|
84
93
|
this.prettyPrint = options.prettyPrint ?? true;
|
|
85
94
|
this.includeStatistics = options.includeStatistics ?? true;
|
|
86
95
|
this.includeMetadata = options.includeMetadata ?? true;
|
|
87
|
-
this.quiet = options.quiet ?? false;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Check if statistics are included
|
|
92
|
-
*/
|
|
93
|
-
areStatisticsIncluded(): boolean {
|
|
94
|
-
return this.includeStatistics;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Get the output path (if configured)
|
|
99
|
-
*/
|
|
100
|
-
getOutputPath(): string | undefined {
|
|
101
|
-
return this.outputPath;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Check if metadata is included
|
|
106
|
-
*/
|
|
107
|
-
isMetadataIncluded(): boolean {
|
|
108
|
-
return this.includeMetadata;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Check if pretty printing is enabled
|
|
113
|
-
*/
|
|
114
|
-
isPrettyPrintEnabled(): boolean {
|
|
115
|
-
return this.prettyPrint;
|
|
116
96
|
}
|
|
117
97
|
|
|
118
98
|
async onEnd(run: BenchmarkRun): Promise<void> {
|
|
@@ -131,41 +111,16 @@ export class JsonReporter extends BaseReporter {
|
|
|
131
111
|
console.error('JSON Reporter Error:', error.message);
|
|
132
112
|
}
|
|
133
113
|
|
|
134
|
-
|
|
135
|
-
// No-op for JSON reporter
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
onFileStart(_file: string): void {
|
|
139
|
-
// No-op for JSON reporter
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
onProgress(_state: ProgressState): void {
|
|
143
|
-
// No-op for JSON reporter - we don't output progress in JSON format
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
onStart(run: BenchmarkRun): void {
|
|
147
|
-
this.currentRun = run;
|
|
114
|
+
onStart(_run: BenchmarkRun): void {
|
|
148
115
|
this.resetStatistics();
|
|
149
116
|
}
|
|
150
117
|
|
|
151
|
-
onSuiteEnd(_result: SuiteResult): void {
|
|
152
|
-
// No-op for JSON reporter
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
onSuiteStart(_suite: string): void {
|
|
156
|
-
// No-op for JSON reporter
|
|
157
|
-
}
|
|
158
|
-
|
|
159
118
|
onTaskResult(result: TaskResult): void {
|
|
160
119
|
if (!result.error) {
|
|
161
120
|
this.updateStatistics(result);
|
|
162
121
|
}
|
|
163
122
|
}
|
|
164
123
|
|
|
165
|
-
onTaskStart(_task: string): void {
|
|
166
|
-
// No-op for JSON reporter
|
|
167
|
-
}
|
|
168
|
-
|
|
169
124
|
/**
|
|
170
125
|
* Build the complete JSON output structure
|
|
171
126
|
*/
|
|
@@ -174,7 +129,7 @@ export class JsonReporter extends BaseReporter {
|
|
|
174
129
|
meta: {
|
|
175
130
|
format: 'modestbench-json',
|
|
176
131
|
timestamp: new Date().toISOString(),
|
|
177
|
-
version:
|
|
132
|
+
version: cachedPackageVersion,
|
|
178
133
|
},
|
|
179
134
|
run: this.includeMetadata ? run : this.sanitizeRun(run),
|
|
180
135
|
};
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile Human Reporter
|
|
3
|
+
*
|
|
4
|
+
* Human-readable reporter for profile command. Uses modestbench's synthwave
|
|
5
|
+
* ANSI theme to display profiled functions in an attractive, color-coded
|
|
6
|
+
* format.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
|
|
13
|
+
import type { FilteredProfileData } from '../types/profiler.js';
|
|
14
|
+
|
|
15
|
+
import { ansiChars, colors } from '../utils/ansi.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Reporter options
|
|
19
|
+
*/
|
|
20
|
+
interface ProfileReporterOptions {
|
|
21
|
+
/** Enable color output */
|
|
22
|
+
color?: boolean;
|
|
23
|
+
|
|
24
|
+
/** Group by file */
|
|
25
|
+
groupByFile?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Human-readable profile reporter
|
|
30
|
+
*/
|
|
31
|
+
export class ProfileHumanReporter {
|
|
32
|
+
private readonly groupByFile: boolean;
|
|
33
|
+
|
|
34
|
+
private readonly useColor: boolean;
|
|
35
|
+
|
|
36
|
+
constructor(options: ProfileReporterOptions = {}) {
|
|
37
|
+
this.useColor =
|
|
38
|
+
options.color ??
|
|
39
|
+
(process.stdout.isTTY &&
|
|
40
|
+
process.env.FORCE_COLOR !== '0' &&
|
|
41
|
+
process.env.NO_COLOR == null);
|
|
42
|
+
|
|
43
|
+
this.groupByFile = options.groupByFile ?? false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Generate and print profile report
|
|
48
|
+
*/
|
|
49
|
+
report(data: FilteredProfileData): void {
|
|
50
|
+
this.printHeader(data);
|
|
51
|
+
this.printLine();
|
|
52
|
+
|
|
53
|
+
if (this.groupByFile && data.groupedByFile) {
|
|
54
|
+
this.printGroupedResults(data);
|
|
55
|
+
} else {
|
|
56
|
+
this.printFlatResults(data);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private colorize(color: keyof typeof colors, text: string): string {
|
|
61
|
+
if (!this.useColor) {
|
|
62
|
+
return text;
|
|
63
|
+
}
|
|
64
|
+
return `${colors[color]}${text}${colors.reset}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Format file path - show relative path if within CWD, otherwise absolute
|
|
69
|
+
*/
|
|
70
|
+
private formatPath(filePath: string): string {
|
|
71
|
+
const cwd = process.cwd();
|
|
72
|
+
const absolutePath = path.resolve(filePath);
|
|
73
|
+
|
|
74
|
+
// Check if the file is within the current working directory
|
|
75
|
+
if (absolutePath.startsWith(cwd + path.sep) || absolutePath === cwd) {
|
|
76
|
+
return path.relative(cwd, absolutePath);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return absolutePath;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private getPercentColor(percent: number): keyof typeof colors {
|
|
83
|
+
if (percent >= 10) {
|
|
84
|
+
return 'brightRed';
|
|
85
|
+
}
|
|
86
|
+
if (percent >= 5) {
|
|
87
|
+
return 'brightYellow';
|
|
88
|
+
}
|
|
89
|
+
if (percent >= 2) {
|
|
90
|
+
return 'brightCyan';
|
|
91
|
+
}
|
|
92
|
+
return 'white';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private printFlatResults(data: FilteredProfileData): void {
|
|
96
|
+
const header = `${this.colorize('magenta', ansiChars.block.full.repeat(2))} ${this.colorize('brightWhite', this.colorize('bold', 'Benchmark Candidates'))}`;
|
|
97
|
+
this.printLine(header);
|
|
98
|
+
this.printLine();
|
|
99
|
+
this.printLine('Top functions by execution time:');
|
|
100
|
+
this.printLine();
|
|
101
|
+
|
|
102
|
+
for (const fn of data.functions) {
|
|
103
|
+
// Function name and percentage
|
|
104
|
+
const percentColor = this.getPercentColor(fn.percentage);
|
|
105
|
+
const percent = `${fn.percentage.toFixed(1)}%`;
|
|
106
|
+
const ticks = `(${fn.ticks.toLocaleString()} ticks)`;
|
|
107
|
+
|
|
108
|
+
this.printLine(
|
|
109
|
+
` ${this.colorize('brightWhite', fn.name).padEnd(60)} ${this.colorize(percentColor, percent.padStart(6))} ${this.colorize('dim', ticks)}`,
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
// File and line
|
|
113
|
+
const displayPath = this.formatPath(fn.file);
|
|
114
|
+
const lineInfo = fn.line ? `:${fn.line}` : '';
|
|
115
|
+
this.printLine(
|
|
116
|
+
` ${this.colorize('brightMagenta', this.colorize('bold', displayPath + lineInfo))}`,
|
|
117
|
+
);
|
|
118
|
+
this.printLine();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.printSummary(data);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private printGroupedResults(data: FilteredProfileData): void {
|
|
125
|
+
if (!data.groupedByFile) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const header = `${this.colorize('magenta', ansiChars.block.full.repeat(2))} ${this.colorize('brightWhite', this.colorize('bold', 'Grouped by File'))}`;
|
|
130
|
+
this.printLine(header);
|
|
131
|
+
this.printLine();
|
|
132
|
+
|
|
133
|
+
// Sort files by total percentage
|
|
134
|
+
const sortedFiles = Array.from(data.groupedByFile.entries()).sort(
|
|
135
|
+
(a, b) => {
|
|
136
|
+
const aTotal = a[1].reduce((sum, fn) => sum + fn.percentage, 0);
|
|
137
|
+
const bTotal = b[1].reduce((sum, fn) => sum + fn.percentage, 0);
|
|
138
|
+
return bTotal - aTotal;
|
|
139
|
+
},
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
for (const [file, functions] of sortedFiles) {
|
|
143
|
+
const totalPercent = functions.reduce(
|
|
144
|
+
(sum, fn) => sum + fn.percentage,
|
|
145
|
+
0,
|
|
146
|
+
);
|
|
147
|
+
const totalTicks = functions.reduce((sum, fn) => sum + fn.ticks, 0);
|
|
148
|
+
|
|
149
|
+
const percentColor = this.getPercentColor(totalPercent);
|
|
150
|
+
const percent = `${totalPercent.toFixed(1)}%`;
|
|
151
|
+
const ticks = `(${totalTicks.toLocaleString()} ticks)`;
|
|
152
|
+
|
|
153
|
+
// File header
|
|
154
|
+
const displayPath = this.formatPath(file);
|
|
155
|
+
this.printLine(
|
|
156
|
+
`${this.colorize('magenta', ansiChars.block.dark)} ${this.colorize('brightMagenta', this.colorize('bold', displayPath)).padEnd(60)} ${this.colorize(percentColor, percent.padStart(6))} ${this.colorize('dim', ticks)}`,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
// Functions in this file
|
|
160
|
+
for (const fn of functions) {
|
|
161
|
+
const fnPercent = `${fn.percentage.toFixed(1)}%`;
|
|
162
|
+
const fnTicks = `(${fn.ticks.toLocaleString()} ticks)`;
|
|
163
|
+
const lineInfo = fn.line ? `:${fn.line}` : '';
|
|
164
|
+
|
|
165
|
+
this.printLine(
|
|
166
|
+
` ${this.colorize('magenta', ansiChars.smallSquare)} ${this.colorize('brightWhite', fn.name).padEnd(58)} ${this.colorize(this.getPercentColor(fn.percentage), fnPercent.padStart(6))} ${this.colorize('dim', fnTicks.padEnd(15))} ${this.colorize('dim', lineInfo)}`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
this.printLine();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
this.printSummary(data);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private printHeader(data: FilteredProfileData): void {
|
|
177
|
+
const header = `${this.colorize('magenta', ansiChars.block.full.repeat(2))} ${this.colorize('brightWhite', this.colorize('bold', 'Profile Analysis'))}`;
|
|
178
|
+
this.printLine(header);
|
|
179
|
+
this.printLine();
|
|
180
|
+
|
|
181
|
+
if (data.command) {
|
|
182
|
+
this.printLine(`Command: ${this.colorize('cyan', data.command)}`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (data.duration) {
|
|
186
|
+
const durationSec = (data.duration / 1000).toFixed(1);
|
|
187
|
+
this.printLine(`Duration: ${this.colorize('cyan', `${durationSec}s`)}`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
this.printLine(
|
|
191
|
+
`Total Ticks: ${this.colorize('cyan', data.totalTicks.toLocaleString())}`,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private printLine(text = ''): void {
|
|
196
|
+
console.log(text);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private printSummary(data: FilteredProfileData): void {
|
|
200
|
+
if (data.totalShown === 0) {
|
|
201
|
+
this.printLine(
|
|
202
|
+
`${this.colorize('dim', `No functions used at least ${data.minExecutionPercent}% of the ticks`)}`,
|
|
203
|
+
);
|
|
204
|
+
} else {
|
|
205
|
+
this.printLine(
|
|
206
|
+
`${this.colorize('dim', `... (showing top ${data.totalShown} of ${data.totalFiltered} user functions)`)}`,
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
package/src/reporters/simple.ts
CHANGED
|
@@ -9,8 +9,8 @@ import path from 'node:path';
|
|
|
9
9
|
|
|
10
10
|
import type {
|
|
11
11
|
BenchmarkRun,
|
|
12
|
+
BudgetSummary,
|
|
12
13
|
FileResult,
|
|
13
|
-
ProgressState,
|
|
14
14
|
SuiteResult,
|
|
15
15
|
TaskResult,
|
|
16
16
|
} from '../types/index.js';
|
|
@@ -62,6 +62,78 @@ export class SimpleReporter extends BaseReporter {
|
|
|
62
62
|
this.quiet = options.quiet ?? false;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Format bytes in human-readable format
|
|
67
|
+
*/
|
|
68
|
+
private static formatBytes(this: void, bytes: number): string {
|
|
69
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
70
|
+
let size = bytes;
|
|
71
|
+
let unitIndex = 0;
|
|
72
|
+
|
|
73
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
74
|
+
size /= 1024;
|
|
75
|
+
unitIndex++;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return `${size.toFixed(1)} ${units[unitIndex]}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Format file path - show relative path if within CWD, otherwise absolute
|
|
83
|
+
*/
|
|
84
|
+
private static formatPath(this: void, filePath: string): string {
|
|
85
|
+
const cwd = process.cwd();
|
|
86
|
+
const absolutePath = path.resolve(filePath);
|
|
87
|
+
|
|
88
|
+
// Check if the file is within the current working directory
|
|
89
|
+
if (absolutePath.startsWith(cwd + path.sep) || absolutePath === cwd) {
|
|
90
|
+
return path.relative(cwd, absolutePath);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return absolutePath;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Simple pluralization helper
|
|
98
|
+
*/
|
|
99
|
+
private static pluralize(this: void, str: string, count: number): string {
|
|
100
|
+
return count === 1 ? str : `${str}s`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
onBudgetResult(summary: BudgetSummary): void {
|
|
104
|
+
if (summary.total === 0 || this.quiet) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log('== Performance Budgets');
|
|
109
|
+
console.log();
|
|
110
|
+
|
|
111
|
+
for (const result of summary.results) {
|
|
112
|
+
const icon = result.passed ? symbols.checkmark : symbols.cross;
|
|
113
|
+
console.log(` ${icon} ${result.taskId}`);
|
|
114
|
+
|
|
115
|
+
if (!result.passed && result.violations.length > 0) {
|
|
116
|
+
for (const violation of result.violations) {
|
|
117
|
+
console.log(` ${violation.message}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
console.log();
|
|
123
|
+
|
|
124
|
+
if (summary.failed === 0) {
|
|
125
|
+
console.log(
|
|
126
|
+
` ${symbols.checkmark} All ${summary.total} budget(s) passed`,
|
|
127
|
+
);
|
|
128
|
+
} else {
|
|
129
|
+
console.log(
|
|
130
|
+
` ${symbols.cross} ${summary.failed} of ${summary.total} budget(s) failed`,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
console.log();
|
|
135
|
+
}
|
|
136
|
+
|
|
65
137
|
onEnd(run: BenchmarkRun): void {
|
|
66
138
|
if (this.quiet) {
|
|
67
139
|
return;
|
|
@@ -97,7 +169,7 @@ export class SimpleReporter extends BaseReporter {
|
|
|
97
169
|
console.log(`- Files: ${totalFiles}`);
|
|
98
170
|
console.log(`- Suites: ${totalSuites}`);
|
|
99
171
|
console.log(
|
|
100
|
-
`${symbols.approx} Duration: ${
|
|
172
|
+
`${symbols.approx} Duration: ${BaseReporter.formatDuration(duration * 1e6)}`,
|
|
101
173
|
);
|
|
102
174
|
console.log();
|
|
103
175
|
|
|
@@ -111,7 +183,7 @@ export class SimpleReporter extends BaseReporter {
|
|
|
111
183
|
console.log();
|
|
112
184
|
|
|
113
185
|
for (const failure of this.failures) {
|
|
114
|
-
const displayPath =
|
|
186
|
+
const displayPath = SimpleReporter.formatPath(failure.file);
|
|
115
187
|
console.log(` ${displayPath} > ${failure.suite} > ${failure.task}`);
|
|
116
188
|
console.log(` ${failure.error}`);
|
|
117
189
|
console.log();
|
|
@@ -155,7 +227,7 @@ export class SimpleReporter extends BaseReporter {
|
|
|
155
227
|
);
|
|
156
228
|
} else {
|
|
157
229
|
console.log(
|
|
158
|
-
` ${symbols.checkmark} ${totalPassed > 1 ? 'All ' : ''}${totalPassed} ${
|
|
230
|
+
` ${symbols.checkmark} ${totalPassed > 1 ? 'All ' : ''}${totalPassed} ${SimpleReporter.pluralize('task', totalPassed)} passed`,
|
|
159
231
|
);
|
|
160
232
|
}
|
|
161
233
|
|
|
@@ -169,15 +241,10 @@ export class SimpleReporter extends BaseReporter {
|
|
|
169
241
|
return;
|
|
170
242
|
}
|
|
171
243
|
|
|
172
|
-
const displayPath =
|
|
244
|
+
const displayPath = SimpleReporter.formatPath(file);
|
|
173
245
|
console.log(`-- ${displayPath}`);
|
|
174
246
|
}
|
|
175
247
|
|
|
176
|
-
onProgress(_state: ProgressState): void {
|
|
177
|
-
// Simple reporter does not display progress bars
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
248
|
onStart(run: BenchmarkRun): void {
|
|
182
249
|
this.startTime = Date.now();
|
|
183
250
|
this.failures = []; // Reset failures for new run
|
|
@@ -197,7 +264,9 @@ export class SimpleReporter extends BaseReporter {
|
|
|
197
264
|
console.log(
|
|
198
265
|
` cpu: ${run.environment.cpu.model} (${run.environment.cpu.cores} cores)`,
|
|
199
266
|
);
|
|
200
|
-
console.log(
|
|
267
|
+
console.log(
|
|
268
|
+
` mem: ${SimpleReporter.formatBytes(run.environment.memory.total)}`,
|
|
269
|
+
);
|
|
201
270
|
console.log();
|
|
202
271
|
}
|
|
203
272
|
|
|
@@ -231,7 +300,7 @@ export class SimpleReporter extends BaseReporter {
|
|
|
231
300
|
console.log(` ${symbols.cross} ${failed} failed, ${passed} passed`);
|
|
232
301
|
} else {
|
|
233
302
|
console.log(
|
|
234
|
-
` ${symbols.checkmark} ${passed} ${
|
|
303
|
+
` ${symbols.checkmark} ${passed} ${SimpleReporter.pluralize('task', passed)} passed`,
|
|
235
304
|
);
|
|
236
305
|
}
|
|
237
306
|
console.log();
|
|
@@ -260,8 +329,11 @@ export class SimpleReporter extends BaseReporter {
|
|
|
260
329
|
return;
|
|
261
330
|
}
|
|
262
331
|
|
|
263
|
-
//
|
|
332
|
+
// Always buffer the result for suite summary (including aborted tasks)
|
|
264
333
|
this.suiteResults.push(result);
|
|
334
|
+
|
|
335
|
+
// Note: Aborted tasks are still printed in simple reporter for completeness
|
|
336
|
+
// but they'll have zero stats
|
|
265
337
|
}
|
|
266
338
|
|
|
267
339
|
onTaskStart(task: string): void {
|
|
@@ -275,44 +347,6 @@ export class SimpleReporter extends BaseReporter {
|
|
|
275
347
|
}
|
|
276
348
|
}
|
|
277
349
|
|
|
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
350
|
/**
|
|
317
351
|
* Print all task results in a suite with aligned columns
|
|
318
352
|
*/
|
|
@@ -364,9 +398,9 @@ export class SimpleReporter extends BaseReporter {
|
|
|
364
398
|
};
|
|
365
399
|
}
|
|
366
400
|
|
|
367
|
-
const duration =
|
|
368
|
-
const opsPerSec =
|
|
369
|
-
const rme =
|
|
401
|
+
const duration = BaseReporter.formatDuration(result.mean * 1e9);
|
|
402
|
+
const opsPerSec = BaseReporter.formatOpsPerSecond(result.opsPerSecond);
|
|
403
|
+
const rme = BaseReporter.formatPercentage(result.marginOfError); // already a percentage
|
|
370
404
|
|
|
371
405
|
return {
|
|
372
406
|
durationLen: duration.length,
|