tstest/test/tapbundle/test.timing-protocol.ts

204 lines
5.5 KiB
TypeScript

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();