fix(protocol): Fix inline timing metadata parsing and enhance test coverage for performance metrics and timing edge cases
This commit is contained in:
204
test/tapbundle/test.timing-protocol.ts
Normal file
204
test/tapbundle/test.timing-protocol.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
import { ProtocolParser, ProtocolEmitter } from '../../ts_tapbundle_protocol/index.js';
|
||||
|
||||
// Test the protocol's ability to emit and parse timing metadata
|
||||
tap.test('protocol should correctly emit timing metadata', async () => {
|
||||
const emitter = new ProtocolEmitter();
|
||||
|
||||
const testResult = {
|
||||
ok: true,
|
||||
testNumber: 1,
|
||||
description: 'test with timing',
|
||||
metadata: {
|
||||
time: 123
|
||||
}
|
||||
};
|
||||
|
||||
const lines = emitter.emitTest(testResult);
|
||||
|
||||
// Should have inline timing metadata
|
||||
expect(lines.length).toEqual(1);
|
||||
expect(lines[0]).toInclude('⟦TSTEST:time:123⟧');
|
||||
});
|
||||
|
||||
tap.test('protocol should correctly parse timing metadata', async () => {
|
||||
const parser = new ProtocolParser();
|
||||
|
||||
const line = 'ok 1 - test with timing ⟦TSTEST:time:456⟧';
|
||||
const messages = parser.parseLine(line);
|
||||
|
||||
expect(messages.length).toEqual(1);
|
||||
expect(messages[0].type).toEqual('test');
|
||||
|
||||
const content = messages[0].content as any;
|
||||
expect(content.metadata).toBeDefined();
|
||||
expect(content.metadata.time).toEqual(456);
|
||||
});
|
||||
|
||||
tap.test('protocol should handle 0ms timing', async () => {
|
||||
const parser = new ProtocolParser();
|
||||
|
||||
const line = 'ok 1 - ultra fast test ⟦TSTEST:time:0⟧';
|
||||
const messages = parser.parseLine(line);
|
||||
|
||||
const content = messages[0].content as any;
|
||||
expect(content.metadata.time).toEqual(0);
|
||||
});
|
||||
|
||||
tap.test('protocol should handle large timing values', async () => {
|
||||
const parser = new ProtocolParser();
|
||||
|
||||
const line = 'ok 1 - slow test ⟦TSTEST:time:999999⟧';
|
||||
const messages = parser.parseLine(line);
|
||||
|
||||
const content = messages[0].content as any;
|
||||
expect(content.metadata.time).toEqual(999999);
|
||||
});
|
||||
|
||||
tap.test('protocol should handle timing with other metadata', async () => {
|
||||
const emitter = new ProtocolEmitter();
|
||||
|
||||
const testResult = {
|
||||
ok: true,
|
||||
testNumber: 1,
|
||||
description: 'complex test',
|
||||
metadata: {
|
||||
time: 789,
|
||||
file: 'test.ts',
|
||||
tags: ['slow', 'integration']
|
||||
}
|
||||
};
|
||||
|
||||
const lines = emitter.emitTest(testResult);
|
||||
|
||||
// Should use block metadata format for complex metadata
|
||||
expect(lines.length).toBeGreaterThan(1);
|
||||
expect(lines[1]).toInclude('META:');
|
||||
expect(lines[1]).toInclude('"time":789');
|
||||
});
|
||||
|
||||
tap.test('protocol should parse timing from block metadata', async () => {
|
||||
const parser = new ProtocolParser();
|
||||
|
||||
const lines = [
|
||||
'ok 1 - complex test',
|
||||
'⟦TSTEST:META:{"time":321,"file":"test.ts"}⟧'
|
||||
];
|
||||
|
||||
let testResult: any;
|
||||
|
||||
for (const line of lines) {
|
||||
const messages = parser.parseLine(line);
|
||||
if (messages.length > 0 && messages[0].type === 'test') {
|
||||
testResult = messages[0].content;
|
||||
}
|
||||
}
|
||||
|
||||
expect(testResult).toBeDefined();
|
||||
expect(testResult.metadata).toBeUndefined(); // Metadata comes separately in block format
|
||||
});
|
||||
|
||||
tap.test('timing for skipped tests should be 0 or missing', async () => {
|
||||
const emitter = new ProtocolEmitter();
|
||||
|
||||
const testResult = {
|
||||
ok: true,
|
||||
testNumber: 1,
|
||||
description: 'skipped test',
|
||||
directive: {
|
||||
type: 'skip' as const,
|
||||
reason: 'Not ready'
|
||||
},
|
||||
metadata: {
|
||||
time: 0
|
||||
}
|
||||
};
|
||||
|
||||
const lines = emitter.emitTest(testResult);
|
||||
expect(lines[0]).toInclude('# SKIP');
|
||||
|
||||
// If time is 0, it might be included or omitted
|
||||
if (lines[0].includes('⟦TSTEST:')) {
|
||||
expect(lines[0]).toInclude('time:0');
|
||||
}
|
||||
});
|
||||
|
||||
tap.test('protocol should handle fractional milliseconds', async () => {
|
||||
const emitter = new ProtocolEmitter();
|
||||
|
||||
// Even though we use integers, test that protocol handles them correctly
|
||||
const testResult = {
|
||||
ok: true,
|
||||
testNumber: 1,
|
||||
description: 'precise test',
|
||||
metadata: {
|
||||
time: 123 // Protocol uses integers for milliseconds
|
||||
}
|
||||
};
|
||||
|
||||
const lines = emitter.emitTest(testResult);
|
||||
expect(lines[0]).toInclude('time:123');
|
||||
});
|
||||
|
||||
tap.test('protocol should handle timing in retry scenarios', async () => {
|
||||
const emitter = new ProtocolEmitter();
|
||||
|
||||
const testResult = {
|
||||
ok: true,
|
||||
testNumber: 1,
|
||||
description: 'retry test',
|
||||
metadata: {
|
||||
time: 200,
|
||||
retry: 2
|
||||
}
|
||||
};
|
||||
|
||||
const lines = emitter.emitTest(testResult);
|
||||
// Should include both time and retry
|
||||
expect(lines[0]).toMatch(/time:200.*retry:2|retry:2.*time:200/);
|
||||
});
|
||||
|
||||
// Test actual timing capture
|
||||
tap.test('HrtMeasurement should capture accurate timing', async (tools) => {
|
||||
// Import HrtMeasurement
|
||||
const { HrtMeasurement } = await import('@push.rocks/smarttime');
|
||||
|
||||
const measurement = new HrtMeasurement();
|
||||
measurement.start();
|
||||
|
||||
await tools.delayFor(50);
|
||||
|
||||
measurement.stop();
|
||||
|
||||
// Should be at least 50ms
|
||||
expect(measurement.milliSeconds).toBeGreaterThanOrEqual(50);
|
||||
// But not too much more (allow for some overhead)
|
||||
expect(measurement.milliSeconds).toBeLessThan(100);
|
||||
});
|
||||
|
||||
tap.test('multiple timing measurements should be independent', async (tools) => {
|
||||
const { HrtMeasurement } = await import('@push.rocks/smarttime');
|
||||
|
||||
const measurement1 = new HrtMeasurement();
|
||||
const measurement2 = new HrtMeasurement();
|
||||
|
||||
measurement1.start();
|
||||
await tools.delayFor(25);
|
||||
|
||||
measurement2.start();
|
||||
await tools.delayFor(25);
|
||||
|
||||
measurement1.stop();
|
||||
await tools.delayFor(25);
|
||||
measurement2.stop();
|
||||
|
||||
// measurement1 should be ~50ms (25ms + 25ms)
|
||||
expect(measurement1.milliSeconds).toBeGreaterThanOrEqual(50);
|
||||
expect(measurement1.milliSeconds).toBeLessThan(70);
|
||||
|
||||
// measurement2 should be ~50ms (25ms + 25ms)
|
||||
expect(measurement2.milliSeconds).toBeGreaterThanOrEqual(50);
|
||||
expect(measurement2.milliSeconds).toBeLessThan(70);
|
||||
});
|
||||
|
||||
tap.start();
|
Reference in New Issue
Block a user