1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-10 11:43:01 +03:00

Merge pull request #838 from fintura/consistent-commands

Consistent commands arguments. All commands are from now on behaving the same no matter if they are on multi or no and they all take an array as either the first or second argument.

Fixes #686 #369 #422 #390 and Closes #634
This commit is contained in:
Ruben Bridgewater
2015-09-16 05:17:22 +02:00
23 changed files with 332 additions and 87 deletions

View File

@@ -16,6 +16,9 @@
"node": true, // Enable globals available when code is running inside of the NodeJS runtime environment. "node": true, // Enable globals available when code is running inside of the NodeJS runtime environment.
"mocha": true, "mocha": true,
// Relaxing options
"boss": true, // Accept things like `while (command = keys.shift()) { ... }`
"overrides": { "overrides": {
"examples/*.js": { "examples/*.js": {
"unused": false "unused": false

125
index.js
View File

@@ -863,8 +863,16 @@ RedisClient.prototype.end = function () {
function Multi(client, args) { function Multi(client, args) {
this._client = client; this._client = client;
this.queue = [["multi"]]; this.queue = [["multi"]];
var command, tmp_args;
if (Array.isArray(args)) { if (Array.isArray(args)) {
this.queue = this.queue.concat(args); while (tmp_args = args.shift()) {
command = tmp_args.shift();
if (Array.isArray(command)) {
this[command[0]].apply(this, command.slice(1).concat(tmp_args));
} else {
this[command].apply(this, tmp_args);
}
}
} }
} }
@@ -878,16 +886,32 @@ commands.forEach(function (fullCommand) {
return; return;
} }
RedisClient.prototype[command] = function (args, callback) { RedisClient.prototype[command] = function (key, arg, callback) {
if (Array.isArray(args)) { if (Array.isArray(key)) {
return this.send_command(command, args, callback); return this.send_command(command, key, arg);
}
if (Array.isArray(arg)) {
arg.unshift(key);
return this.send_command(command, arg, callback);
} }
return this.send_command(command, to_array(arguments)); return this.send_command(command, to_array(arguments));
}; };
RedisClient.prototype[command.toUpperCase()] = RedisClient.prototype[command]; RedisClient.prototype[command.toUpperCase()] = RedisClient.prototype[command];
Multi.prototype[command] = function () { Multi.prototype[command] = function (key, arg, callback) {
if (Array.isArray(key)) {
if (arg) {
key.push(arg);
}
this.queue.push([command].concat(key));
} else if (Array.isArray(arg)) {
if (callback) {
arg.push(callback);
}
this.queue.push([command, key].concat(arg));
} else {
this.queue.push([command].concat(to_array(arguments))); this.queue.push([command].concat(to_array(arguments)));
}
return this; return this;
}; };
Multi.prototype[command.toUpperCase()] = Multi.prototype[command]; Multi.prototype[command.toUpperCase()] = Multi.prototype[command];
@@ -919,70 +943,63 @@ RedisClient.prototype.auth = RedisClient.prototype.AUTH = function (pass, callba
} }
}; };
RedisClient.prototype.hmget = RedisClient.prototype.HMGET = function (arg1, arg2, arg3) { RedisClient.prototype.hmset = RedisClient.prototype.HMSET = function (key, args, callback) {
if (Array.isArray(arg2) && typeof arg3 === "function") { var field, tmp_args;
return this.send_command("hmget", [arg1].concat(arg2), arg3); if (Array.isArray(key)) {
} else if (Array.isArray(arg1) && typeof arg2 === "function") { return this.send_command("hmset", key, args);
return this.send_command("hmget", arg1, arg2);
} else {
return this.send_command("hmget", to_array(arguments));
} }
};
RedisClient.prototype.hmset = RedisClient.prototype.HMSET = function (args, callback) {
var tmp_args, tmp_keys, i, il, key;
if (Array.isArray(args)) { if (Array.isArray(args)) {
return this.send_command("hmset", args, callback); return this.send_command("hmset", [key].concat(args), callback);
} }
if (typeof args === "object") {
args = to_array(arguments);
if (typeof args[args.length - 1] === "function") {
callback = args[args.length - 1];
args.length -= 1;
} else {
callback = null;
}
if (args.length === 2 && (typeof args[0] === "string" || typeof args[0] === "number") && typeof args[1] === "object") {
// User does: client.hmset(key, {key1: val1, key2: val2}) // User does: client.hmset(key, {key1: val1, key2: val2})
// assuming key is a string, i.e. email address // assuming key is a string, i.e. email address
// if key is a number, i.e. timestamp, convert to string // if key is a number, i.e. timestamp, convert to string
if (typeof args[0] === "number") { // TODO: This seems random and no other command get's the key converted => either all or none should behave like this
args[0] = args[0].toString(); if (typeof key !== "string") {
key = key.toString();
} }
tmp_args = [key];
tmp_args = [ args[0] ]; var fields = Object.keys(args);
tmp_keys = Object.keys(args[1]); while (field = fields.shift()) {
for (i = 0, il = tmp_keys.length; i < il ; i++) { tmp_args.push(field, args[field]);
key = tmp_keys[i];
tmp_args.push(key);
tmp_args.push(args[1][key]);
} }
args = tmp_args; return this.send_command("hmset", tmp_args, callback);
} }
return this.send_command("hmset", to_array(arguments));
return this.send_command("hmset", args, callback);
}; };
Multi.prototype.hmset = Multi.prototype.HMSET = function () { Multi.prototype.hmset = Multi.prototype.HMSET = function (key, args, callback) {
var args = to_array(arguments), tmp_args; var tmp_args, field;
if (args.length >= 2 && typeof args[0] === "string" && typeof args[1] === "object") { if (Array.isArray(key)) {
tmp_args = [ "hmset", args[0] ]; if (args) {
Object.keys(args[1]).map(function (key) { key.push(args);
tmp_args.push(key); }
tmp_args.push(args[1][key]); tmp_args = ['hmset'].concat(key);
}); } else if (Array.isArray(args)) {
if (args[2]) { if (callback) {
tmp_args.push(args[2]); args.push(callback);
}
tmp_args = ['hmset', key].concat(args);
} else if (typeof args === "object") {
tmp_args = ["hmset", key];
if (typeof key !== "string") {
key = key.toString();
}
var fields = Object.keys(args);
while (field = fields.shift()) {
tmp_args.push(field);
tmp_args.push(args[field]);
}
if (callback) {
tmp_args.push(callback);
} }
args = tmp_args;
} else { } else {
args.unshift("hmset"); tmp_args = to_array(arguments);
tmp_args.unshift("hmset");
} }
this.queue.push(tmp_args);
this.queue.push(args);
return this; return this;
}; };

View File

@@ -33,6 +33,16 @@ describe("The 'blpop' method", function () {
}); });
}); });
it('pops value immediately if list contains values using array notation', function (done) {
bclient = redis.createClient.apply(redis.createClient, args);
client.rpush(["blocking list", "initial value"], helper.isNumber(1));
bclient.blpop(["blocking list", 0], function (err, value) {
assert.strictEqual(value[0], "blocking list");
assert.strictEqual(value[1], "initial value");
return done(err);
});
});
it('waits for value if list is not yet populated', function (done) { it('waits for value if list is not yet populated', function (done) {
bclient = redis.createClient.apply(redis.createClient, args); bclient = redis.createClient.apply(redis.createClient, args);
bclient.blpop("blocking list 2", 5, function (err, value) { bclient.blpop("blocking list 2", 5, function (err, value) {

View File

@@ -37,8 +37,17 @@ describe("The 'client' method", function () {
}); });
}); });
it("lists connected clients when invoked with array syntax on client", function (done) {
client.multi().client(["list"]).exec(function(err, results) {
assert(pattern.test(results[0]), "expected string '" + results + "' to match " + pattern.toString());
return done();
});
});
it("lists connected clients when invoked with multi's array syntax", function (done) { it("lists connected clients when invoked with multi's array syntax", function (done) {
client.multi().client("list").exec(function(err, results) { client.multi([
['client', 'list']
]).exec(function(err, results) {
assert(pattern.test(results[0]), "expected string '" + results + "' to match " + pattern.toString()); assert(pattern.test(results[0]), "expected string '" + results + "' to match " + pattern.toString());
return done(); return done();
}); });

View File

@@ -71,7 +71,7 @@ describe("The 'dbsize' method", function () {
var oldSize; var oldSize;
beforeEach(function (done) { beforeEach(function (done) {
client.dbsize([], function (err, res) { client.dbsize(function (err, res) {
helper.isType.number()(err, res); helper.isType.number()(err, res);
assert.strictEqual(res, 0, "Initial db size should be 0"); assert.strictEqual(res, 0, "Initial db size should be 0");

View File

@@ -36,6 +36,20 @@ describe("The 'del' method", function () {
client.get('apple', helper.isNull(done)); client.get('apple', helper.isNull(done));
}); });
it('allows multiple keys to be deleted with the array syntax', function (done) {
client.mset('foo', 'bar', 'apple', 'banana');
client.del(['foo', 'apple'], helper.isNumber(2));
client.get('foo', helper.isNull());
client.get('apple', helper.isNull(done));
});
it('allows multiple keys to be deleted with the array syntax and no callback', function (done) {
client.mset('foo', 'bar', 'apple', 'banana');
client.del(['foo', 'apple']);
client.get('foo', helper.isNull());
client.get('apple', helper.isNull(done));
});
afterEach(function () { afterEach(function () {
client.end(); client.end();
}); });

View File

@@ -24,6 +24,11 @@ describe("The 'exits' method", function () {
client.EXISTS('foo', helper.isNumber(1, done)); client.EXISTS('foo', helper.isNumber(1, done));
}); });
it('returns 1 if the key exists with array syntax', function (done) {
client.set('foo', 'bar');
client.EXISTS(['foo'], helper.isNumber(1, done));
});
it('returns 0 if the key does not exist', function (done) { it('returns 0 if the key does not exist', function (done) {
client.exists('bar', helper.isNumber(0, done)); client.exists('bar', helper.isNumber(0, done));
}); });

View File

@@ -20,6 +20,14 @@ describe("The 'expire' method", function () {
}); });
it('expires key after timeout', function (done) { it('expires key after timeout', function (done) {
client.set(['expiry key', 'bar'], helper.isString("OK"));
client.EXPIRE("expiry key", "1", helper.isNumber(1));
setTimeout(function () {
client.exists(["expiry key"], helper.isNumber(0, done));
}, 1100);
});
it('expires key after timeout with array syntax', function (done) {
client.set(['expiry key', 'bar'], helper.isString("OK")); client.set(['expiry key', 'bar'], helper.isString("OK"));
client.EXPIRE(["expiry key", "1"], helper.isNumber(1)); client.EXPIRE(["expiry key", "1"], helper.isNumber(1));
setTimeout(function () { setTimeout(function () {

View File

@@ -58,18 +58,17 @@ describe("The 'flushdb' method", function () {
describe("when there is data in Redis", function () { describe("when there is data in Redis", function () {
beforeEach(function (done) { beforeEach(function (done) {
var end = helper.callFuncAfter(function () { client.mset(key, uuid.v4(), key2, uuid.v4(), helper.isNotError());
client.flushdb(helper.isString("OK", done));
}, 2);
client.mset(key, uuid.v4(), key2, uuid.v4(), helper.isNotError(end));
client.dbsize([], function (err, res) { client.dbsize([], function (err, res) {
helper.isType.positiveNumber()(err, res); helper.isType.positiveNumber()(err, res);
assert.equal(res, 2, 'Two keys should have been inserted'); assert.equal(res, 2, 'Two keys should have been inserted');
end(); done();
}); });
}); });
it("deletes all the keys", function (done) { it("deletes all the keys", function (done) {
client.flushdb(function(err, res) {
assert.equal(res, 'OK');
client.mget(key, key2, function (err, res) { client.mget(key, key2, function (err, res) {
assert.strictEqual(null, err, "Unexpected error returned"); assert.strictEqual(null, err, "Unexpected error returned");
assert.strictEqual(true, Array.isArray(res), "Results object should be an array."); assert.strictEqual(true, Array.isArray(res), "Results object should be an array.");
@@ -79,8 +78,10 @@ describe("The 'flushdb' method", function () {
done(err); done(err);
}); });
}); });
});
it("results in a db size of zero", function (done) { it("results in a db size of zero", function (done) {
client.flushdb(function(err, res) {
client.dbsize([], function (err, res) { client.dbsize([], function (err, res) {
helper.isNotError()(err, res); helper.isNotError()(err, res);
helper.isType.number()(err, res); helper.isType.number()(err, res);
@@ -89,6 +90,19 @@ describe("The 'flushdb' method", function () {
}); });
}); });
}); });
it("results in a db size of zero without a callback", function (done) {
client.flushdb();
setTimeout(function(err, res) {
client.dbsize([], function (err, res) {
helper.isNotError()(err, res);
helper.isType.number()(err, res);
assert.strictEqual(0, res, "Flushing db should result in db size 0");
done();
});
}, 25);
});
});
}); });
}); });
}); });

View File

@@ -70,6 +70,21 @@ describe("The 'get' method", function () {
done(err); done(err);
}); });
}); });
it("gets the value correctly with array syntax and the callback being in the array", function (done) {
client.GET([key, function (err, res) {
helper.isString(value)(err, res);
done(err);
}]);
});
it("should not throw on a get without callback (even if it's not useful", function (done) {
client.GET(key);
client.on('error', function(err) {
throw err;
});
setTimeout(done, 50);
});
}); });
describe("when the key does not exist in Redis", function () { describe("when the key does not exist in Redis", function () {

View File

@@ -74,6 +74,26 @@ describe("The 'getset' method", function () {
}); });
}); });
}); });
it("gets the value correctly with array syntax", function (done) {
client.GETSET([key, value2], function (err, res) {
helper.isString(value)(err, res);
client.get(key, function (err, res) {
helper.isString(value2)(err, res);
done(err);
});
});
});
it("gets the value correctly with array syntax style 2", function (done) {
client.GETSET(key, [value2], function (err, res) {
helper.isString(value)(err, res);
client.get(key, function (err, res) {
helper.isString(value2)(err, res);
done(err);
});
});
});
}); });
describe("when the key does not exist in Redis", function () { describe("when the key does not exist in Redis", function () {

View File

@@ -67,7 +67,7 @@ describe("The 'hgetall' method", function () {
it('returns binary results', function (done) { it('returns binary results', function (done) {
client.hmset(["bhosts", "mjr", "1", "another", "23", "home", "1234", new Buffer([0xAA, 0xBB, 0x00, 0xF0]), new Buffer([0xCC, 0xDD, 0x00, 0xF0])], helper.isString("OK")); client.hmset(["bhosts", "mjr", "1", "another", "23", "home", "1234", new Buffer([0xAA, 0xBB, 0x00, 0xF0]), new Buffer([0xCC, 0xDD, 0x00, 0xF0])], helper.isString("OK"));
client.HGETALL(["bhosts"], function (err, obj) { client.HGETALL(["bhosts", function (err, obj) {
assert.strictEqual(4, Object.keys(obj).length); assert.strictEqual(4, Object.keys(obj).length);
assert.strictEqual("1", obj.mjr.toString()); assert.strictEqual("1", obj.mjr.toString());
assert.strictEqual("23", obj.another.toString()); assert.strictEqual("23", obj.another.toString());
@@ -75,7 +75,7 @@ describe("The 'hgetall' method", function () {
assert.strictEqual((new Buffer([0xAA, 0xBB, 0x00, 0xF0])).toString('binary'), Object.keys(obj)[3]); assert.strictEqual((new Buffer([0xAA, 0xBB, 0x00, 0xF0])).toString('binary'), Object.keys(obj)[3]);
assert.strictEqual((new Buffer([0xCC, 0xDD, 0x00, 0xF0])).toString('binary'), obj[(new Buffer([0xAA, 0xBB, 0x00, 0xF0])).toString('binary')].toString('binary')); assert.strictEqual((new Buffer([0xCC, 0xDD, 0x00, 0xF0])).toString('binary'), obj[(new Buffer([0xAA, 0xBB, 0x00, 0xF0])).toString('binary')].toString('binary'));
return done(err); return done(err);
}); }]);
}); });
}); });

View File

@@ -83,6 +83,24 @@ describe("The 'hmset' method", function () {
}); });
}); });
it('allows a key plus array without callback', function (done) {
client.HMSET(hash, [99, 'banana', 'test', 25]);
client.HGETALL(hash, function (err, obj) {
assert.equal(obj['99'], 'banana');
assert.equal(obj.test, '25');
return done(err);
});
});
it('allows a key plus array and a callback', function (done) {
client.HMSET(hash, [99, 'banana', 'test', 25], helper.isString('OK'));
client.HGETALL(hash, function (err, obj) {
assert.equal(obj['99'], 'banana');
assert.equal(obj.test, '25');
return done(err);
});
});
it('handles object-style syntax without callback', function (done) { it('handles object-style syntax without callback', function (done) {
client.HMSET(hash, {"0123456789": "abcdefghij", "some manner of key": "a type of value"}); client.HMSET(hash, {"0123456789": "abcdefghij", "some manner of key": "a type of value"});
client.HGETALL(hash, function (err, obj) { client.HGETALL(hash, function (err, obj) {

View File

@@ -23,7 +23,7 @@ describe("The 'keys' method", function () {
it('returns matching keys', function (done) { it('returns matching keys', function (done) {
client.mset(["test keys 1", "test val 1", "test keys 2", "test val 2"], helper.isString("OK")); client.mset(["test keys 1", "test val 1", "test keys 2", "test val 2"], helper.isString("OK"));
client.KEYS(["test keys*"], function (err, results) { client.KEYS("test keys*", function (err, results) {
assert.strictEqual(2, results.length); assert.strictEqual(2, results.length);
assert.ok(~results.indexOf("test keys 1")); assert.ok(~results.indexOf("test keys 1"));
assert.ok(~results.indexOf("test keys 2")); assert.ok(~results.indexOf("test keys 2"));

View File

@@ -42,7 +42,7 @@ describe("The 'mget' method", function () {
}); });
it('handles fetching multiple keys, when some keys do not exist', function (done) { it('handles fetching multiple keys, when some keys do not exist', function (done) {
client.MGET(["mget keys 1", "some random shit", "mget keys 2", "mget keys 3"], function (err, results) { client.MGET("mget keys 1", ["some random shit", "mget keys 2", "mget keys 3"], function (err, results) {
assert.strictEqual(4, results.length); assert.strictEqual(4, results.length);
assert.strictEqual("mget val 1", results[0].toString()); assert.strictEqual("mget val 1", results[0].toString());
assert.strictEqual(null, results[1]); assert.strictEqual(null, results[1]);

View File

@@ -88,6 +88,12 @@ describe("The 'mset' method", function () {
client.get(key, helper.isString(value2)); client.get(key, helper.isString(value2));
client.get(key2, helper.isString(value, done)); client.get(key2, helper.isString(value, done));
}); });
it("sets the value correctly with array syntax", function (done) {
client.mset([key, value2, key2, value]);
client.get([key, helper.isString(value2)]);
client.get(key2, helper.isString(value, done));
});
}); });
describe("with undefined 'key' and missing 'value' parameter", function () { describe("with undefined 'key' and missing 'value' parameter", function () {

View File

@@ -123,7 +123,7 @@ describe("The 'multi' method", function () {
it('handles multiple operations being applied to a set', function (done) { it('handles multiple operations being applied to a set', function (done) {
client.sadd("some set", "mem 1"); client.sadd("some set", "mem 1");
client.sadd("some set", "mem 2"); client.sadd(["some set", "mem 2"]);
client.sadd("some set", "mem 3"); client.sadd("some set", "mem 3");
client.sadd("some set", "mem 4"); client.sadd("some set", "mem 4");
@@ -136,7 +136,7 @@ describe("The 'multi' method", function () {
// test nested multi-bulk replies with empty mb elements. // test nested multi-bulk replies with empty mb elements.
client.multi([ client.multi([
["smembers", "some set"], ["smembers", ["some set"]],
["del", "some set"], ["del", "some set"],
["smembers", "some set"] ["smembers", "some set"]
]) ])
@@ -148,6 +148,40 @@ describe("The 'multi' method", function () {
}); });
}); });
it('allows multiple operations to be performed using constructor with all kinds of syntax', function (done) {
var now = Date.now();
client.multi([
["mset", [578, "multibar"], helper.isString('OK')],
[["mset", "multifoo2", "multibar2", "multifoo3", "multibar3"], helper.isString('OK')],
["hmset", ["multihmset", "multibar", "multibaz"]],
[["hmset", "multihmset2", "multibar2", "multifoo3", "multibar3", "test", helper.isString('OK')]],
["hmset", ["multihmset", "multibar", "multifoo", helper.isString('OK')]],
["hmset", [5768, "multibarx", "multifoox"], helper.isString('OK')],
['hmset', now, {123456789: "abcdefghij", "some manner of key": "a type of value", "otherTypes": 555}],
['hmset', 'key2', {"0123456789": "abcdefghij", "some manner of key": "a type of value", "otherTypes": 999}, helper.isString('OK')],
["hmset", "multihmset", ["multibar", "multibaz"]],
["hmset", "multihmset", ["multibar", "multibaz"], helper.isString('OK')],
])
.hmget(now, 123456789, 'otherTypes')
.hmget('key2', ['some manner of key', 'otherTypes'])
.hmget(['multihmset2', 'some manner of key', 'multibar3'])
.mget('multifoo2', ['multifoo3', 'multifoo'], function(err, res) {
assert(res[0], 'multifoo3');
assert(res[1], 'multifoo');
})
.exec(function (err, replies) {
assert.strictEqual(null, err);
assert.equal(replies[10][1], '555');
assert.equal(replies[11][0], 'a type of value');
assert.strictEqual(replies[12][0], null);
assert.equal(replies[12][1], 'test');
assert.equal(replies[13][0], 'multibar2');
assert.equal(replies[13].length, 3);
assert.equal(replies.length, 14);
return done();
});
});
it('allows multiple operations to be performed using a chaining API', function (done) { it('allows multiple operations to be performed using a chaining API', function (done) {
client.multi() client.multi()
.mset('some', '10', 'keys', '20') .mset('some', '10', 'keys', '20')
@@ -165,6 +199,23 @@ describe("The 'multi' method", function () {
}); });
}); });
it('allows multiple commands to work the same as normal to be performed using a chaining API', function (done) {
client.multi()
.mset(['some', '10', 'keys', '20'])
.incr(['some', helper.isNumber(11)])
.incr(['keys'], helper.isNumber(21))
.mget('some', 'keys')
.exec(function (err, replies) {
assert.strictEqual(null, err);
assert.equal('OK', replies[0]);
assert.equal(11, replies[1]);
assert.equal(21, replies[2]);
assert.equal(11, replies[3][0].toString());
assert.equal(21, replies[3][1].toString());
return done();
});
});
it('allows an array to be provided indicating multiple operations to perform', function (done) { it('allows an array to be provided indicating multiple operations to perform', function (done) {
// test nested multi-bulk replies with nulls. // test nested multi-bulk replies with nulls.
client.multi([ client.multi([

View File

@@ -0,0 +1,37 @@
'use strict';
var config = require("../lib/config");
var helper = require("../helper");
var redis = config.redis;
var assert = require('assert');
describe("The 'rpush' command", function () {
helper.allTests(function(parser, ip, args) {
describe("using " + parser + " and " + ip, function () {
var client;
beforeEach(function (done) {
client = redis.createClient.apply(redis.createClient, args);
client.once("error", done);
client.once("connect", function () {
client.flushdb(done);
});
});
it('inserts multiple values at a time into a list', function (done) {
client.rpush('test', ['list key', 'should be a list']);
client.lrange('test', 0, -1, function(err, res) {
assert.equal(res[0], 'list key');
assert.equal(res[1], 'should be a list');
done(err);
});
});
afterEach(function () {
client.end();
});
});
});
});

View File

@@ -44,6 +44,17 @@ describe("The 'sadd' method", function () {
}); });
}); });
it('allows multiple values to be added to the set with a different syntax', function (done) {
client.sadd(["set0", "member0", "member1", "member2"], helper.isNumber(3));
client.smembers("set0", function (err, res) {
assert.strictEqual(res.length, 3);
assert.ok(~res.indexOf("member0"));
assert.ok(~res.indexOf("member1"));
assert.ok(~res.indexOf("member2"));
return done(err);
});
});
afterEach(function () { afterEach(function () {
client.end(); client.end();
}); });

View File

@@ -22,11 +22,11 @@ describe("The 'sdiff' method", function () {
it('returns set difference', function (done) { it('returns set difference', function (done) {
client.sadd('foo', 'x', helper.isNumber(1)); client.sadd('foo', 'x', helper.isNumber(1));
client.sadd('foo', 'a', helper.isNumber(1)); client.sadd('foo', ['a'], helper.isNumber(1));
client.sadd('foo', 'b', helper.isNumber(1)); client.sadd('foo', 'b', helper.isNumber(1));
client.sadd('foo', 'c', helper.isNumber(1)); client.sadd(['foo', 'c'], helper.isNumber(1));
client.sadd('bar', 'c', helper.isNumber(1)); client.sadd(['bar', 'c', helper.isNumber(1)]);
client.sadd('baz', 'a', helper.isNumber(1)); client.sadd('baz', 'a', helper.isNumber(1));
client.sadd('baz', 'd', helper.isNumber(1)); client.sadd('baz', 'd', helper.isNumber(1));

View File

@@ -75,6 +75,13 @@ describe("The 'sort' method", function () {
}); });
}); });
it("handles sorting with a 'by' pattern and 2 'get' patterns with the array syntax", function (done) {
client.sort(['x', 'by', 'w*', 'asc', 'get', 'o*', 'get', 'p*'], function (err, sorted) {
assert.deepEqual(sorted, ['foo', 'bux', 'bar', 'tux', 'baz', 'lux', 'buz', 'qux']);
return done(err);
});
});
it("sorting with a 'by' pattern and 2 'get' patterns and stores results", function (done) { it("sorting with a 'by' pattern and 2 'get' patterns and stores results", function (done) {
client.sort('x', 'by', 'w*', 'asc', 'get', 'o*', 'get', 'p*', 'store', 'bacon', function (err) { client.sort('x', 'by', 'w*', 'asc', 'get', 'o*', 'get', 'p*', 'store', 'bacon', function (err) {
if (err) return done(err); if (err) return done(err);

View File

@@ -41,8 +41,8 @@ describe("The 'srem' method", function () {
}); });
it('handles a value missing from the set of values being removed', function (done) { it('handles a value missing from the set of values being removed', function (done) {
client.sadd("set0", ["member0", "member1", "member2"], helper.isNumber(3)); client.sadd(["set0", "member0", "member1", "member2"], helper.isNumber(3));
client.SREM("set0", ["member3", "member4"], helper.isNumber(0)); client.SREM(["set0", "member3", "member4"], helper.isNumber(0));
client.smembers("set0", function (err, res) { client.smembers("set0", function (err, res) {
assert.strictEqual(res.length, 3); assert.strictEqual(res.length, 3);
assert.ok(~res.indexOf("member0")); assert.ok(~res.indexOf("member0"));

View File

@@ -35,12 +35,12 @@ describe("The 'type' method", function () {
}); });
it('reports zset type', function (done) { it('reports zset type', function (done) {
client.zadd(["zset key", "10.0", "should be a zset"], helper.isNumber(1)); client.zadd("zset key", ["10.0", "should be a zset"], helper.isNumber(1));
client.TYPE(["zset key"], helper.isString("zset", done)); client.TYPE(["zset key"], helper.isString("zset", done));
}); });
it('reports hash type', function (done) { it('reports hash type', function (done) {
client.hset(["hash key", "hashtest", "should be a hash"], helper.isNumber(1)); client.hset("hash key", "hashtest", "should be a hash", helper.isNumber(1));
client.TYPE(["hash key"], helper.isString("hash", done)); client.TYPE(["hash key"], helper.isString("hash", done));
}); });