@rt_lite/api
Version:
An unoficial rotten tomatoes REST api
144 lines (103 loc) • 3.43 kB
text/typescript
import { Cache } from '~/models/cache.model';
import faker from '@faker-js/faker';
jest.useFakeTimers();
type RandomRecord = Readonly<{
key: string;
value: Readonly<unknown>;
}>;
describe('cache.class', () => {
/* eslint-disable @typescript-eslint/init-declarations */
let cache: Cache<unknown>;
/* eslint-enable @typescript-eslint/init-declarations */
afterEach(() => {
cache.clear();
});
describe('Default constructor options', () => {
beforeEach(() => {
cache = new Cache();
});
test('Setting and getting a record', () => {
const key = faker.lorem.word();
const record = JSON.parse(faker.datatype.json()) as Readonly<unknown>;
cache.set(key, record);
const stored = cache.get(key);
expect(stored).toStrictEqual(record);
});
test('Deleting a record', () => {
const key = faker.lorem.word();
const record = JSON.parse(faker.datatype.json()) as Readonly<unknown>;
cache.set(key, record);
cache.delete(key);
const stored = cache.get(key);
expect(stored).toBeNull();
});
test('Clearing the cache', () => {
const numRecords = 10;
const keyValuePairs = new Array(numRecords)
.fill(null)
.map((): [string, Readonly<unknown>] => [
faker.lorem.word(),
JSON.parse(faker.datatype.json()) as Readonly<unknown>
]);
keyValuePairs
.forEach(([key, value]: readonly [string, Readonly<unknown>]) => cache.set(key, value));
cache.clear();
keyValuePairs
.map(([key]: readonly [string, Readonly<unknown>]) => key)
.forEach(key => {
const stored = cache.get(key);
expect(stored).toBeNull();
});
});
});
describe('Custom maxSize parameter', () => {
const maxSize = 10;
beforeEach(() => {
cache = new Cache({ maxSize });
});
test('maxSize respected, with LRU default', () => {
// Create maxSize + 1 records
const records: RandomRecord[] = new Array(maxSize + 1)
.fill(null)
.map((unused, index) => ({
key: `${index}`,
value: JSON.parse(faker.datatype.json()) as Readonly<unknown>
}));
const [firstRecord] = records;
const { [records.length - 1]: lastRecord } = records;
const allButLastRecord = records.slice(0, records.length - 1);
// Insert all but the last into the cache
allButLastRecord.forEach(({ key, value }) => {
cache.set(key, value);
});
// Verify that all but the last are in the cache
allButLastRecord.forEach(({ key, value }) => {
expect(cache.get(key)).toStrictEqual(value);
});
// Verify that the last is not in the cache
expect(cache.get(lastRecord.key)).toBeNull();
// Insert the last
cache.set(lastRecord.key, lastRecord.value);
// Verify that the first is no longer in the cache (LRU default)
expect(cache.get(firstRecord.key)).toStrictEqual(null);
// Verify that the last is in the cache
expect(cache.get(lastRecord.key)).toStrictEqual(lastRecord.value);
});
});
describe('Custom ttl parameter', () => {
const ttl = 5;
beforeEach(() => {
cache = new Cache<RandomRecord>({ ttl });
});
test('ttl respected', () => {
const key = faker.lorem.word();
const record = JSON.parse(faker.datatype.json()) as RandomRecord;
cache.set(key, record);
let storedRecord = cache.get(key);
expect(storedRecord).toStrictEqual(record);
jest.advanceTimersByTime(ttl + 1);
storedRecord = cache.get(key);
expect(storedRecord).toBeNull();
});
});
});