tstest/test/tapbundle/test.timing-edge-cases.ts

214 lines
5.7 KiB
TypeScript

import { tap, expect } from '../../ts_tapbundle/index.js';
tap.test('ultra-fast test - should capture sub-millisecond timing', async () => {
// This test does almost nothing, should complete in < 1ms
const x = 1 + 1;
expect(x).toEqual(2);
});
tap.test('test with exact 1ms delay', async (tools) => {
const start = Date.now();
await tools.delayFor(1);
const elapsed = Date.now() - start;
// Should be at least 1ms but could be more due to event loop
expect(elapsed).toBeGreaterThanOrEqual(1);
});
tap.test('test with 10ms delay', async (tools) => {
await tools.delayFor(10);
expect(true).toBeTrue();
});
tap.test('test with 100ms delay', async (tools) => {
await tools.delayFor(100);
expect(true).toBeTrue();
});
tap.test('test with 250ms delay', async (tools) => {
await tools.delayFor(250);
expect(true).toBeTrue();
});
tap.test('test with 500ms delay', async (tools) => {
await tools.delayFor(500);
expect(true).toBeTrue();
});
tap.test('test with variable processing time', async (tools) => {
// Simulate variable processing
const iterations = 1000000;
let sum = 0;
for (let i = 0; i < iterations; i++) {
sum += Math.sqrt(i);
}
expect(sum).toBeGreaterThan(0);
// Add a small delay to ensure measurable time
await tools.delayFor(5);
});
tap.test('test with multiple async operations', async () => {
// Multiple promises in parallel
const results = await Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 10)),
new Promise(resolve => setTimeout(() => resolve(2), 20)),
new Promise(resolve => setTimeout(() => resolve(3), 30))
]);
expect(results).toEqual([1, 2, 3]);
// This should take at least 30ms (the longest delay)
});
tap.test('test with synchronous heavy computation', async () => {
// Heavy synchronous computation
const fibonacci = (n: number): number => {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
};
// Calculate fibonacci(30) - should take measurable time
const result = fibonacci(30);
expect(result).toEqual(832040);
});
// Test with retry to see if timing accumulates correctly
tap.retry(2).test('test with retry - fails first then passes', async (tools) => {
// Get or initialize retry count
const retryCount = tools.context.get('retryCount') || 0;
tools.context.set('retryCount', retryCount + 1);
await tools.delayFor(50);
if (retryCount === 0) {
throw new Error('First attempt fails');
}
expect(retryCount).toEqual(1);
});
// Test timeout handling
tap.timeout(100).test('test with timeout - should complete just in time', async (tools) => {
await tools.delayFor(80); // Just under the timeout
expect(true).toBeTrue();
});
// Skip test - should show 0ms
tap.skip.test('skipped test - should report 0ms', async (tools) => {
await tools.delayFor(1000); // This won't execute
expect(true).toBeTrue();
});
// Todo test - should show 0ms
tap.todo.test('todo test - should report 0ms', async (tools) => {
await tools.delayFor(1000); // This won't execute
expect(true).toBeTrue();
});
// Test with skip inside
tap.test('test that skips conditionally - should show time until skip', async (tools) => {
await tools.delayFor(25);
const shouldSkip = true;
if (shouldSkip) {
tools.skip('Skipping after 25ms');
}
// This won't execute
await tools.delayFor(1000);
expect(true).toBeTrue();
});
// Test with very precise timing
tap.test('test with precise timing measurements', async (tools) => {
const measurements: number[] = [];
for (let i = 0; i < 5; i++) {
const start = process.hrtime.bigint();
await tools.delayFor(10);
const end = process.hrtime.bigint();
const durationMs = Number(end - start) / 1_000_000;
measurements.push(durationMs);
}
// All measurements should be at least 10ms
measurements.forEach(m => {
expect(m).toBeGreaterThanOrEqual(10);
});
// But not too much more (accounting for timer precision)
measurements.forEach(m => {
expect(m).toBeLessThan(20);
});
});
// Test that intentionally has 0 actual work
tap.test('empty test - absolute minimum execution time', async () => {
// Literally nothing
});
// Test with promise that resolves immediately
tap.test('test with immediate promise resolution', async () => {
await Promise.resolve();
expect(true).toBeTrue();
});
// Test with microtask queue
tap.test('test with microtask queue processing', async () => {
let value = 0;
await Promise.resolve().then(() => {
value = 1;
return Promise.resolve();
}).then(() => {
value = 2;
return Promise.resolve();
}).then(() => {
value = 3;
});
expect(value).toEqual(3);
});
// Test to verify timing accumulation in describe blocks
tap.describe('timing in describe blocks', () => {
let startTime: number;
tap.beforeEach(async () => {
startTime = Date.now();
await new Promise(resolve => setTimeout(resolve, 5));
});
tap.afterEach(async () => {
await new Promise(resolve => setTimeout(resolve, 5));
});
tap.test('first test in describe', async (tools) => {
await tools.delayFor(10);
const elapsed = Date.now() - startTime;
expect(elapsed).toBeGreaterThanOrEqual(10);
});
tap.test('second test in describe', async (tools) => {
await tools.delayFor(20);
const elapsed = Date.now() - startTime;
expect(elapsed).toBeGreaterThanOrEqual(20);
});
});
// Parallel tests to see timing differences
tap.testParallel('parallel test 1 - 100ms', async (tools) => {
await tools.delayFor(100);
expect(true).toBeTrue();
});
tap.testParallel('parallel test 2 - 50ms', async (tools) => {
await tools.delayFor(50);
expect(true).toBeTrue();
});
tap.testParallel('parallel test 3 - 150ms', async (tools) => {
await tools.delayFor(150);
expect(true).toBeTrue();
});
tap.start();