Skip to content

Commit 20d34e9

Browse files
feat: add reporterOptions support with printHeader opt (#92)
Fixes: #88 Co-authored-by: Jason <jdmarshall@users.noreply.github.com>
1 parent ebac341 commit 20d34e9

File tree

5 files changed

+147
-25
lines changed

5 files changed

+147
-25
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,14 @@ A `Suite` manages and executes benchmark functions. It provides two methods: `ad
9797
### `new Suite([options])`
9898

9999
* `options` {Object} Configuration options for the suite.
100-
* `reporter` {Function} Callback function for reporting results. Receives one argument:
100+
* `reporter` {Function} Callback function for reporting results. Receives two arguments:
101101
* `results` {Object[]} Array of benchmark results:
102102
* `name` {string} Benchmark name.
103103
* `opsSec` {string} Operations per second.
104104
* `iterations` {Number} Number of iterations.
105105
* `histogram` {Histogram} Histogram instance.
106+
* `reporterOptions` {Object} Reporter-specific options.
107+
* `printHeader` {boolean} Whether to print system information header. **Default:** `true`.
106108
* `benchmarkMode` {string} Benchmark mode to use. Can be 'ops' or 'time'. **Default:** `'ops'`.
107109
* `'ops'` - Measures operations per second (traditional benchmarking).
108110
* `'time'` - Measures actual execution time for a single run.
@@ -252,9 +254,15 @@ const { Suite, chartReport } = require('bench-node');
252254

253255
const suite = new Suite({
254256
reporter: chartReport,
257+
// Optionally control header display
258+
reporterOptions: {
259+
printHeader: true // Set to false to hide system info header
260+
}
255261
});
256262
```
257263

264+
The `reporterOptions.printHeader` setting controls whether the system information (Node.js version, platform, and CPU cores) appears at the top of the output. This is useful when running multiple suites in sequence and you want to avoid duplicate headers.
265+
258266
### `htmlReport`
259267

260268
The `htmlReport` generates an interactive HTML visualization of benchmark results.

examples/chart-report/node.js

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,46 @@
11
const { Suite, chartReport } = require('../../lib');
22
const assert = require('node:assert');
33

4-
const suite = new Suite({
5-
reporter: chartReport,
6-
});
4+
async function runSuiteOne() {
5+
const suite = new Suite({
6+
reporter: chartReport,
7+
});
78

8-
suite
9-
.add('single with matcher', function () {
10-
const pattern = /[123]/g
11-
const replacements = { 1: 'a', 2: 'b', 3: 'c' }
12-
const subject = '123123123123123123123123123123123123123123123123'
13-
const r = subject.replace(pattern, m => replacements[m])
14-
assert.ok(r);
15-
})
16-
.add('multiple replaces', function () {
17-
const subject = '123123123123123123123123123123123123123123123123'
18-
const r = subject.replace(/1/g, 'a').replace(/2/g, 'b').replace(/3/g, 'c')
19-
assert.ok(r);
20-
})
21-
.run();
9+
await suite
10+
.add('test 1', function () {
11+
const pattern = /[123]/g
12+
})
13+
.add('test 2', function () {
14+
const subject = '123123123123123123123123123123123123123123123123'
15+
const r = subject.replace(/1/g, 'a').replace(/2/g, 'b').replace(/3/g, 'c')
16+
})
17+
.run();
18+
}
19+
20+
async function runSuiteTwo() {
21+
const suite = new Suite({
22+
reporter: chartReport,
23+
reporterOptions: {
24+
printHeader: false
25+
}
26+
});
27+
28+
await suite
29+
.add('test 3', function () {
30+
const pattern = /[123]/g
31+
})
32+
.add('test 4', function () {
33+
const subject = '123123123123123123123123123123123123123123123123'
34+
const r = subject.replace(/1/g, 'a').replace(/2/g, 'b').replace(/3/g, 'c')
35+
assert.ok(r)
36+
})
37+
.run();
38+
}
39+
40+
async function main() {
41+
await runSuiteOne()
42+
process.stdout.write('\n\n')
43+
await runSuiteTwo()
44+
}
45+
46+
main()

lib/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class Suite {
108108
#plugins;
109109
#useWorkers;
110110
#benchmarkMode;
111+
#reporterOptions;
111112

112113
constructor(options = {}) {
113114
this.#benchmarks = [];
@@ -135,6 +136,10 @@ class Suite {
135136
// Benchmark Mode setup
136137
this.#benchmarkMode = options.benchmarkMode || "ops"; // Default to 'ops'
137138
validateBenchmarkMode(this.#benchmarkMode, "options.benchmarkMode");
139+
140+
this.#reporterOptions = options.reporterOptions || {
141+
printHeader: true,
142+
};
138143
}
139144

140145
add(name, options, fn) {
@@ -236,7 +241,7 @@ class Suite {
236241
}
237242

238243
if (this.#reporter) {
239-
this.#reporter(results);
244+
this.#reporter(results, this.#reporterOptions);
240245
}
241246

242247
return results;

lib/reporter/chart.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,19 @@ const environment = {
7272
* Displays system information and a bar chart of operations per second or time per operation
7373
* @param {import('../report').BenchmarkResult[]} results - Array of benchmark results
7474
*/
75-
function chartReport(results) {
75+
function chartReport(results, options) {
7676
// Determine the primary metric and calculate max value for scaling
7777
const primaryMetric =
7878
results[0]?.opsSec !== undefined ? "opsSec" : "totalTime";
7979
const maxValue = Math.max(...results.map((b) => b[primaryMetric]));
8080

81-
process.stdout.write(
82-
`${environment.nodeVersion}\n` +
83-
`Platform: ${environment.platform}\n` +
84-
`CPU Cores: ${environment.hardware}\n\n`,
85-
);
81+
if (options?.printHeader) {
82+
process.stdout.write(
83+
`${environment.nodeVersion}\n` +
84+
`Platform: ${environment.platform}\n` +
85+
`CPU Cores: ${environment.hardware}\n\n`,
86+
);
87+
}
8688

8789
for (const result of results) {
8890
drawBar(

test/reporter.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,88 @@ describe("chartReport outputs benchmark results as a bar chart", async (t) => {
7070
});
7171
});
7272

73+
describe("chartReport respects reporterOptions.printHeader", async (t) => {
74+
let outputWithHeader = "";
75+
let outputWithoutHeader = "";
76+
77+
before(async () => {
78+
const originalStdoutWrite = process.stdout.write;
79+
80+
// Test with default settings (printHeader: true)
81+
process.stdout.write = (data) => {
82+
outputWithHeader += data;
83+
};
84+
85+
const suiteWithHeader = new Suite({
86+
reporter: chartReport,
87+
reporterOptions: {
88+
printHeader: true,
89+
},
90+
});
91+
92+
suiteWithHeader.add("test benchmark", () => {
93+
const a = 1 + 1;
94+
assert.strictEqual(a, 2);
95+
});
96+
await suiteWithHeader.run();
97+
98+
// Test with printHeader: false
99+
outputWithoutHeader = "";
100+
process.stdout.write = (data) => {
101+
outputWithoutHeader += data;
102+
};
103+
104+
const suiteWithoutHeader = new Suite({
105+
reporter: chartReport,
106+
reporterOptions: {
107+
printHeader: false,
108+
},
109+
});
110+
111+
suiteWithoutHeader.add("test benchmark", () => {
112+
const a = 1 + 1;
113+
assert.strictEqual(a, 2);
114+
});
115+
await suiteWithoutHeader.run();
116+
117+
process.stdout.write = originalStdoutWrite;
118+
});
119+
120+
it("should include Node.js version when printHeader is true", () => {
121+
const regex = /Node\.js version: v\d+\.\d+\.\d+/;
122+
assert.ok(outputWithHeader.match(regex));
123+
});
124+
125+
it("should include Platform when printHeader is true", () => {
126+
assert.ok(outputWithHeader.includes("Platform:"));
127+
});
128+
129+
it("should include CPU Cores when printHeader is true", () => {
130+
assert.ok(outputWithHeader.includes("CPU Cores:"));
131+
});
132+
133+
it("should NOT include Node.js version when printHeader is false", () => {
134+
const regex = /Node\.js version: v\d+\.\d+\.\d+/;
135+
assert.ok(!outputWithoutHeader.match(regex));
136+
});
137+
138+
it("should NOT include Platform when printHeader is false", () => {
139+
assert.ok(!outputWithoutHeader.includes("Platform:"));
140+
});
141+
142+
it("should NOT include CPU Cores when printHeader is false", () => {
143+
assert.ok(!outputWithoutHeader.includes("CPU Cores:"));
144+
});
145+
146+
it("should still include benchmark data with or without header", () => {
147+
// Both outputs should still have benchmark bars and results
148+
assert.ok(outputWithHeader.includes("█"));
149+
assert.ok(outputWithoutHeader.includes("█"));
150+
assert.ok(outputWithHeader.includes("test benchmark"));
151+
assert.ok(outputWithoutHeader.includes("test benchmark"));
152+
});
153+
});
154+
73155
describe("htmlReport should create a file", async (t) => {
74156
let output = "";
75157
let htmlName = "";

0 commit comments

Comments
 (0)