113 lines
3.6 KiB
TypeScript
113 lines
3.6 KiB
TypeScript
import { beforeEach, describe, expect, it, mock } from 'bun:test';
|
|
import { CacheFactory, createNamespacedCache } from '../src/cache-factory';
|
|
import { generateKey } from '../src/key-generator';
|
|
import type { ICache } from '../src/types';
|
|
|
|
describe('CacheFactory', () => {
|
|
it('should create null cache when no config provided', () => {
|
|
const cache = CacheFactory.create(null as any, 'test');
|
|
expect(cache).toBeDefined();
|
|
expect(cache.type).toBe('null');
|
|
});
|
|
|
|
it('should create cache with namespace', () => {
|
|
const mockConfig = {
|
|
cache: {
|
|
provider: 'memory',
|
|
redis: { host: 'localhost', port: 6379 },
|
|
},
|
|
};
|
|
const cache = CacheFactory.create(mockConfig as any, 'test-namespace');
|
|
expect(cache).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('NamespacedCache', () => {
|
|
let mockCache: ICache;
|
|
|
|
beforeEach(() => {
|
|
mockCache = {
|
|
type: 'mock',
|
|
get: mock(() => Promise.resolve(null)),
|
|
set: mock(() => Promise.resolve()),
|
|
del: mock(() => Promise.resolve()),
|
|
clear: mock(() => Promise.resolve()),
|
|
exists: mock(() => Promise.resolve(false)),
|
|
ttl: mock(() => Promise.resolve(-1)),
|
|
keys: mock(() => Promise.resolve([])),
|
|
mget: mock(() => Promise.resolve([])),
|
|
mset: mock(() => Promise.resolve()),
|
|
mdel: mock(() => Promise.resolve()),
|
|
size: mock(() => Promise.resolve(0)),
|
|
flush: mock(() => Promise.resolve()),
|
|
ping: mock(() => Promise.resolve(true)),
|
|
disconnect: mock(() => Promise.resolve()),
|
|
isConnected: mock(() => true),
|
|
};
|
|
});
|
|
|
|
it('should create namespaced cache', () => {
|
|
const nsCache = createNamespacedCache(mockCache, 'sub-namespace');
|
|
expect(nsCache).toBeDefined();
|
|
expect(nsCache).toHaveProperty('get');
|
|
expect(nsCache).toHaveProperty('set');
|
|
});
|
|
|
|
it('should prefix keys with namespace', async () => {
|
|
const nsCache = createNamespacedCache(mockCache, 'test');
|
|
await nsCache.set('key', 'value');
|
|
expect(mockCache.set).toHaveBeenCalledWith('test:key', 'value', undefined);
|
|
});
|
|
|
|
it('should handle null cache gracefully', async () => {
|
|
const nsCache = createNamespacedCache(null, 'test');
|
|
expect(nsCache).toBeDefined();
|
|
// Should return null for get operations
|
|
const value = await nsCache.get('key');
|
|
expect(value).toBeNull();
|
|
});
|
|
|
|
it('should prefix multiple operations', async () => {
|
|
const nsCache = createNamespacedCache(mockCache, 'prefix');
|
|
|
|
await nsCache.get('key1');
|
|
expect(mockCache.get).toHaveBeenCalledWith('prefix:key1');
|
|
|
|
await nsCache.del('key2');
|
|
expect(mockCache.del).toHaveBeenCalledWith('prefix:key2');
|
|
|
|
await nsCache.exists('key3');
|
|
expect(mockCache.exists).toHaveBeenCalledWith('prefix:key3');
|
|
});
|
|
|
|
it('should handle pattern operations', async () => {
|
|
const nsCache = createNamespacedCache(mockCache, 'ns');
|
|
mockCache.keys = mock(() => Promise.resolve(['ns:key1', 'ns:key2', 'other:key']));
|
|
|
|
const keys = await nsCache.keys('*');
|
|
expect(mockCache.keys).toHaveBeenCalledWith('ns:*');
|
|
expect(keys).toEqual(['key1', 'key2']);
|
|
});
|
|
});
|
|
|
|
describe('KeyGenerator', () => {
|
|
it('should generate key from parts', () => {
|
|
const key = generateKey('part1', 'part2', 'part3');
|
|
expect(key).toBe('part1:part2:part3');
|
|
});
|
|
|
|
it('should handle empty parts', () => {
|
|
const key = generateKey();
|
|
expect(key).toBe('');
|
|
});
|
|
|
|
it('should skip undefined parts', () => {
|
|
const key = generateKey('part1', undefined, 'part3');
|
|
expect(key).toBe('part1:part3');
|
|
});
|
|
|
|
it('should convert non-string parts', () => {
|
|
const key = generateKey('prefix', 123, true);
|
|
expect(key).toBe('prefix:123:true');
|
|
});
|
|
});
|