import { describe, expect, it, vi, } from 'vitest'; import { createSingleton } from './createSingleton'; describe('createSingleton', () => { it('does not call the factory until the first get (lazy)', () => { const factory = vi.fn(() => ({ id: 1 })); createSingleton(factory); expect(factory).not.toHaveBeenCalled(); }); it('constructs on first get and memoizes the instance', () => { const factory = vi.fn(() => ({ id: 1 })); const singleton = createSingleton(factory); const a = singleton.get(); const b = singleton.get(); expect(factory).toHaveBeenCalledTimes(1); expect(a).toBe(b); }); it('rebuilds a fresh instance after reset', () => { let count = 0; const singleton = createSingleton(() => ({ id: ++count })); const first = singleton.get(); singleton.reset(); const second = singleton.get(); expect(first).not.toBe(second); expect(second.id).toBe(2); }); it('runs teardown once, with the live instance, on reset', () => { const teardown = vi.fn(); const singleton = createSingleton(() => ({ id: 1 }), teardown); const instance = singleton.get(); singleton.reset(); expect(teardown).toHaveBeenCalledTimes(1); expect(teardown).toHaveBeenCalledWith(instance); }); it('treats reset before any get as a no-op (no teardown, no throw)', () => { const teardown = vi.fn(); const singleton = createSingleton(() => ({ id: 1 }), teardown); expect(() => singleton.reset()).not.toThrow(); expect(teardown).not.toHaveBeenCalled(); }); it('does not run teardown again on a second consecutive reset', () => { const teardown = vi.fn(); const singleton = createSingleton(() => ({ id: 1 }), teardown); singleton.get(); singleton.reset(); singleton.reset(); expect(teardown).toHaveBeenCalledTimes(1); }); it('works without a teardown', () => { const singleton = createSingleton(() => ({ id: 1 })); singleton.get(); expect(() => singleton.reset()).not.toThrow(); expect(singleton.get().id).toBe(1); }); it('caches a falsy instance value without re-running the factory', () => { const factory = vi.fn(() => undefined); const singleton = createSingleton(factory); singleton.get(); singleton.get(); expect(factory).toHaveBeenCalledTimes(1); }); });