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