fix(refactor): remove deprecated Port80Handler and related utilities
- 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.
This commit is contained in:
252
test/core/utils/test.lifecycle-component.ts
Normal file
252
test/core/utils/test.lifecycle-component.ts
Normal file
@ -0,0 +1,252 @@
|
||||
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
||||
import { LifecycleComponent } from '../../../ts/core/utils/lifecycle-component.js';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
// Test implementation of LifecycleComponent
|
||||
class TestComponent extends LifecycleComponent {
|
||||
public timerCallCount = 0;
|
||||
public intervalCallCount = 0;
|
||||
public cleanupCalled = false;
|
||||
public testEmitter = new EventEmitter();
|
||||
public listenerCallCount = 0;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.setupTimers();
|
||||
this.setupListeners();
|
||||
}
|
||||
|
||||
private setupTimers() {
|
||||
// Set up a timeout
|
||||
this.setTimeout(() => {
|
||||
this.timerCallCount++;
|
||||
}, 100);
|
||||
|
||||
// Set up an interval
|
||||
this.setInterval(() => {
|
||||
this.intervalCallCount++;
|
||||
}, 50);
|
||||
}
|
||||
|
||||
private setupListeners() {
|
||||
this.addEventListener(this.testEmitter, 'test-event', () => {
|
||||
this.listenerCallCount++;
|
||||
});
|
||||
}
|
||||
|
||||
protected async onCleanup(): Promise<void> {
|
||||
this.cleanupCalled = true;
|
||||
}
|
||||
|
||||
// Expose protected methods for testing
|
||||
public testSetTimeout(handler: Function, timeout: number): NodeJS.Timeout {
|
||||
return this.setTimeout(handler, timeout);
|
||||
}
|
||||
|
||||
public testSetInterval(handler: Function, interval: number): NodeJS.Timeout {
|
||||
return this.setInterval(handler, interval);
|
||||
}
|
||||
|
||||
public testClearTimeout(timer: NodeJS.Timeout): void {
|
||||
return this.clearTimeout(timer);
|
||||
}
|
||||
|
||||
public testClearInterval(timer: NodeJS.Timeout): void {
|
||||
return this.clearInterval(timer);
|
||||
}
|
||||
|
||||
public testAddEventListener(target: any, event: string, handler: Function): void {
|
||||
return this.addEventListener(target, event, handler);
|
||||
}
|
||||
|
||||
public testIsShuttingDown(): boolean {
|
||||
return this.isShuttingDownState();
|
||||
}
|
||||
}
|
||||
|
||||
tap.test('should manage timers properly', async () => {
|
||||
const component = new TestComponent();
|
||||
|
||||
// Wait for timers to fire
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
|
||||
expect(component.timerCallCount).toEqual(1);
|
||||
expect(component.intervalCallCount).toBeGreaterThan(2);
|
||||
|
||||
await component.cleanup();
|
||||
});
|
||||
|
||||
tap.test('should manage event listeners properly', async () => {
|
||||
const component = new TestComponent();
|
||||
|
||||
// Emit events
|
||||
component.testEmitter.emit('test-event');
|
||||
component.testEmitter.emit('test-event');
|
||||
|
||||
expect(component.listenerCallCount).toEqual(2);
|
||||
|
||||
// Cleanup and verify listeners are removed
|
||||
await component.cleanup();
|
||||
|
||||
component.testEmitter.emit('test-event');
|
||||
expect(component.listenerCallCount).toEqual(2); // Should not increase
|
||||
});
|
||||
|
||||
tap.test('should prevent timer execution after cleanup', async () => {
|
||||
const component = new TestComponent();
|
||||
|
||||
let laterCallCount = 0;
|
||||
component.testSetTimeout(() => {
|
||||
laterCallCount++;
|
||||
}, 100);
|
||||
|
||||
// Cleanup immediately
|
||||
await component.cleanup();
|
||||
|
||||
// Wait for timer that would have fired
|
||||
await new Promise(resolve => setTimeout(resolve, 150));
|
||||
|
||||
expect(laterCallCount).toEqual(0);
|
||||
});
|
||||
|
||||
tap.test('should handle child components', async () => {
|
||||
class ParentComponent extends LifecycleComponent {
|
||||
public child: TestComponent;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.child = new TestComponent();
|
||||
this.registerChildComponent(this.child);
|
||||
}
|
||||
}
|
||||
|
||||
const parent = new ParentComponent();
|
||||
|
||||
// Wait for child timers
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
expect(parent.child.timerCallCount).toEqual(1);
|
||||
|
||||
// Cleanup parent should cleanup child
|
||||
await parent.cleanup();
|
||||
|
||||
expect(parent.child.cleanupCalled).toBeTrue();
|
||||
expect(parent.child.testIsShuttingDown()).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('should handle multiple cleanup calls gracefully', async () => {
|
||||
const component = new TestComponent();
|
||||
|
||||
// Call cleanup multiple times
|
||||
const promises = [
|
||||
component.cleanup(),
|
||||
component.cleanup(),
|
||||
component.cleanup()
|
||||
];
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
// Should only clean up once
|
||||
expect(component.cleanupCalled).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('should clear specific timers', async () => {
|
||||
const component = new TestComponent();
|
||||
|
||||
let callCount = 0;
|
||||
const timer = component.testSetTimeout(() => {
|
||||
callCount++;
|
||||
}, 100);
|
||||
|
||||
// Clear the timer
|
||||
component.testClearTimeout(timer);
|
||||
|
||||
// Wait and verify it didn't fire
|
||||
await new Promise(resolve => setTimeout(resolve, 150));
|
||||
|
||||
expect(callCount).toEqual(0);
|
||||
|
||||
await component.cleanup();
|
||||
});
|
||||
|
||||
tap.test('should clear specific intervals', async () => {
|
||||
const component = new TestComponent();
|
||||
|
||||
let callCount = 0;
|
||||
const interval = component.testSetInterval(() => {
|
||||
callCount++;
|
||||
}, 50);
|
||||
|
||||
// Let it run a bit
|
||||
await new Promise(resolve => setTimeout(resolve, 120));
|
||||
|
||||
const countBeforeClear = callCount;
|
||||
expect(countBeforeClear).toBeGreaterThan(1);
|
||||
|
||||
// Clear the interval
|
||||
component.testClearInterval(interval);
|
||||
|
||||
// Wait and verify it stopped
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
expect(callCount).toEqual(countBeforeClear);
|
||||
|
||||
await component.cleanup();
|
||||
});
|
||||
|
||||
tap.test('should handle once event listeners', async () => {
|
||||
const component = new TestComponent();
|
||||
const emitter = new EventEmitter();
|
||||
|
||||
let callCount = 0;
|
||||
const handler = () => {
|
||||
callCount++;
|
||||
};
|
||||
|
||||
component.testAddEventListener(emitter, 'once-event', handler, { once: true });
|
||||
|
||||
// Check listener count before emit
|
||||
const beforeCount = emitter.listenerCount('once-event');
|
||||
expect(beforeCount).toEqual(1);
|
||||
|
||||
// Emit once - the listener should fire and auto-remove
|
||||
emitter.emit('once-event');
|
||||
expect(callCount).toEqual(1);
|
||||
|
||||
// Check listener was auto-removed
|
||||
const afterCount = emitter.listenerCount('once-event');
|
||||
expect(afterCount).toEqual(0);
|
||||
|
||||
// Emit again - should not increase count
|
||||
emitter.emit('once-event');
|
||||
expect(callCount).toEqual(1);
|
||||
|
||||
await component.cleanup();
|
||||
});
|
||||
|
||||
tap.test('should not create timers when shutting down', async () => {
|
||||
const component = new TestComponent();
|
||||
|
||||
// Start cleanup
|
||||
const cleanupPromise = component.cleanup();
|
||||
|
||||
// Try to create timers during shutdown
|
||||
let timerFired = false;
|
||||
let intervalFired = false;
|
||||
|
||||
component.testSetTimeout(() => {
|
||||
timerFired = true;
|
||||
}, 10);
|
||||
|
||||
component.testSetInterval(() => {
|
||||
intervalFired = true;
|
||||
}, 10);
|
||||
|
||||
await cleanupPromise;
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
|
||||
expect(timerFired).toBeFalse();
|
||||
expect(intervalFired).toBeFalse();
|
||||
});
|
||||
|
||||
tap.start();
|
Reference in New Issue
Block a user