- Deleted event-utils.ts which contained deprecated Port80Handler and its subscribers. - Updated index.ts to remove the export of event-utils. - Refactored ConnectionManager to extend LifecycleComponent for better resource management. - Added BinaryHeap implementation for efficient priority queue operations. - Introduced EnhancedConnectionPool for managing pooled connections with lifecycle management. - Implemented LifecycleComponent to manage timers and event listeners automatically. - Added comprehensive tests for BinaryHeap and LifecycleComponent to ensure functionality.
206 lines
5.6 KiB
TypeScript
206 lines
5.6 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
import { BinaryHeap } from '../../../ts/core/utils/binary-heap.js';
|
|
|
|
interface TestItem {
|
|
id: string;
|
|
priority: number;
|
|
value: string;
|
|
}
|
|
|
|
tap.test('should create empty heap', async () => {
|
|
const heap = new BinaryHeap<number>((a, b) => a - b);
|
|
|
|
expect(heap.size).toEqual(0);
|
|
expect(heap.isEmpty()).toBeTrue();
|
|
expect(heap.peek()).toBeUndefined();
|
|
});
|
|
|
|
tap.test('should insert and extract in correct order', async () => {
|
|
const heap = new BinaryHeap<number>((a, b) => a - b);
|
|
|
|
heap.insert(5);
|
|
heap.insert(3);
|
|
heap.insert(7);
|
|
heap.insert(1);
|
|
heap.insert(9);
|
|
heap.insert(4);
|
|
|
|
expect(heap.size).toEqual(6);
|
|
|
|
// Extract in ascending order
|
|
expect(heap.extract()).toEqual(1);
|
|
expect(heap.extract()).toEqual(3);
|
|
expect(heap.extract()).toEqual(4);
|
|
expect(heap.extract()).toEqual(5);
|
|
expect(heap.extract()).toEqual(7);
|
|
expect(heap.extract()).toEqual(9);
|
|
expect(heap.extract()).toBeUndefined();
|
|
});
|
|
|
|
tap.test('should work with custom objects and comparator', async () => {
|
|
const heap = new BinaryHeap<TestItem>(
|
|
(a, b) => a.priority - b.priority,
|
|
(item) => item.id
|
|
);
|
|
|
|
heap.insert({ id: 'a', priority: 5, value: 'five' });
|
|
heap.insert({ id: 'b', priority: 2, value: 'two' });
|
|
heap.insert({ id: 'c', priority: 8, value: 'eight' });
|
|
heap.insert({ id: 'd', priority: 1, value: 'one' });
|
|
|
|
const first = heap.extract();
|
|
expect(first?.priority).toEqual(1);
|
|
expect(first?.value).toEqual('one');
|
|
|
|
const second = heap.extract();
|
|
expect(second?.priority).toEqual(2);
|
|
expect(second?.value).toEqual('two');
|
|
});
|
|
|
|
tap.test('should support reverse order (max heap)', async () => {
|
|
const heap = new BinaryHeap<number>((a, b) => b - a);
|
|
|
|
heap.insert(5);
|
|
heap.insert(3);
|
|
heap.insert(7);
|
|
heap.insert(1);
|
|
heap.insert(9);
|
|
|
|
// Extract in descending order
|
|
expect(heap.extract()).toEqual(9);
|
|
expect(heap.extract()).toEqual(7);
|
|
expect(heap.extract()).toEqual(5);
|
|
});
|
|
|
|
tap.test('should extract by predicate', async () => {
|
|
const heap = new BinaryHeap<TestItem>((a, b) => a.priority - b.priority);
|
|
|
|
heap.insert({ id: 'a', priority: 5, value: 'five' });
|
|
heap.insert({ id: 'b', priority: 2, value: 'two' });
|
|
heap.insert({ id: 'c', priority: 8, value: 'eight' });
|
|
|
|
const extracted = heap.extractIf(item => item.id === 'b');
|
|
expect(extracted?.id).toEqual('b');
|
|
expect(heap.size).toEqual(2);
|
|
|
|
// Should not find it again
|
|
const notFound = heap.extractIf(item => item.id === 'b');
|
|
expect(notFound).toBeUndefined();
|
|
});
|
|
|
|
tap.test('should extract by key', async () => {
|
|
const heap = new BinaryHeap<TestItem>(
|
|
(a, b) => a.priority - b.priority,
|
|
(item) => item.id
|
|
);
|
|
|
|
heap.insert({ id: 'a', priority: 5, value: 'five' });
|
|
heap.insert({ id: 'b', priority: 2, value: 'two' });
|
|
heap.insert({ id: 'c', priority: 8, value: 'eight' });
|
|
|
|
expect(heap.hasKey('b')).toBeTrue();
|
|
|
|
const extracted = heap.extractByKey('b');
|
|
expect(extracted?.id).toEqual('b');
|
|
expect(heap.size).toEqual(2);
|
|
expect(heap.hasKey('b')).toBeFalse();
|
|
|
|
// Should not find it again
|
|
const notFound = heap.extractByKey('b');
|
|
expect(notFound).toBeUndefined();
|
|
});
|
|
|
|
tap.test('should throw when using key operations without extractKey', async () => {
|
|
const heap = new BinaryHeap<TestItem>((a, b) => a.priority - b.priority);
|
|
|
|
heap.insert({ id: 'a', priority: 5, value: 'five' });
|
|
|
|
let error: Error | null = null;
|
|
try {
|
|
heap.extractByKey('a');
|
|
} catch (e: any) {
|
|
error = e;
|
|
}
|
|
|
|
expect(error).not.toBeNull();
|
|
expect(error?.message).toContain('extractKey function must be provided');
|
|
});
|
|
|
|
tap.test('should handle duplicates correctly', async () => {
|
|
const heap = new BinaryHeap<number>((a, b) => a - b);
|
|
|
|
heap.insert(5);
|
|
heap.insert(5);
|
|
heap.insert(5);
|
|
heap.insert(3);
|
|
heap.insert(7);
|
|
|
|
expect(heap.size).toEqual(5);
|
|
expect(heap.extract()).toEqual(3);
|
|
expect(heap.extract()).toEqual(5);
|
|
expect(heap.extract()).toEqual(5);
|
|
expect(heap.extract()).toEqual(5);
|
|
expect(heap.extract()).toEqual(7);
|
|
});
|
|
|
|
tap.test('should convert to array without modifying heap', async () => {
|
|
const heap = new BinaryHeap<number>((a, b) => a - b);
|
|
|
|
heap.insert(5);
|
|
heap.insert(3);
|
|
heap.insert(7);
|
|
|
|
const array = heap.toArray();
|
|
expect(array).toContain(3);
|
|
expect(array).toContain(5);
|
|
expect(array).toContain(7);
|
|
expect(array.length).toEqual(3);
|
|
|
|
// Heap should still be intact
|
|
expect(heap.size).toEqual(3);
|
|
expect(heap.extract()).toEqual(3);
|
|
});
|
|
|
|
tap.test('should clear the heap', async () => {
|
|
const heap = new BinaryHeap<TestItem>(
|
|
(a, b) => a.priority - b.priority,
|
|
(item) => item.id
|
|
);
|
|
|
|
heap.insert({ id: 'a', priority: 5, value: 'five' });
|
|
heap.insert({ id: 'b', priority: 2, value: 'two' });
|
|
|
|
expect(heap.size).toEqual(2);
|
|
expect(heap.hasKey('a')).toBeTrue();
|
|
|
|
heap.clear();
|
|
|
|
expect(heap.size).toEqual(0);
|
|
expect(heap.isEmpty()).toBeTrue();
|
|
expect(heap.hasKey('a')).toBeFalse();
|
|
});
|
|
|
|
tap.test('should handle complex extraction patterns', async () => {
|
|
const heap = new BinaryHeap<number>((a, b) => a - b);
|
|
|
|
// Insert numbers 1-10 in random order
|
|
[8, 3, 5, 9, 1, 7, 4, 10, 2, 6].forEach(n => heap.insert(n));
|
|
|
|
// Extract some in order
|
|
expect(heap.extract()).toEqual(1);
|
|
expect(heap.extract()).toEqual(2);
|
|
|
|
// Insert more
|
|
heap.insert(0);
|
|
heap.insert(1.5);
|
|
|
|
// Continue extracting
|
|
expect(heap.extract()).toEqual(0);
|
|
expect(heap.extract()).toEqual(1.5);
|
|
expect(heap.extract()).toEqual(3);
|
|
|
|
// Verify remaining size (10 - 2 extracted + 2 inserted - 3 extracted = 7)
|
|
expect(heap.size).toEqual(7);
|
|
});
|
|
|
|
tap.start(); |