Skip to content

Commit 071b3ff

Browse files
author
Benjamin Coe
committed
moved tests for specific commands into the /commands sub-folder, put a ton of tests around the multi command
1 parent eaca486 commit 071b3ff

13 files changed

+311
-81
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"scripts": {
1313
"coverage": "nyc report --reporter=text-lcov | coveralls",
1414
"test": "nyc ./test/run.sh",
15-
"mocha": "nyc ./node_modules/.bin/_mocha ./test/mocha/*.js"
15+
"mocha": "nyc ./node_modules/.bin/_mocha ./test/mocha/*.js ./test/mocha/commands/*.js"
1616
},
1717
"devDependencies": {
1818
"async": "^1.3.0",

test/lib/nodeify-assertions.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,15 @@ module.exports = {
5656
return true;
5757
};
5858
}
59+
},
60+
61+
serverVersionAtLeast: function (connection, desired_version) {
62+
// Return true if the server version >= desired_version
63+
var version = connection.server_info.versions;
64+
for (var i = 0; i < 3; i++) {
65+
if (version[i] > desired_version[i]) return true;
66+
if (version[i] < desired_version[i]) return false;
67+
}
68+
return true;
5969
}
6070
};

test/mocha/dbsize.spec.js renamed to test/mocha/commands/dbsize.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
var async = require('async');
22
var assert = require('assert');
3-
var config = require("../lib/config");
4-
var nodeAssert = require('../lib/nodeify-assertions');
3+
var config = require("../../lib/config");
4+
var nodeAssert = require('../../lib/nodeify-assertions');
55
var redis = config.redis;
6-
var RedisProcess = require("../lib/redis-process");
6+
var RedisProcess = require("../../lib/redis-process");
77
var uuid = require('uuid');
88

