Skip to content

Commit 29b31f7

Browse files
author
Ruben Bridgewater
committed
Add a better promise documentation and add some tests
1 parent db8c6e3 commit 29b31f7

File tree

6 files changed

+80
-13
lines changed

6 files changed

+80
-13
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,30 @@ Note that the API is entire asynchronous. To get data back from the server,
5353
you'll need to use a callback. The return value from most of the API is a
5454
backpressure indicator.
5555

56+
### Promises
57+
5658
You can also use node_redis with promises by promisifying node_redis with [bluebird](https://github.com/petkaantonov/bluebird) as in:
5759

5860
```js
5961
var redis = require('redis');
6062
bluebird.promisifyAll(redis.RedisClient.prototype);
63+
bluebird.promisifyAll(redis.Multi.prototype);
64+
```
65+
66+
It'll add a *Async* to all node_redis functions (e.g. return client.getAsync().then())
67+
68+
```js
69+
// We expect a value 'foo': 'bar' to be present
70+
// So instead of writing client.get('foo', cb); you have to write:
71+
return client.getAsync('foo').then(function(res) {
72+
console.log(res); // => 'bar'
73+
});
74+
75+
// Using multi with promises looks like:
76+
77+
return client.multi().get('foo').execAsync().then(function(res) {
78+
console.log(res); // => 'bar'
79+
});
6180
```
6281

6382
### Sending Commands

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"optional-dev-dependency": "^1.1.0",
2727
"tcp-port-used": "^0.1.2",
2828
"uuid": "^2.0.1",
29-
"win-spawn": "^2.0.0"
29+
"win-spawn": "^2.0.0",
30+
"bluebird": "^2.10.0"
3031
},
3132
"repository": {
3233
"type": "git",

test/commands/mget.spec.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ describe("The 'mget' method", function () {
5252
});
5353
});
5454

55+
it('handles fetching multiple keys, when some keys do not exist promisified', function () {
56+
return client.MGETAsync("mget keys 1", ["some random shit", "mget keys 2", "mget keys 3"]).then(function (results) {
57+
assert.strictEqual(4, results.length);
58+
assert.strictEqual("mget val 1", results[0].toString());
59+
assert.strictEqual(null, results[1]);
60+
assert.strictEqual("mget val 2", results[2].toString());
61+
assert.strictEqual("mget val 3", results[3].toString());
62+
});
63+
});
64+
5565
afterEach(function () {
5666
client.end();
5767
});

test/commands/multi.spec.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ describe("The 'multi' method", function () {
3838
done();
3939
});
4040
});
41+
42+
it("reports an error if promisified", function () {
43+
return client.multi().execAsync().catch(function(err) {
44+
assert(err.message.match(/The connection has already been closed/));
45+
});
46+
});
4147
});
4248

4349
describe("when connected", function () {
@@ -238,6 +244,22 @@ describe("The 'multi' method", function () {
238244
});
239245
});
240246

247+
it('allows multiple commands to work the same as normal to be performed using a chaining API promisified', function () {
248+
return client.multi()
249+
.mset(['some', '10', 'keys', '20'])
250+
.incr(['some', helper.isNumber(11)])
251+
.incr(['keys'], helper.isNumber(21))
252+
.mget('some', 'keys')
253+
.execAsync()
254+
.then(function (replies) {
255+
assert.equal('OK', replies[0]);
256+
assert.equal(11, replies[1]);
257+
assert.equal(21, replies[2]);
258+
assert.equal(11, replies[3][0].toString());
259+
assert.equal(21, replies[3][1].toString());
260+
});
261+
});
262+
241263
it('allows an array to be provided indicating multiple operations to perform', function (done) {
242264
// test nested multi-bulk replies with nulls.
243265
client.multi([
@@ -299,6 +321,19 @@ describe("The 'multi' method", function () {
299321
});
300322
});
301323

324+
it('reports multiple exceptions when they occur (while EXEC is running) promisified', function () {
325+
return client.multi().config("bar").debug("foo").eval("return {err='this is an error'}", 0).execAsync().then(function (reply) {
326+
assert.strictEqual(reply.length, 3);
327+
assert.equal(reply[0].code, 'ERR');
328+
assert.equal(reply[0].command, 'CONFIG');
329+
assert.equal(reply[2].code, undefined);
330+
assert.equal(reply[2].command, 'EVAL');
331+
assert(/^this is an error/.test(reply[2].message));
332+
assert(/^ERR/.test(reply[0].message), "Error message should begin with ERR");
333+
assert(/^ERR/.test(reply[1].message), "Error message should begin with ERR");
334+
});
335+
});
336+
302337
it('reports multiple exceptions when they occur (while EXEC is running) and calls cb', function (done) {
303338
var multi = client.multi();
304339
multi.config("bar", helper.isError());

test/lib/config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
// helpers for configuring a redis client in
44
// its various modes, ipV6, ipV4, socket.
55
var redis = require('../../index');
6+
var bluebird = require('bluebird');
7+
8+
// Promisify everything
9+
bluebird.promisifyAll(redis.RedisClient.prototype);
10+
bluebird.promisifyAll(redis.Multi.prototype);
611

712
var config = {
813
redis: redis,

test/lib/redis-process.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,15 @@ function waitForRedis (available, cb) {
1515

1616
var ipV4 = false;
1717
var id = setInterval(function () {
18-
tcpPortUsed.check(config.PORT, '127.0.0.1')
19-
.then(function (_ipV4) {
20-
ipV4 = _ipV4;
21-
return tcpPortUsed.check(config.PORT, '::1');
22-
})
23-
.then(function (ipV6) {
24-
if (ipV6 === available && ipV4 === available &&
25-
fs.existsSync('/tmp/redis.sock') === available) {
26-
clearInterval(id);
27-
return cb();
28-
}
29-
});
18+
tcpPortUsed.check(config.PORT, '127.0.0.1').then(function (_ipV4) {
19+
ipV4 = _ipV4;
20+
return tcpPortUsed.check(config.PORT, '::1');
21+
}).then(function (ipV6) {
22+
if (ipV6 === available && ipV4 === available && fs.existsSync('/tmp/redis.sock') === available) {
23+
clearInterval(id);
24+
return cb();
25+
}
26+
});
3027
}, 100);
3128
}
3229

0 commit comments

Comments
 (0)