Skip to content

Commit 3698d61

Browse files
boneskullclaude
andcommitted
fix(output): use UTC timestamps and improve test patterns
- Use UTC time methods for consistent timestamped filenames - Make regex patterns more specific to match exact timestamp format - Replace 1100ms delay test with Date mocking for faster execution 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent ab6559d commit 3698d61

File tree

5 files changed

+48
-17
lines changed

5 files changed

+48
-17
lines changed

src/core/output-path-resolver.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import { extname, isAbsolute, join, resolve } from 'node:path';
44
* Generates a timestamped filename for benchmark output files.
55
*
66
* @param extension - File extension without the dot (e.g., 'json', 'csv')
7-
* @returns Filename in format `benchmarks-YYYY-MM-DD-HH-MM-SS.{extension}`
7+
* @returns Filename in format `benchmarks-YYYY-MM-DD-HH-MM-SS.{extension}` (UTC
8+
* time)
89
*/
910
export const generateTimestampedFilename = (extension: string): string => {
1011
const now = new Date();
1112
const pad = (n: number) => n.toString().padStart(2, '0');
12-
const timestamp = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${pad(now.getHours())}-${pad(now.getMinutes())}-${pad(now.getSeconds())}`;
13+
const timestamp = `${now.getUTCFullYear()}-${pad(now.getUTCMonth() + 1)}-${pad(now.getUTCDate())}-${pad(now.getUTCHours())}-${pad(now.getUTCMinutes())}-${pad(now.getUTCSeconds())}`;
1314
return `benchmarks-${timestamp}.${extension}`;
1415
};
1516

test/integration/quiet-mode.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,15 @@ describe('Quiet Mode Integration Tests', () => {
158158
// Both JSON and CSV files should be written with timestamped names
159159
const jsonFile = await findFileByPattern(
160160
outputDir,
161-
/^benchmarks-.*\.json$/,
161+
/^benchmarks-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.json$/,
162162
);
163163
expect(jsonFile, 'to be truthy');
164164
const jsonContent = await readFile(jsonFile!, 'utf-8');
165165
expect(jsonContent, 'to match', /"meta":/);
166166

167167
const csvFile = await findFileByPattern(
168168
outputDir,
169-
/^benchmarks-.*\.csv$/,
169+
/^benchmarks-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.csv$/,
170170
);
171171
expect(csvFile, 'to be truthy');
172172
const csvContent = await readFile(csvFile!, 'utf-8');
@@ -227,7 +227,7 @@ describe('Quiet Mode Integration Tests', () => {
227227
// Verify file was written with timestamped name
228228
const outputFile = await findFileByPattern(
229229
outputDir,
230-
/^benchmarks-.*\.json$/,
230+
/^benchmarks-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.json$/,
231231
);
232232
expect(outputFile, 'to be truthy');
233233
const fileExists = existsSync(outputFile!);

test/integration/reporters.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,11 @@ describe('Multiple reporter output formats', () => {
245245
// Should create json and csv files with timestamped names
246246
const jsonFile = await findFileByPattern(
247247
outputDir,
248-
/^benchmarks-.*\.json$/,
248+
/^benchmarks-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.json$/,
249249
);
250250
const csvFile = await findFileByPattern(
251251
outputDir,
252-
/^benchmarks-.*\.csv$/,
252+
/^benchmarks-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.csv$/,
253253
);
254254

255255
expect(jsonFile, 'to be truthy');
@@ -305,7 +305,7 @@ describe('Multiple reporter output formats', () => {
305305
// Should create nested directories and timestamped files
306306
const jsonFile = await findFileByPattern(
307307
outputDir,
308-
/^benchmarks-.*\.json$/,
308+
/^benchmarks-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.json$/,
309309
);
310310
expect(jsonFile, 'to be truthy');
311311
const jsonContent = await readFile(jsonFile!, 'utf-8');

test/integration/verbose-mode.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ describe('Verbose Mode Integration Tests', () => {
251251
// JSON data should be written to file with timestamped name
252252
const jsonFile = await findFileByPattern(
253253
outputDir,
254-
/^benchmarks-.*\.json$/,
254+
/^benchmarks-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.json$/,
255255
);
256256
expect(jsonFile, 'to be truthy');
257257
const jsonContent = await readFile(jsonFile!, 'utf-8');
@@ -277,7 +277,7 @@ describe('Verbose Mode Integration Tests', () => {
277277
// JSON data should be written to file with timestamped name
278278
const jsonFile = await findFileByPattern(
279279
outputDir,
280-
/^benchmarks-.*\.json$/,
280+
/^benchmarks-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.json$/,
281281
);
282282
expect(jsonFile, 'to be truthy');
283283
const jsonContent = await readFile(jsonFile!, 'utf-8');
@@ -307,7 +307,7 @@ describe('Verbose Mode Integration Tests', () => {
307307
// CSV data should be written to file with timestamped name
308308
const csvFile = await findFileByPattern(
309309
outputDir,
310-
/^benchmarks-.*\.csv$/,
310+
/^benchmarks-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}\.csv$/,
311311
);
312312
expect(csvFile, 'to be truthy');
313313
const csvContent = await readFile(csvFile!, 'utf-8');

test/unit/output-path-resolver.test.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,42 @@ describe('generateTimestampedFilename', () => {
7676
);
7777
});
7878

79-
it('should generate different filenames at different times', async () => {
80-
const result1 = generateTimestampedFilename('json');
81-
// Wait a second to ensure different timestamp
82-
await new Promise((resolve) => setTimeout(resolve, 1100));
83-
const result2 = generateTimestampedFilename('json');
84-
expect(result1, 'not to equal', result2);
79+
it('should generate different filenames at different times', () => {
80+
const RealDate = globalThis.Date;
81+
82+
const fixedTime1 = new RealDate('2020-01-01T00:00:00Z').getTime();
83+
const fixedTime2 = new RealDate('2020-01-01T00:00:01Z').getTime();
84+
85+
const mockDate = (ms: number) => {
86+
const MockDate = class extends RealDate {
87+
constructor(...args: Parameters<typeof RealDate>) {
88+
if (args.length === 0) {
89+
super(ms);
90+
} else {
91+
super(...args);
92+
}
93+
}
94+
95+
static override now() {
96+
return ms;
97+
}
98+
};
99+
globalThis.Date = MockDate as typeof Date;
100+
};
101+
102+
try {
103+
mockDate(fixedTime1);
104+
const result1 = generateTimestampedFilename('json');
105+
106+
mockDate(fixedTime2);
107+
const result2 = generateTimestampedFilename('json');
108+
109+
expect(result1, 'not to equal', result2);
110+
expect(result1, 'to equal', 'benchmarks-2020-01-01-00-00-00.json');
111+
expect(result2, 'to equal', 'benchmarks-2020-01-01-00-00-01.json');
112+
} finally {
113+
globalThis.Date = RealDate;
114+
}
85115
});
86116

87117
it('should use zero-padded date and time components', () => {

0 commit comments

Comments
 (0)