Files
frontend-svelte/src/shared/lib/helpers/createSingleton/createSingleton.test.ts
T

87 lines
2.5 KiB
TypeScript
Raw Normal View History

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<undefined>(factory);
singleton.get();
singleton.get();
expect(factory).toHaveBeenCalledTimes(1);
});
});