import { TtlCache } from '../ttl-cache'; describe(`${TtlCache.name}`, () => { const key = 'foo'; const value = 'bar'; let cache: TtlCache; beforeEach(() => { jest.useFakeTimers(); cache = new TtlCache(); }); test('cache rejects invalid default ttl', () => { expect(() => new TtlCache({ ttlMs: -1 })).toThrow(); }); describe('when cache omits key', () => { test('has returns false', () => { expect(cache.has(key)).toBe(false); }); test('get returns undefined', () => { expect(cache.get(key)).toBeUndefined(); }); }); describe('when cache contains key', () => { const elements = { [key]: value, [`other-${key}`]: `other-${value}`, }; beforeEach(() => { Object.entries(elements).map(([key, value]) => cache.set(key, value)); }); test('has returns true', () => { expect(cache.has(key)).toBe(true); }); test('get returns value', () => { expect(cache.get(key)).toBe(value); }); test('set replaces value', () => { const newValue = `new-${value}`; cache.set(key, newValue); expect(cache.get(key)).toBe(newValue); }); test('delete removes key', () => { cache.delete(key); expect(cache.has(key)).toBe(false); }); test('clear removes all keys', () => { cache.clear(); Object.keys(elements).forEach(key => expect(cache.has(key)).toBe(false)); }); test('removes keys after five minutes', () => { jest.advanceTimersByTime(1000 * 60 * 5 - 1); Object.keys(elements).forEach(key => expect(cache.has(key)).toBe(true)); jest.advanceTimersByTime(1); Object.keys(elements).forEach(key => expect(cache.has(key)).toBe(false)); }); describe('when key has custom ttl', () => { const ttl = 1000 * 60 * 10; beforeEach(() => cache.set(key, value, ttl)); test('removes key after custom ttl', () => { jest.advanceTimersByTime(ttl - 1); expect(cache.has(key)).toBe(true); jest.advanceTimersByTime(1); expect(cache.has(key)).toBe(false); }); }); describe('when key has negative ttl', () => { beforeEach(() => cache.set(key, value, -1)); test('never removes key', () => { jest.runOnlyPendingTimers(); expect(cache.has(key)).toBe(true); }); }); }); });