99
describe("The 'dbsize' method", function () {

test/mocha/flushdb.spec.js renamed to test/mocha/commands/flushdb.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
var async = require('async');
22
var assert = require('assert');
3-
var config = require("../lib/config");
4-
var nodeAssert = require('../lib/nodeify-assertions');
3+
var config = require("../../lib/config");
4+
var nodeAssert = require('../../lib/nodeify-assertions');
55
var redis = config.redis;
6-
var RedisProcess = require("../lib/redis-process");
6+
var RedisProcess = require("../../lib/redis-process");
77
var uuid = require('uuid');
88

99
describe("The 'flushdb' method", function () {

test/mocha/get.spec.js renamed to test/mocha/commands/get.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
var async = require('async');
22
var assert = require('assert');
3-
var config = require("../lib/config");
4-
var nodeAssert = require('../lib/nodeify-assertions');
3+
var config = require("../../lib/config");
4+
var nodeAssert = require('../../lib/nodeify-assertions');
55
var redis = config.redis;
6-
var RedisProcess = require("../lib/redis-process");
6+
var RedisProcess = require("../../lib/redis-process");
77
var uuid = require('uuid');
88

99
describe("The 'get' method", function () {

test/mocha/getset.spec.js renamed to test/mocha/commands/getset.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
var async = require('async');
22
var assert = require('assert');
3-
var config = require("../lib/config");
4-
var nodeAssert = require('../lib/nodeify-assertions');
3+
var config = require("../../lib/config");
4+
var nodeAssert = require('../../lib/nodeify-assertions');
55
var redis = config.redis;
6-
var RedisProcess = require("../lib/redis-process");
6+
var RedisProcess = require("../../lib/redis-process");
77
var uuid = require('uuid');
88

99
describe("The 'getset' method", function () {

test/mocha/incr.spec.js renamed to test/mocha/commands/incr.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
var async = require('async');
22
var assert = require('assert');
3-
var config = require("../lib/config");
4-
var nodeAssert = require('../lib/nodeify-assertions');
3+
var config = require("../../lib/config");
4+
var nodeAssert = require('../../lib/nodeify-assertions');
55
var redis = config.redis;
6-
var RedisProcess = require("../lib/redis-process");
6+
var RedisProcess = require("../../lib/redis-process");
77
var uuid = require('uuid');
88

99
describe("The 'incr' method", function () {

test/mocha/mset.spec.js renamed to test/mocha/commands/mset.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
var async = require('async');
22
var assert = require('assert');
3-
var config = require("../lib/config");
4-
var nodeAssert = require('../lib/nodeify-assertions');
3+
var config = require("../../lib/config");
4+
var nodeAssert = require('../../lib/nodeify-assertions');
55
var redis = config.redis;
6-
var RedisProcess = require("../lib/redis-process");
6+
var RedisProcess = require("../../lib/redis-process");
77
var uuid = require('uuid');
88

99
describe("The 'mset' method", function () {

test/mocha/commands/multi.spec.js

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
var async = require('async');
2+
var assert = require('assert');
3+
var config = require("../../lib/config");
4+
var nodeAssert = require('../../lib/nodeify-assertions');
5+
var redis = config.redis;
6+
var RedisProcess = require("../../lib/redis-process");
7+
var uuid = require('uuid');
8+
9+
describe("The 'multi' method", function () {
10+
11+
var rp;
12+
before(function (done) {
13+
RedisProcess.start(function (err, _rp) {
14+
rp = _rp;
15+
return done(err);
16+
});
17+
})
18+
19+
function removeMochaListener () {
20+
var mochaListener = process.listeners('uncaughtException').pop();
21+
process.removeListener('uncaughtException', mochaListener);
22+
return mochaListener;
23+
}
24+
25+
function allTests(parser, ip) {
26+
var args = config.configureClient(parser, ip);
27+
28+
describe("using " + parser + " and " + ip, function () {
29+
var key, value;
30+
31+
beforeEach(function () {
32+
key = uuid.v4();
33+
value = uuid.v4();
34+
});
35+
36+
describe("when not connected", function () {
37+
var client;
38+
39+
beforeEach(function (done) {
40+
client = redis.createClient.apply(redis.createClient, args);
41+
client.once("error", done);
42+
client.once("connect", function () {
43+
client.quit();
44+
});
45+
client.on('end', function () {
46+
return done();
47+
});
48+
});
49+
50+
it("reports an error", function (done) {
51+
client.multi();
52+
client.exec(function (err, res) {
53+
assert.equal(err.message, 'Redis connection gone from end event.');
54+
done();
55+
});
56+
});
57+
});
58+
59+
describe("when connected", function () {
60+
var client;
61+
62+
beforeEach(function (done) {
63+
client = redis.createClient.apply(redis.createClient, args);
64+
client.once("error", done);
65+
client.once("connect", function () {
66+
client.del('multifoo', 'multibar', 'multifoo_8', 'multibar_8', function (err) {
67+
return done(err);
68+
})
69+
});
70+
});
71+
72+
afterEach(function () {
73+
client.end();
74+
});
75+
76+
it('roles back a transaction when one command in a sequence of commands fails', function (done) {
77+
var name = "MULTI_1", multi1, multi2;
78+
79+
// Provoke an error at queue time
80+
multi1 = client.multi();
81+
multi1.mset("multifoo", "10", "multibar", "20", nodeAssert.isString("OK"));
82+
multi1.set("foo2", nodeAssert.isError());
83+
multi1.incr("multifoo", nodeAssert.isNumber(11));
84+
multi1.incr("multibar", nodeAssert.isNumber(21));
85+
multi1.exec(function () {
86+
// Redis 2.6.5+ will abort transactions with errors
87+
// see: http://redis.io/topics/transactions
88+
var multibar_expected = 22;
89+
var multifoo_expected = 12;
90+
if (nodeAssert.serverVersionAtLeast(client, [2, 6, 5])) {
91+
multibar_expected = 1;
92+
multifoo_expected = 1;
93+
}
94+
95+
// Confirm that the previous command, while containing an error, still worked.
96+
multi2 = client.multi();
97+
multi2.incr("multibar", nodeAssert.isNumber(multibar_expected));
98+
multi2.incr("multifoo", nodeAssert.isNumber(multifoo_expected));
99+
multi2.exec(function (err, replies) {
100+
assert.strictEqual(multibar_expected, replies[0]);
101+
assert.strictEqual(multifoo_expected, replies[1]);
102+
return done();
103+
});
104+
});
105+
});
106+
107+
// I'm unclear as to the difference between this test in the test above,
108+
// perhaps @mranney can clarify?
109+
it('roles back a transaction when an error was provoked at queue time', function (done) {
110+
multi1 = client.multi();
111+
multi1.mset("multifoo_8", "10", "multibar_8", "20", nodeAssert.isString("OK"));
112+
multi1.set("foo2", nodeAssert.isError());
113+
multi1.set("foo3", nodeAssert.isError());
114+
multi1.incr("multifoo_8", nodeAssert.isNumber(11));
115+
multi1.incr("multibar_8", nodeAssert.isNumber(21));
116+
multi1.exec(function () {
117+
// Redis 2.6.5+ will abort transactions with errors
118+
// see: http://redis.io/topics/transactions
119+
var multibar_expected = 22;
120+
var multifoo_expected = 12;
121+
if (nodeAssert.serverVersionAtLeast(client, [2, 6, 5])) {
122+
multibar_expected = 1;
123+
multifoo_expected = 1;
124+
}
125+
126+
// Confirm that the previous command, while containing an error, still worked.
127+
multi2 = client.multi();
128+
multi2.incr("multibar_8", nodeAssert.isNumber(multibar_expected));
129+
multi2.incr("multifoo_8", nodeAssert.isNumber(multifoo_expected));
130+
multi2.exec(function (err, replies) {
131+
assert.strictEqual(multibar_expected, replies[0]);
132+
assert.strictEqual(multifoo_expected, replies[1]);
133+
return done();
134+
});
135+
});
136+
});
137+
138+
it('roles back a transaction when one command in an array of commands fails', function (done) {
139+
// test nested multi-bulk replies
140+
client.multi([
141+
["mget", "multifoo", "multibar", function (err, res) {
142+
assert.strictEqual(2, res.length);
143+
assert.strictEqual("0", res[0].toString());
144+
assert.strictEqual("0", res[1].toString());
145+
}],
146+
["set", "foo2", nodeAssert.isError()],
147+
["incr", "multifoo", nodeAssert.isNumber(1)],
148+
["incr", "multibar", nodeAssert.isNumber(1)]
149+
]).exec(function (err, replies) {
150+
if (nodeAssert.serverVersionAtLeast(client, [2, 6, 5])) {
151+
assert.notEqual(err, null);
152+
assert.equal(replies, undefined);
153+
} else {
154+
assert.strictEqual(2, replies[0].length);
155+
assert.strictEqual("0", replies[0][0].toString());
156+
assert.strictEqual("0", replies[0][1].toString());
157+
158+
assert.strictEqual("1", replies[1].toString());
159+
assert.strictEqual("1", replies[2].toString());
160+
}
161+
162+
return done();
163+
});
164+
});
165+
166+
it('handles multiple operations being applied to a set', function (done) {
167+
client.sadd("some set", "mem 1");
168+
client.sadd("some set", "mem 2");
169+
client.sadd("some set", "mem 3");
170+
client.sadd("some set", "mem 4");
171+
172+
// make sure empty mb reply works
173+
client.del("some missing set");
174+
client.smembers("some missing set", function (err, reply) {
175+
// make sure empty mb reply works
176+
assert.strictEqual(0, reply.length);
177+
});
178+
179+
// test nested multi-bulk replies with empty mb elements.
180+
client.multi([
181+
["smembers", "some set"],
182+
["del", "some set"],
183+
["smembers", "some set"]
184+
])
185+
.scard("some set")
186+
.exec(function (err, replies) {
187+
assert.strictEqual(4, replies[0].length);
188+
assert.strictEqual(0, replies[2].length);
189+
return done();
190+
});
191+
});
192+
193+
it('allows multiple operations to be performed using a chaining API', function (done) {
194+
client.multi()
195+
.mset('some', '10', 'keys', '20')
196+
.incr('some')
197+
.incr('keys')
198+
.mget('some', 'keys')
199+
.exec(function (err, replies) {
200+
assert.strictEqual(null, err);
201+
assert.equal('OK', replies[0]);
202+
assert.equal(11, replies[1]);
203+
assert.equal(21, replies[2]);
204+
assert.equal(11, replies[3][0].toString());
205+
assert.equal(21, replies[3][1].toString());
206+
return done();
207+
});
208+
});
209+
210+
it('allows an array to be provided indicating multiple operations to perform', function (done) {
211+
// test nested multi-bulk replies with nulls.
212+
client.multi([
213+
["mget", ["multifoo", "some", "random value", "keys"]],
214+
["incr", "multifoo"]
215+
])
216+
.exec(function (err, replies) {
217+
assert.strictEqual(replies.length, 2);
218+
assert.strictEqual(replies[0].length, 4);
219+
return done();
220+
});
221+
});
222+
223+
it('allows multiple operations to be performed on a hash', function (done) {
224+
client.multi()
225+
.hmset("multihash", "a", "foo", "b", 1)
226+
.hmset("multihash", {
227+
extra: "fancy",
228+
things: "here"
229+
})
230+
.hgetall("multihash")
231+
.exec(function (err, replies) {
232+
assert.strictEqual(null, err);
233+
assert.equal("OK", replies[0]);
234+
assert.equal(Object.keys(replies[2]).length, 4);
235+
assert.equal("foo", replies[2].a);
236+
assert.equal("1", replies[2].b);
237+
assert.equal("fancy", replies[2].extra);
238+
assert.equal("here", replies[2].things);
239+
return done();
240+
});
241+
});
242+
243+
it('reports multiple exceptions when they occur', function (done) {
244+
if (!nodeAssert.serverVersionAtLeast(client, [2, 6, 5])) return done();
245+
246+
client.multi().set("foo").exec(function (err, reply) {
247+
assert(Array.isArray(err), "err should be an array");
248+
assert.equal(2, err.length, "err should have 2 items");
249+
assert(err[0].message.match(/ERR/), "First error message should contain ERR");
250+
assert(err[1].message.match(/EXECABORT/), "First error message should contain EXECABORT");
251+
return done();
252+
});
253+
});
254+
255+
});
256+
});
257+
}
258+
259+
['javascript', 'hiredis'].forEach(function (parser) {
260+
allTests(parser, "/tmp/redis.sock");
261+
['IPv4', 'IPv6'].forEach(function (ip) {
262+
allTests(parser, ip);
263+
})
264+
});
265+
266+
after(function (done) {
267+
if (rp) rp.stop(done);
268+
});
269+
});

test/mocha/select.spec.js renamed to test/mocha/commands/select.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
var async = require('async');
22
var assert = require('assert');
3-
var config = require("../lib/config");
4-
var nodeAssert = require('../lib/nodeify-assertions');
3+
var config = require("../../lib/config");
4+
var nodeAssert = require('../../lib/nodeify-assertions');
55
var redis = config.redis;
6-
var RedisProcess = require("../lib/redis-process");
6+
var RedisProcess = require("../../lib/redis-process");
77

88
describe("The 'select' method", function () {
99

0 commit comments

Comments
 (0)