Skip to content

Commit 2b1fe68

Browse files
committed
feat: add more tests to improve coverage
1 parent 9e66f91 commit 2b1fe68

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

rpc/test/decorators/logged.targetLogger.spec.ts

Whitespace-only changes.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*!
2+
* RedisCache additional coverage: purge() and set() with Promise
3+
*/
4+
import { expect } from 'chai';
5+
import { RedisCache } from '../..';
6+
7+
class FakeRedis {
8+
// minimal in-memory store
9+
private store = new Map<string, string>();
10+
public status: string = 'ready';
11+
public connected: boolean = true;
12+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
13+
public on(event: string, listener: (...args: any[]) => void): any { return this }
14+
public once?: any;
15+
public emit?: any;
16+
public removeAllListeners(): void {}
17+
public disconnect(_reconnect: boolean): void {}
18+
public quit(): void {}
19+
public end?(): void {}
20+
21+
public async set(key: string, val: string, ..._args: any[]): Promise<any> {
22+
this.store.set(key, val);
23+
return true;
24+
}
25+
public async get(key: string, ..._args: any[]): Promise<any> {
26+
return this.store.get(key) as any;
27+
}
28+
public async del(key: string): Promise<number> {
29+
const existed = this.store.delete(key);
30+
return existed ? 1 : 0;
31+
}
32+
public async eval(script: string, _numkeys: number, ..._args: any[]): Promise<any> {
33+
// Extract mask from: redis.call('keys','<MASK>')
34+
const m = script.match(/redis\.call\('keys','([^']*)'\)/);
35+
const mask = m ? m[1] : '';
36+
if (mask.endsWith('*')) {
37+
const prefix = mask.slice(0, -1);
38+
for (const key of Array.from(this.store.keys())) {
39+
if (key.startsWith(prefix)) {
40+
this.store.delete(key);
41+
}
42+
}
43+
} else if (mask) {
44+
this.store.delete(mask);
45+
}
46+
return true;
47+
}
48+
}
49+
50+
class ErrorEvalRedis extends FakeRedis {
51+
public async eval(): Promise<any> {
52+
throw new Error('eval failed');
53+
}
54+
}
55+
56+
describe('cache/RedisCache purge() and set() with Promise', () => {
57+
afterEach(async () => {
58+
await RedisCache.destroy();
59+
});
60+
61+
it('purge() should delete keys by wildcard and return true', async () => {
62+
const conn = new FakeRedis();
63+
const cache = new RedisCache();
64+
await cache.init({ conn: conn as any, prefix: 'cov-cache', logger: console as any });
65+
66+
// prepare some keys
67+
await cache.set('keep', 'x'); // fully qualified: cov-cache:RedisCache:keep
68+
await cache.set('del1', 1);
69+
await cache.set('del2', 2);
70+
71+
// unrelated key stored directly in connection should not be removed
72+
await conn.set('other:namespace:key', 'y');
73+
74+
const mask = `${cache.options.prefix}:${cache.name}:del*`;
75+
const ok = await cache.purge(mask);
76+
expect(ok).to.equal(true);
77+
78+
// del* gone, keep remains, and unrelated stays
79+
expect(await cache.get('del1')).to.equal(undefined);
80+
expect(await cache.get('del2')).to.equal(undefined);
81+
expect(await cache.get('keep')).to.equal('x');
82+
// Sanity: unrelated
83+
expect(await (conn as any).get('other:namespace:key')).to.equal('y');
84+
});
85+
86+
it('purge() should return false and log when eval throws', async () => {
87+
const conn = new ErrorEvalRedis();
88+
const cache = new RedisCache();
89+
const logs: any[] = [];
90+
const logger = { info: () => {}, error: (e: any) => logs.push(e) } as any;
91+
await cache.init({ conn: conn as any, prefix: 'cov-cache', logger });
92+
const res = await cache.purge('cov-cache:RedisCache:*');
93+
expect(res).to.equal(false);
94+
expect(logs.length).to.be.greaterThan(0);
95+
});
96+
97+
it('set() should accept Promise value and store resolved value', async () => {
98+
const conn = new FakeRedis();
99+
const cache = new RedisCache();
100+
await cache.init({ conn: conn as any, prefix: 'cov-cache', logger: console as any });
101+
102+
const key = 'promised';
103+
const valuePromise = new Promise<number>((resolve) => setTimeout(() => resolve(42), 1));
104+
await cache.set(key, valuePromise);
105+
expect(await cache.get(key)).to.equal(42);
106+
});
107+
108+
it('del() should return boolean false when key did not exist', async () => {
109+
const conn = new FakeRedis();
110+
const cache = new RedisCache();
111+
await cache.init({ conn: conn as any, prefix: 'cov-cache', logger: console as any });
112+
113+
const res = await cache.del('missing');
114+
expect(res).to.equal(false);
115+
});
116+
});

0 commit comments

Comments
 (0)