-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathcache-service.test.ts
More file actions
111 lines (97 loc) · 3.41 KB
/
Copy pathcache-service.test.ts
File metadata and controls
111 lines (97 loc) · 3.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { describe, it, expect } from 'vitest';
import type { ICacheService, CacheStats } from './cache-service';
describe('Cache Service Contract', () => {
it('should allow a minimal ICacheService implementation', () => {
const cache: ICacheService = {
get: async <T>(_key: string) => undefined as T | undefined,
set: async (_key, _value, _ttl?) => {},
delete: async (_key) => false,
has: async (_key) => false,
clear: async () => {},
stats: async () => ({ hits: 0, misses: 0, keyCount: 0 }),
};
expect(typeof cache.get).toBe('function');
expect(typeof cache.set).toBe('function');
expect(typeof cache.delete).toBe('function');
expect(typeof cache.has).toBe('function');
expect(typeof cache.clear).toBe('function');
expect(typeof cache.stats).toBe('function');
});
it('should perform basic cache operations', async () => {
const store = new Map<string, { value: unknown; ttl?: number }>();
const cache: ICacheService = {
get: async <T>(key: string) => {
const entry = store.get(key);
return entry ? entry.value as T : undefined;
},
set: async (key, value, ttl?) => {
store.set(key, { value, ttl });
},
delete: async (key) => store.delete(key),
has: async (key) => store.has(key),
clear: async () => { store.clear(); },
stats: async () => ({
hits: 0,
misses: 0,
keyCount: store.size,
}),
};
await cache.set('user:1', { name: 'Alice' }, 60);
expect(await cache.has('user:1')).toBe(true);
expect(await cache.get('user:1')).toEqual({ name: 'Alice' });
await cache.delete('user:1');
expect(await cache.has('user:1')).toBe(false);
expect(await cache.get('user:1')).toBeUndefined();
});
it('should return cache stats', async () => {
let hits = 0;
let misses = 0;
const store = new Map<string, unknown>();
const cache: ICacheService = {
get: async <T>(key: string) => {
if (store.has(key)) {
hits++;
return store.get(key) as T;
}
misses++;
return undefined;
},
set: async (key, value) => { store.set(key, value); },
delete: async (key) => store.delete(key),
has: async (key) => store.has(key),
clear: async () => { store.clear(); },
stats: async (): Promise<CacheStats> => ({
hits,
misses,
keyCount: store.size,
memoryUsage: 1024,
}),
};
await cache.set('a', 1);
await cache.get('a');
await cache.get('b');
const s = await cache.stats();
expect(s.hits).toBe(1);
expect(s.misses).toBe(1);
expect(s.keyCount).toBe(1);
expect(s.memoryUsage).toBe(1024);
});
it('should clear all entries', async () => {
const store = new Map<string, unknown>();
const cache: ICacheService = {
get: async <T>(key: string) => store.get(key) as T | undefined,
set: async (key, value) => { store.set(key, value); },
delete: async (key) => store.delete(key),
has: async (key) => store.has(key),
clear: async () => { store.clear(); },
stats: async () => ({ hits: 0, misses: 0, keyCount: store.size }),
};
await cache.set('x', 1);
await cache.set('y', 2);
await cache.clear();
expect(await cache.has('x')).toBe(false);
expect(await cache.has('y')).toBe(false);
const s = await cache.stats();
expect(s.keyCount).toBe(0);
});
});