import { ObjectPool } from '@common/ObjectPool'; interface Bullet { x: number; alive: boolean; } const makeBullet = (): Bullet => ({ x: 0, alive: false }); const resetBullet = (b: Bullet): void => { b.x = 0; b.alive = false; }; describe('ObjectPool', () => { it('creates new instances when the free list is empty', () => { const pool = new ObjectPool({ factory: makeBullet }); const a = pool.acquire(); const b = pool.acquire(); expect(a).not.toBe(b); expect(pool.stats().created).toBe(2); expect(pool.borrowedCount).toBe(2); expect(pool.freeCount).toBe(0); }); it('reuses instances after release', () => { const pool = new ObjectPool({ factory: makeBullet, resetter: resetBullet }); const a = pool.acquire(); a.x = 100; a.alive = true; pool.release(a); expect(a.x).toBe(0); expect(a.alive).toBe(false); const b = pool.acquire(); expect(b).toBe(a); expect(pool.stats().recycled).toBe(1); }); it('pre-allocates instances when preAlloc is set', () => { const pool = new ObjectPool({ factory: makeBullet, preAlloc: 5 }); expect(pool.freeCount).toBe(5); expect(pool.stats().created).toBe(5); }); it('discards excess releases when over maxSize', () => { const pool = new ObjectPool({ factory: makeBullet, maxSize: 2 }); const a = pool.acquire(); const b = pool.acquire(); const c = pool.acquire(); pool.release(a); pool.release(b); pool.release(c); // should be dropped expect(pool.freeCount).toBe(2); }); it('fires onDoubleRelease and ignores double-release', () => { const spy = jest.fn(); const pool = new ObjectPool({ factory: makeBullet, onDoubleRelease: spy, }); const a = pool.acquire(); pool.release(a); pool.release(a); expect(spy).toHaveBeenCalledTimes(1); expect(pool.freeCount).toBe(1); }); it('drain() clears both free and borrowed', () => { const pool = new ObjectPool({ factory: makeBullet, preAlloc: 3 }); pool.acquire(); pool.drain(); expect(pool.freeCount).toBe(0); expect(pool.borrowedCount).toBe(0); }); it('stats track acquired / recycled totals', () => { const pool = new ObjectPool({ factory: makeBullet }); const a = pool.acquire(); const b = pool.acquire(); pool.release(a); pool.release(b); pool.acquire(); const s = pool.stats(); expect(s.acquired).toBe(3); expect(s.recycled).toBe(2); expect(s.created).toBe(2); }); });