@daiso-tech/core
Version:
The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.
1,078 lines (1,077 loc) • 99 kB
JavaScript
/**
* @module Cache
*/
import { vi, } from "vitest";
import { KeyNotFoundCacheError, CACHE_EVENTS, KeyExistsCacheError, } from "../../../cache/contracts/_module.js";
import {} from "../../../event-bus/contracts/_module.js";
import {} from "../../../namespace/contracts/_module.js";
import {} from "../../../time-span/contracts/time-span.contract.js";
import { TimeSpan } from "../../../time-span/implementations/_module.js";
import { delay } from "../../../utilities/_module.js";
/**
* The `cacheTestSuite` function simplifies the process of testing your custom implementation of {@link ICache | `ICache`} with `vitest`.
*
* IMPORT_PATH: `"@daiso-tech/core/cache/test-utilities"`
* @group TestUtilities
* @example
* ```ts
* import { beforeEach, describe, expect, test } from "vitest";
* import { cacheTestSuite } from "@daiso-tech/core/cache/test-utilities";
* import { MemoryCacheAdapter } from "@daiso-tech/core/cache/memory-cache-adapter";
* import { Cache } from "@daiso-tech/core/cache";
*
* describe("class: Cache", () => {
* cacheTestSuite({
* createCache: () => {
* return new Cache({
* adapter: new MemoryCacheAdapter(),
* });
* },
* test,
* beforeEach,
* expect,
* describe,
* });
* });
* ```
*/
export function cacheTestSuite(settings) {
const { expect, test, createCache, describe, beforeEach: beforeEach_, excludeEventTests = false, delayBuffer = TimeSpan.fromMilliseconds(10), eventDispatchWaitTime = TimeSpan.fromMilliseconds(10), } = settings;
let cache;
beforeEach_(async () => {
cache = (await createCache());
});
const waitForSettings = {
interval: TimeSpan.fromTimeSpan(eventDispatchWaitTime).toMilliseconds(),
timeout: TimeSpan.fromTimeSpan(eventDispatchWaitTime)
.multiply(3)
.toMilliseconds(),
};
async function delayWithBuffer(ttl) {
await delay(TimeSpan.fromTimeSpan(ttl).addTimeSpan(delayBuffer));
}
const TTL = TimeSpan.fromMilliseconds(50);
const LONG_TTL = TimeSpan.fromMinutes(5);
describe("ICache tests:", () => {
describe("Api tests:", () => {
describe("method: exists", () => {
test("Should return false when key does not exists", async () => {
const key = "a";
const result = await cache.exists(key);
expect(result).toBe(false);
});
test("Should return false when key is expired", async () => {
const key = "a";
await cache.add(key, 1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const result = await cache.exists(key);
expect(result).toBe(false);
});
test("Should return true when key exists", async () => {
const key = "a";
await cache.add(key, 1);
const result = await cache.exists(key);
expect(result).toBe(true);
});
test("Should return true when key is unexpired", async () => {
const key = "a";
await cache.add(key, 1, { ttl: LONG_TTL });
const result = await cache.exists(key);
expect(result).toBe(true);
});
});
describe("method: missing", () => {
test("Should return true when key does not exists", async () => {
const key = "a";
const result = await cache.missing(key);
expect(result).toBe(true);
});
test("Should return true when key is expired", async () => {
const key = "a";
await cache.add(key, 1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const result = await cache.missing(key);
expect(result).toBe(true);
});
test("Should return false when key exists", async () => {
const key = "a";
await cache.add(key, 1);
const result = await cache.missing(key);
expect(result).toBe(false);
});
test("Should return false when key is unexpired", async () => {
const key = "a";
await cache.add(key, 1, { ttl: LONG_TTL });
const result = await cache.missing(key);
expect(result).toBe(false);
});
});
describe("method: get", () => {
test("Should return null when key does not exists", async () => {
const key = "a";
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return null when key is expired", async () => {
const key = "a";
await cache.add(key, 1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return value when key exists", async () => {
const key = "a";
const value = 1;
await cache.add(key, value);
const result = await cache.get(key);
expect(result).toBe(value);
});
test("Should return value when key is unexpired", async () => {
const key = "a";
const value = 1;
await cache.add(key, value, { ttl: LONG_TTL });
const result = await cache.get(key);
expect(result).toBe(value);
});
});
describe("method: getOrFail", () => {
test("Should throw KeyNotFoundCacheError when key does not exists", async () => {
const key = "a";
const result = cache.getOrFail(key);
await expect(result).rejects.toBeInstanceOf(KeyNotFoundCacheError);
});
test("Should throw KeyNotFoundCacheError when key is expired", async () => {
const key = "a";
await cache.add(key, 1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const result = cache.getOrFail(key);
await expect(result).rejects.toBeInstanceOf(KeyNotFoundCacheError);
});
test("Should return value when key exists", async () => {
const key = "a";
const value = 1;
await cache.add(key, value);
const result = await cache.getOrFail(key);
expect(result).toBe(value);
});
test("Should return value when key is unexpired", async () => {
const key = "a";
const value = 1;
await cache.add(key, value, { ttl: LONG_TTL });
const result = await cache.getOrFail(key);
expect(result).toBe(value);
});
});
describe("method: getOr", () => {
test("Should return default value when key does not exists", async () => {
const key = "a";
const defaultValue = -1;
const result = await cache.getOr(key, defaultValue);
expect(result).toBe(defaultValue);
});
test("Should return default value when key is expired", async () => {
const key = "a";
await cache.add(key, 1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const defaultValue = -1;
const result = await cache.getOr(key, defaultValue);
expect(result).toBe(defaultValue);
});
test("Should return value when key exists", async () => {
const key = "a";
const value = 1;
await cache.add(key, value);
const defaultValue = -1;
const result = await cache.getOr(key, defaultValue);
expect(result).toBe(value);
});
test("Should return value when key is unexpired", async () => {
const key = "a";
const value = 1;
await cache.add(key, value, { ttl: LONG_TTL });
const defaultValue = -1;
const result = await cache.getOr(key, defaultValue);
expect(result).toBe(value);
});
});
describe("method: getAndRemove", () => {
test("Should return null when key does not exists", async () => {
const key = "a";
const result = await cache.getAndRemove(key);
expect(result).toBeNull();
});
test("Should return null when key is expired", async () => {
const key = "a";
await cache.add(key, 1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const result = await cache.getAndRemove(key);
expect(result).toBeNull();
});
test("Should return value when key exists", async () => {
const key = "a";
const value = 1;
await cache.add(key, value);
const result = await cache.getAndRemove(key);
expect(result).toBe(value);
});
test("Should return value when key is unexpired", async () => {
const key = "a";
const value = 1;
await cache.add(key, value, { ttl: LONG_TTL });
const result = await cache.getAndRemove(key);
expect(result).toBe(value);
});
test("Should remove key when exists", async () => {
const key = "a";
const value = 1;
await cache.add(key, value);
await cache.getAndRemove(key);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should remove key when is unexpired", async () => {
const key = "a";
const value = 1;
await cache.add(key, value, { ttl: LONG_TTL });
await cache.getAndRemove(key);
const result = await cache.get(key);
expect(result).toBeNull();
});
});
describe("method: getOrAdd", () => {
test("Should return value to add when key does not exists", async () => {
const key = "a";
const valueToAdd = -1;
const result = await cache.getOrAdd(key, valueToAdd);
expect(result).toBe(valueToAdd);
});
test("Should persist value when key does not exists", async () => {
const key = "a";
const valueToAdd = -1;
await cache.getOrAdd(key, valueToAdd);
const result = await cache.get(key);
expect(result).toBe(valueToAdd);
});
test("Should return value to add when key is expired", async () => {
const key = "a";
await cache.add(key, 1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const valueToAdd = -1;
const result = await cache.getOrAdd(key, valueToAdd);
expect(result).toBe(valueToAdd);
});
test("Should persist value when key is expired", async () => {
const key = "a";
await cache.add(key, 1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const valueToAdd = -1;
await cache.getOrAdd(key, valueToAdd);
const result = await cache.get(key);
expect(result).toBe(valueToAdd);
});
test("Should return value when key exists", async () => {
const key = "a";
const value = 1;
await cache.add(key, value);
const valueToAdd = -1;
const result = await cache.getOrAdd(key, valueToAdd);
expect(result).toBe(value);
});
test("Should not persist value when key exists", async () => {
const key = "a";
const value = 1;
await cache.add(key, value);
const valueToAdd = -1;
await cache.getOrAdd(key, valueToAdd);
const result = await cache.get(key);
expect(result).toBe(value);
});
test("Should return value when key is unexpired", async () => {
const key = "a";
const value = 1;
await cache.add(key, value, { ttl: LONG_TTL });
const valueToAdd = -1;
const result = await cache.getOrAdd(key, valueToAdd);
expect(result).toBe(value);
});
test("Should not persist when key is unexpired", async () => {
const key = "a";
const value = 1;
await cache.add(key, value, { ttl: LONG_TTL });
const valueToAdd = -1;
await cache.getOrAdd(key, valueToAdd);
const result = await cache.get(key);
expect(result).toBe(value);
});
});
describe("method: add", () => {
test("Should return true when key does not exists", async () => {
const key = "a";
const value = 1;
const result = await cache.add(key, value);
expect(result).toBe(true);
});
test("Should persist value when key does not exists", async () => {
const key = "a";
const value = 1;
await cache.add(key, value);
const result = await cache.get(key);
expect(result).toBe(value);
});
test("Should return true when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
const result = await cache.add(key, value2);
expect(result).toBe(true);
});
test("Should persist value when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
await cache.add(key, value2);
const result = await cache.get(key);
expect(result).toBe(value2);
});
test("Should return false when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
const result = await cache.add(key, value2);
expect(result).toBe(false);
});
test("Should return false when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
const result = await cache.add(key, value2);
expect(result).toBe(false);
});
test("Should not persist value when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
await cache.add(key, value2);
const result = await cache.get(key);
expect(result).toBe(value1);
});
test("Should not persist value when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
await cache.add(key, value2);
const result = await cache.get(key);
expect(result).toBe(value1);
});
});
describe("method: addOrFail", () => {
test("Should not throw error when key does not exists", async () => {
const key = "a";
const value = 1;
const result = cache.addOrFail(key, value);
await expect(result).resolves.toBeUndefined();
});
test("Should persist value when key does not exists", async () => {
const key = "a";
const value = 1;
await cache.addOrFail(key, value);
const result = await cache.get(key);
expect(result).toBe(value);
});
test("Should not throw error when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.addOrFail(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
const result = cache.addOrFail(key, value2);
await expect(result).resolves.toBeUndefined();
});
test("Should persist value when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.addOrFail(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
await cache.addOrFail(key, value2);
const result = await cache.get(key);
expect(result).toBe(value2);
});
test("Should throw KeyExistsCacheError when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.addOrFail(key, value1);
const value2 = 2;
const result = cache.addOrFail(key, value2);
await expect(result).rejects.toBeInstanceOf(KeyExistsCacheError);
});
test("Should throw KeyExistsCacheError when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.addOrFail(key, value1, {
ttl: LONG_TTL,
});
const value2 = 2;
const result = cache.addOrFail(key, value2);
await expect(result).rejects.toBeInstanceOf(KeyExistsCacheError);
});
test("Should not persist value when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.addOrFail(key, value1);
const value2 = 2;
try {
await cache.addOrFail(key, value2);
}
catch (error) {
if (!(error instanceof KeyExistsCacheError)) {
throw error;
}
}
const result = await cache.get(key);
expect(result).toBe(value1);
});
test("Should not persist value when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.addOrFail(key, value1, {
ttl: LONG_TTL,
});
const value2 = 2;
try {
await cache.addOrFail(key, value2);
}
catch (error) {
if (!(error instanceof KeyExistsCacheError)) {
throw error;
}
}
const result = await cache.get(key);
expect(result).toBe(value1);
});
});
describe("method: put", () => {
test("Should return true when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
const result = await cache.put(key, value2);
expect(result).toBe(true);
});
test("Should persist value when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
await cache.put(key, value2);
const result = await cache.get(key);
expect(result).toBe(value2);
});
test("Should persist ttl when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
await cache.put(key, value2, { ttl: TTL });
await delayWithBuffer(TTL);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return true when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
const result = await cache.put(key, value2);
expect(result).toBe(true);
});
test("Should persist value when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
await cache.put(key, value2);
const result = await cache.get(key);
expect(result).toBe(value2);
});
test("Should persist ttl when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
await cache.put(key, value2, { ttl: TTL });
await delayWithBuffer(TTL);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return false when key does not exist", async () => {
const key = "a";
const value = 1;
const result = await cache.put(key, value);
expect(result).toBe(false);
});
test("Should persist value when key does not exist", async () => {
const key = "a";
const value = 2;
await cache.put(key, value);
const result = await cache.get(key);
expect(result).toBe(value);
});
test("Should persist ttl when key does not exist", async () => {
const key = "a";
const value = 2;
await cache.put(key, value, { ttl: TTL });
await delayWithBuffer(TTL);
const result = await cache.get(key);
expect(result).toBeNull();
});
});
describe("method: update", () => {
test("Should return false when key does not exists", async () => {
const key = "a";
const value = 1;
const result = await cache.update(key, value);
expect(result).toBe(false);
});
test("Should not persist value when key does not exists", async () => {
const key = "a";
const value = 1;
await cache.update(key, value);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return false when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
const result = await cache.update(key, value2);
expect(result).toBe(false);
});
test("Should not persist value when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
await cache.update(key, value2);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return true when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
const result = await cache.update(key, value2);
expect(result).toBe(true);
});
test("Should return true when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
const result = await cache.update(key, value2);
expect(result).toBe(true);
});
test("Should persist value when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
await cache.update(key, value2);
const result = await cache.get(key);
expect(result).toBe(value2);
});
test("Should persist value when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
await cache.update(key, value2);
const result = await cache.get(key);
expect(result).toBe(value2);
});
});
describe("method: updateOrFail", () => {
test("Should throw KeyNotFoundCacheError when key does not exists", async () => {
const key = "a";
const value = 1;
const result = cache.updateOrFail(key, value);
await expect(result).rejects.toBeInstanceOf(KeyNotFoundCacheError);
});
test("Should not persist value when key does not exists", async () => {
const key = "a";
const value = 1;
try {
await cache.updateOrFail(key, value);
}
catch (error) {
if (!(error instanceof KeyNotFoundCacheError)) {
throw error;
}
}
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should throw KeyNotFoundCacheError when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
const result = cache.updateOrFail(key, value2);
await expect(result).rejects.toBeInstanceOf(KeyNotFoundCacheError);
});
test("Should not persist value when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
try {
await cache.updateOrFail(key, value2);
}
catch (error) {
if (!(error instanceof KeyNotFoundCacheError)) {
throw error;
}
}
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should not throw error when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
const result = cache.updateOrFail(key, value2);
await expect(result).resolves.toBeUndefined();
});
test("Should not throw error when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
const result = cache.updateOrFail(key, value2);
await expect(result).resolves.toBeUndefined();
});
test("Should persist value when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
await cache.updateOrFail(key, value2);
const result = await cache.get(key);
expect(result).toBe(value2);
});
test("Should persist value when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
await cache.updateOrFail(key, value2);
const result = await cache.get(key);
expect(result).toBe(value2);
});
});
describe("method: increment", () => {
test("Should return false when key does not exists", async () => {
const key = "a";
const value = 1;
const result = await cache.increment(key, value);
expect(result).toBe(false);
});
test("Should not persist value when key does not exists", async () => {
const key = "a";
const value = 1;
await cache.increment(key, value);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return false when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
const result = await cache.increment(key, value2);
expect(result).toBe(false);
});
test("Should not persist value when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
await cache.increment(key, value2);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return true when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
const result = await cache.increment(key, value2);
expect(result).toBe(true);
});
test("Should return true when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
const result = await cache.increment(key, value2);
expect(result).toBe(true);
});
test("Should persist value when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
await cache.increment(key, value2);
const result = await cache.get(key);
expect(result).toBe(3);
});
test("Should persist value when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
await cache.increment(key, value2);
const result = await cache.get(key);
expect(result).toBe(3);
});
});
describe("method: incrementOrFail", () => {
test("Should throw KeyNotFoundCacheError when key does not exists", async () => {
const key = "a";
const value = 1;
const result = cache.incrementOrFail(key, value);
await expect(result).rejects.toBeInstanceOf(KeyNotFoundCacheError);
});
test("Should not persist value when key does not exists", async () => {
const key = "a";
const value = 1;
try {
await cache.incrementOrFail(key, value);
}
catch (error) {
if (!(error instanceof KeyNotFoundCacheError)) {
throw error;
}
}
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should throw KeyNotFoundCacheError when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
const result = cache.incrementOrFail(key, value2);
await expect(result).rejects.toBeInstanceOf(KeyNotFoundCacheError);
});
test("Should not persist value when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
try {
await cache.incrementOrFail(key, value2);
}
catch (error) {
if (!(error instanceof KeyNotFoundCacheError)) {
throw error;
}
}
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should not throw error when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
const result = cache.incrementOrFail(key, value2);
await expect(result).resolves.toBeUndefined();
});
test("Should not throw error when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
const result = cache.incrementOrFail(key, value2);
await expect(result).resolves.toBeUndefined();
});
test("Should persist value when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
await cache.incrementOrFail(key, value2);
const result = await cache.get(key);
expect(result).toBe(3);
});
test("Should persist value when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
await cache.incrementOrFail(key, value2);
const result = await cache.get(key);
expect(result).toBe(3);
});
});
describe("method: decrement", () => {
test("Should return false when key does not exists", async () => {
const key = "a";
const value = 1;
const result = await cache.decrement(key, value);
expect(result).toBe(false);
});
test("Should not persist value when key does not exists", async () => {
const key = "a";
const value = 1;
await cache.decrement(key, value);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return false when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
const result = await cache.decrement(key, value2);
expect(result).toBe(false);
});
test("Should not persist value when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
await cache.decrement(key, value2);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should return true when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
const result = await cache.decrement(key, value2);
expect(result).toBe(true);
});
test("Should return true when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
const result = await cache.decrement(key, value2);
expect(result).toBe(true);
});
test("Should persist value when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
await cache.decrement(key, value2);
const result = await cache.get(key);
expect(result).toBe(-1);
});
test("Should persist value when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
await cache.decrement(key, value2);
const result = await cache.get(key);
expect(result).toBe(-1);
});
});
describe("method: decrementOrFail", () => {
test("Should throw KeyNotFoundCacheError when key does not exists", async () => {
const key = "a";
const value = 1;
const result = cache.decrementOrFail(key, value);
await expect(result).rejects.toBeInstanceOf(KeyNotFoundCacheError);
});
test("Should not persist value when key does not exists", async () => {
const key = "a";
const value = 1;
try {
await cache.decrementOrFail(key, value);
}
catch (error) {
if (!(error instanceof KeyNotFoundCacheError)) {
throw error;
}
}
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should throw KeyNotFoundCacheError when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
const result = cache.decrementOrFail(key, value2);
await expect(result).rejects.toBeInstanceOf(KeyNotFoundCacheError);
});
test("Should not persist value when key is expired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const value2 = 2;
try {
await cache.decrementOrFail(key, value2);
}
catch (error) {
if (!(error instanceof KeyNotFoundCacheError)) {
throw error;
}
}
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should not throw error when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
const result = cache.decrementOrFail(key, value2);
await expect(result).resolves.toBeUndefined();
});
test("Should not throw error when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
const result = cache.decrementOrFail(key, value2);
await expect(result).resolves.toBeUndefined();
});
test("Should persist value when key exists", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1);
const value2 = 2;
await cache.decrementOrFail(key, value2);
const result = await cache.get(key);
expect(result).toBe(-1);
});
test("Should persist value when key is unexpired", async () => {
const key = "a";
const value1 = 1;
await cache.add(key, value1, { ttl: LONG_TTL });
const value2 = 2;
await cache.decrementOrFail(key, value2);
const result = await cache.get(key);
expect(result).toBe(-1);
});
});
describe("method: remove", () => {
test("Should return false when key does not exists", async () => {
const key = "a";
const result = await cache.remove(key);
expect(result).toBe(false);
});
test("Should return false when key is expired", async () => {
const key = "a";
await cache.add(key, 1, {
ttl: TTL,
});
await delayWithBuffer(TTL);
const result = await cache.remove(key);
expect(result).toBe(false);
});
test("Should return true when key exists", async () => {
const key = "a";
await cache.add(key, 1);
const result = await cache.remove(key);
expect(result).toBe(true);
});
test("Should return true when key is unexpired", async () => {
const key = "a";
await cache.add(key, 1, { ttl: LONG_TTL });
const result = await cache.remove(key);
expect(result).toBe(true);
});
test("Should persist removal when key exists", async () => {
const key = "a";
await cache.add(key, 1);
await cache.remove(key);
const result = await cache.get(key);
expect(result).toBeNull();
});
test("Should persist removal when key is unexpired", async () => {
const key = "a";
await cache.add(key, 1, { ttl: LONG_TTL });
await cache.remove(key);
const result = await cache.get(key);
expect(result).toBeNull();
});
});