Skip to content

Commit 603229d

Browse files
committed
WIP Test Coverage
1 parent 0bdd4ac commit 603229d

File tree

7 files changed

+260
-43
lines changed

7 files changed

+260
-43
lines changed

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"private": false,
33
"author": "Matthew Oaxaca",
44
"license": "MIT",
5-
"version": "1.1.8",
5+
"version": "2.0.0",
66
"name": "async-redis",
77
"keywords": [
88
"redis",
@@ -40,6 +40,8 @@
4040
"redis": "3.0.2"
4141
},
4242
"devDependencies": {
43+
"@types/node": "^14.0.27",
44+
"@types/redis": "^2.8.25",
4345
"chai": "^4.2.0",
4446
"chai-as-promised": "^7.1.1",
4547
"coveralls": "^3.1.0",

src/index.d.ts

+125-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
1-
import { Commands, RedisClient, ClientOpts } from 'redis';
1+
import { Commands, RedisClient, ClientOpts, ServerInfo } from 'redis';
2+
import {EventEmitter} from "events";
3+
4+
type Callback<T> = (err: Error | null, reply: T) => void;
25

36
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
47
type Omitted = Omit<RedisClient, keyof Commands<boolean>>;
8+
type OkOrError = 'OK'|Error
9+
10+
interface OverloadedCommand<T, R> {
11+
(arg1: T, arg2: T, arg3: T, arg4: T, arg5: T, arg6: T): R;
12+
(arg1: T, arg2: T, arg3: T, arg4: T, arg5: T): R;
13+
(arg1: T, arg2: T, arg3: T, arg4: T): R;
14+
(arg1: T, arg2: T, arg3: T): R;
15+
(arg1: T, arg2: T | T[]): R;
16+
(arg1: T | T[]): R;
17+
(...args: Array<T>): R;
18+
}
519

620
interface Promisified<T = RedisClient> extends Omitted, Commands<Promise<boolean>> {}
721

@@ -19,10 +33,117 @@ interface AsyncRedisConstructor {
1933
decorate: (client: RedisClient) => Promisified;
2034
}
2135

22-
interface AsyncRedisCommands {
36+
interface AsyncRedisEventHandlers extends EventEmitter {
37+
on(event: 'message' | 'message_buffer', listener: (channel: string, message: string) => void): this;
38+
on(event: 'pmessage' | 'pmessage_buffer', listener: (pattern: string, channel: string, message: string) => void): this;
39+
on(event: 'subscribe' | 'unsubscribe', listener: (channel: string, count: number) => void): this;
40+
on(event: 'psubscribe' | 'punsubscribe', listener: (pattern: string, count: number) => void): this;
41+
on(event: string, listener: (...args: any[]) => void): this;
42+
}
43+
44+
interface AsyncRedisCommands<R> {
45+
/**
46+
* Listen for all requests received by the server in real time.
47+
*/
48+
monitor(cb?: Callback<undefined>): any;
49+
MONITOR(cb?: Callback<undefined>): any;
50+
51+
/**
52+
* Get information and statistics about the server.
53+
*/
54+
info(): Promise<ServerInfo|boolean>;
55+
info(section?: string | string[]): Promise<ServerInfo|boolean>;
56+
INFO(): Promise<ServerInfo|boolean>;
57+
INFO(section?: string | string[]): Promise<ServerInfo|boolean>;
58+
59+
/**
60+
* Ping the server.
61+
*/
62+
ping(): Promise<string|boolean>;
63+
ping(message: string): Promise<string|boolean>;
64+
PING(): Promise<string|boolean>;
65+
PING(message: string): Promise<string|boolean>;
66+
67+
/**
68+
* Authenticate to the server.
69+
*/
70+
auth(password: string): Promise<string>;
71+
AUTH(password: string): Promise<string>;
72+
73+
/**
74+
* Get array of Redis command details.
75+
*
76+
* COUNT - Get total number of Redis commands.
77+
* GETKEYS - Extract keys given a full Redis command.
78+
* INFO - Get array of specific REdis command details.
79+
*/
80+
command(cb?: Callback<Array<[string, number, string[], number, number, number]>>): R;
81+
COMMAND(cb?: Callback<Array<[string, number, string[], number, number, number]>>): R;
82+
83+
/**
84+
* Get array of Redis command details.
85+
*
86+
* COUNT - Get array of Redis command details.
87+
* GETKEYS - Extract keys given a full Redis command.
88+
* INFO - Get array of specific Redis command details.
89+
* GET - Get the value of a configuration parameter.
90+
* REWRITE - Rewrite the configuration file with the in memory configuration.
91+
* SET - Set a configuration parameter to the given value.
92+
* RESETSTAT - Reset the stats returned by INFO.
93+
*/
94+
config: OverloadedCommand<string, boolean>;
95+
CONFIG: OverloadedCommand<string, boolean>;
96+
97+
/**
98+
* Return the number of keys in the selected database.
99+
*/
100+
dbsize(): Promise<number>;
101+
DBSIZE(): Promise<number>;
102+
103+
/**
104+
* OBJECT - Get debugging information about a key.
105+
* SEGFAULT - Make the server crash.
106+
*/
107+
debug: OverloadedCommand<string, boolean>;
108+
DEBUG: OverloadedCommand<string, boolean>;
109+
110+
/**
111+
* PubSub Commands
112+
*/
113+
/**
114+
* Post a message to a channel.
115+
*/
116+
publish(channel: string, value: string): Promise<number|boolean>;
117+
PUBLISH(channel: string, value: string): Promise<number|boolean>;
118+
23119
/**
24120
* CRUD Commands
25121
*/
122+
123+
/**
124+
* Append a value to a key.
125+
*/
126+
append(key: string, value: string): Promise<number>;
127+
APPEND(key: string, value: string): Promise<number>;
128+
129+
/**
130+
* Asynchronously rewrite the append-only file.
131+
*/
132+
bgrewriteaof(): Promise<OkOrError>;
133+
BGREWRITEAOF(): Promise<OkOrError>;
134+
135+
/**
136+
* Asynchronously save the dataset to disk.
137+
*/
138+
bgsave(): Promise<OkOrError>;
139+
BGSAVE(): Promise<OkOrError>;
140+
141+
/**
142+
* Determine if a key exists.
143+
*/
144+
exists: OverloadedCommand<string, R>;
145+
EXISTS: OverloadedCommand<string, R>;
146+
26147
/**
27148
* Set the string value of a key.
28149
*/
@@ -36,5 +157,6 @@ interface AsyncRedisCommands {
36157
SET(key: string, value: string, mode: string, duration: number, flag: string): Promise<string|undefined>;
37158
}
38159

39-
declare const AsyncRedis: AsyncRedisConstructor;
160+
interface AsyncRedisInterface extends AsyncRedisConstructor, AsyncRedisEventHandlers, AsyncRedisCommands<boolean> {}
161+
declare const AsyncRedis: AsyncRedisInterface;
40162
export = AsyncRedis;

src/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ AsyncRedis.prototype.setup = function(redisClient) {
2323
const commandConfigs = redisCommands(redisClient);
2424
objectDecorator(redisClient, (name, method) => {
2525
if (commandConfigs.commands.has(name)) {
26-
objectPromisify(this, method);
26+
objectPromisify(this, redisClient, name);
2727
} else if (commandConfigs.queueCommands.has(name)) {
2828
return (...args) => {
2929
const multi = method.apply(redisClient, args);

src/object-decorator.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
*/
66
module.exports = (object, decorator) => {
77
for (const prop in object) {
8-
console.log(prop);
98
if (typeof object[prop] === 'function') {
10-
object[prop] = decorator(prop, object[prop]);
9+
decorator(prop, object[prop]);
1110
}
1211
}
1312
return object;

src/object-promisify.js

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
/**
2+
* @param proxy
23
* @param object
3-
* @param method
4-
* @returns {*}
4+
* @param name
5+
* @returns void
56
*/
6-
module.exports = (object, method) => {
7-
return (...args) => new Promise((resolve, reject) => {
8-
args.push((error, ...results) => {
9-
console.log(results);
10-
if (error) {
11-
reject(error, ...results);
12-
} else {
13-
resolve(...results);
14-
}
7+
module.exports = (proxy, object, name) => {
8+
proxy[name] = (...args) => {
9+
return new Promise((resolve, reject) => {
10+
args.push((error, ...results) => {
11+
if (error) {
12+
reject(error, ...results);
13+
} else {
14+
resolve(...results);
15+
}
16+
});
17+
object[name](...args);
1518
});
16-
objects.
17-
method.apply(object, args);
18-
});
19+
};
1920
};

test/integration/commands.spec.js

+102-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
require('../setup');
12
const { assert } = require('chai');
23

4+
/**
5+
* @type {AsyncRedis}
6+
*/
37
const AsyncRedis = require('../../src');
48
const getTestRedisConfig = require('../util/getTestRedisConfig');
59

@@ -14,25 +18,59 @@ describe('Commands', () => {
1418
redis.flushall();
1519
});
1620

17-
xdescribe('APPEND Commands', () => {
18-
it('should execute append', async () => {
19-
const status = await redis.append('SETUSER', 'hello');
20-
assert.equal(status, 'OK');
21+
describe('Auth', () => {
22+
it('should check decoration', async () => {
23+
assert.equal(typeof redis.auth, 'function');
2124
});
2225

23-
it('should execute exists', async () => {
24-
const status = await redis.append('SETUSER', 'world');
26+
it('should test rejection', async () => {
27+
const promise = redis.auth('bad_password');
28+
assert.isRejected(promise, Error);
29+
});
30+
});
31+
32+
describe('CRUD - AOF (Append Only File)', () => {
33+
it('should work with AOF', async () => {
34+
await redis.config('set', 'appendonly', 'no');
35+
await redis.config('rewrite');
36+
let status = await redis.bgrewriteaof();
37+
assert.equal(status, 'Background append only file rewriting started');
38+
status = await redis.set('test', 'value');
2539
assert.equal(status, 'OK');
40+
status = await redis.bgsave();
41+
await redis.bgrewriteaof();
42+
assert.equal(status, 'Background saving started');
2643
});
2744
});
2845

29-
describe('CRUD (set, get, del)', () => {
30-
it('should return ok', async () => {
46+
describe('CRUD (append, set, get, del, exists)', () => {
47+
it('should execute append', async () => {
48+
let status = await redis.append('KEY', 'hello');
49+
assert.equal(status, 5);
50+
status = await redis.append('KEY', 'world');
51+
assert.equal(status, 10);
52+
});
53+
54+
it('should execute exists', async () => {
55+
let status = await redis.exists('KEY');
56+
assert.equal(status, 0);
57+
await redis.set('KEY', '');
58+
status = await redis.exists('KEY');
59+
assert.equal(status, 1);
60+
});
61+
62+
it('should set and return ok', async () => {
3163
const status = await redis.set('hello', 'world');
3264
assert.equal(status, "OK");
3365
});
3466

35-
it('should return true', async () => {
67+
it('should get value', async () => {
68+
await redis.set('hello', 'world');
69+
const value = await redis.get('hello');
70+
assert.equal(value, "world");
71+
});
72+
73+
it('should del and return true', async () => {
3674
await redis.set('hello', 'world');
3775
const status = await redis.del('hello');
3876
assert.equal(status, true);
@@ -44,17 +82,65 @@ describe('Commands', () => {
4482
});
4583
});
4684

47-
xdescribe('test rejection', () => {
48-
it('should reject promise on throw', async () => {
49-
const promise = redis.set('hello');
50-
assert.isRejected(promise, Error);
51-
});
52-
});
53-
5485
xdescribe('test multi not a promise', () => {
5586
it('should be not equal', async () => {
5687
const notAPromise = redis.multi();
5788
assert.notEqual(Promise.resolve(notAPromise), notAPromise);
5889
});
5990
});
91+
92+
describe('PubSub', () => {
93+
94+
});
95+
96+
describe('Utility', () => {
97+
it('should return server info', async () => {
98+
let info = await redis.info();
99+
assert.equal(info.slice(0, 8), '# Server');
100+
});
101+
102+
it('should ping', async () => {
103+
let reply = await redis.ping();
104+
assert.equal(reply, 'PONG');
105+
});
106+
107+
it('should return db size', async () => {
108+
let status = await redis.set('test', 'value');
109+
assert.equal(status, 'OK');
110+
status = await redis.dbsize();
111+
assert.equal(status, 1);
112+
});
113+
114+
it('should execute debug', async () => {
115+
let status = await redis.set('test', 'value');
116+
assert.equal(status, 'OK');
117+
status = await redis.debug('object', 'test');
118+
assert(status);
119+
});
120+
121+
it('should execute monitor', async () => {
122+
const promises = [];
123+
promises.push(new Promise((resolve, reject) => {
124+
redis.monitor((error, status) => {
125+
if (error) {
126+
reject(error)
127+
} else {
128+
assert.equal(status, 'OK');
129+
resolve();
130+
}
131+
});
132+
}));
133+
promises.push(new Promise((resolve) => {
134+
redis.on('monitor', function(time, args) {
135+
assert.equal(args.length, 3);
136+
assert.equal(args[0], 'set');
137+
assert.equal(args[1], 'hello');
138+
assert.equal(args[2], 'world');
139+
resolve();
140+
});
141+
}));
142+
promises.push(redis.set('hello', 'world'));
143+
await Promise.all(promises);
144+
});
145+
});
60146
});

0 commit comments

Comments
 (0)