1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-04 15:02:09 +03:00

Remove snack_case and always use camelCase

This commit is contained in:
Ruben Bridgewater
2016-12-18 01:46:58 +01:00
committed by Ruben Bridgewater
parent a86c998a64
commit 28afc33c9a
43 changed files with 1048 additions and 1163 deletions

View File

@@ -2,7 +2,7 @@
var fs = require('fs'); var fs = require('fs');
var metrics = require('metrics'); var metrics = require('metrics');
// `node diff_multi_bench_output.js beforeBench.txt afterBench.txt` // `node diffMultiBenchOutput.js beforeBench.txt afterBench.txt`
var file1 = process.argv[2]; var file1 = process.argv[2];
var file2 = process.argv[3]; var file2 = process.argv[3];
@@ -17,13 +17,13 @@ if (!file1 || !file2) {
return; return;
} }
var before_lines = fs.readFileSync(file1, 'utf8').split('\n'); var beforeLines = fs.readFileSync(file1, 'utf8').split('\n');
var after_lines = fs.readFileSync(file2, 'utf8').split('\n'); var afterLines = fs.readFileSync(file2, 'utf8').split('\n');
var total_ops = new metrics.Histogram.createUniformHistogram(); var totalOps = new metrics.Histogram.createUniformHistogram();
console.log('Comparing before,', file1, '(', before_lines.length, 'lines)', 'to after,', file2, '(', after_lines.length, 'lines)'); console.log('Comparing before,', file1, '(', beforeLines.length, 'lines)', 'to after,', file2, '(', afterLines.length, 'lines)');
function is_whitespace (s) { function isWhitespace (s) {
return !!s.trim(); return !!s.trim();
} }
@@ -44,7 +44,7 @@ function pad (input, len, chr, right) {
} }
// green if greater than 0, red otherwise // green if greater than 0, red otherwise
function humanize_diff (num, unit, toFixed) { function humanizeDiff (num, unit, toFixed) {
unit = unit || ''; unit = unit || '';
if (num > 0) { if (num > 0) {
return ' +' + pad(num.toFixed(toFixed || 0) + unit, 7); return ' +' + pad(num.toFixed(toFixed || 0) + unit, 7);
@@ -52,21 +52,21 @@ function humanize_diff (num, unit, toFixed) {
return ' -' + pad(Math.abs(num).toFixed(toFixed || 0) + unit, 7); return ' -' + pad(Math.abs(num).toFixed(toFixed || 0) + unit, 7);
} }
function command_name (words) { function commandName (words) {
var line = words.join(' '); var line = words.join(' ');
return line.substr(0, line.indexOf(',')); return line.substr(0, line.indexOf(','));
} }
before_lines.forEach(function (b, i) { beforeLines.forEach(function (b, i) {
var a = after_lines[i]; var a = afterLines[i];
if (!a || !b || !b.trim() || !a.trim()) { if (!a || !b || !b.trim() || !a.trim()) {
// console.log('#ignored#', '>'+a+'<', '>'+b+'<'); // console.log('#ignored#', '>'+a+'<', '>'+b+'<');
return; return;
} }
var b_words = b.split(' ').filter(is_whitespace); var bWords = b.split(' ').filter(isWhitespace);
var a_words = a.split(' ').filter(is_whitespace); var aWords = a.split(' ').filter(isWhitespace);
var ops = [b_words, a_words].map(function (words) { var ops = [bWords, aWords].map(function (words) {
// console.log(words); // console.log(words);
return words.slice(-2, -1) | 0; return words.slice(-2, -1) | 0;
}).filter(function (num) { }).filter(function (num) {
@@ -80,16 +80,16 @@ before_lines.forEach(function (b, i) {
var pct = +((delta / ops[0]) * 100); var pct = +((delta / ops[0]) * 100);
ops[0] = pad(ops[0], 6); ops[0] = pad(ops[0], 6);
ops[1] = pad(ops[1], 6); ops[1] = pad(ops[1], 6);
total_ops.update(delta); totalOps.update(delta);
delta = humanize_diff(delta); delta = humanizeDiff(delta);
var small_delta = pct < 3 && pct > -3; var smallDelta = pct < 3 && pct > -3;
// Let's mark differences above 20% bold // Let's mark differences above 20% bold
var big_delta = pct > 20 || pct < -20 ? ';1' : ''; var bigDelta = pct > 20 || pct < -20 ? ';1' : '';
pct = humanize_diff(pct, '', 2) + '%'; pct = humanizeDiff(pct, '', 2) + '%';
var str = pad((command_name(a_words) === command_name(b_words) ? command_name(a_words) + ':' : '404:'), 14, false, true) + var str = pad((commandName(aWords) === commandName(bWords) ? commandName(aWords) + ':' : '404:'), 14, false, true) +
(pad(ops.join(' -> '), 15) + ' ops/sec (∆' + delta + pct + ')'); (pad(ops.join(' -> '), 15) + ' ops/sec (∆' + delta + pct + ')');
str = (small_delta ? '' : (/-[^>]/.test(str) ? '\x1b[31' : '\x1b[32') + big_delta + 'm') + str + '\x1b[0m'; str = (smallDelta ? '' : (/-[^>]/.test(str) ? '\x1b[31' : '\x1b[32') + bigDelta + 'm') + str + '\x1b[0m';
console.log(str); console.log(str);
}); });
console.log('Mean difference in ops/sec:', humanize_diff(total_ops.mean(), '', 1)); console.log('Mean difference in ops/sec:', humanizeDiff(totalOps.mean(), '', 1));

View File

@@ -3,7 +3,7 @@
var path = require('path'); var path = require('path');
var RedisProcess = require('../test/lib/redis-process'); var RedisProcess = require('../test/lib/redis-process');
var rp; var rp;
var client_nr = 0; var clientNr = 0;
var redis = require('../index'); var redis = require('../index');
var totalTime = 0; var totalTime = 0;
var metrics = require('metrics'); var metrics = require('metrics');
@@ -21,14 +21,14 @@ function returnArg (name, def) {
} }
return def; return def;
} }
var num_clients = returnArg('clients', 1); var numClients = returnArg('clients', 1);
var run_time = returnArg('time', 2500); // ms var runTime = returnArg('time', 2500); // ms
var pipeline = returnArg('pipeline', 1); // number of concurrent commands var pipeline = returnArg('pipeline', 1); // number of concurrent commands
var versions_logged = false; var versionsLogged = false;
var client_options = { var clientOptions = {
path: returnArg('socket') // '/tmp/redis.sock' path: returnArg('socket') // '/tmp/redis.sock'
}; };
var small_str, large_str, small_buf, large_buf, very_large_str, very_large_buf, mget_array; var smallStr, largeStr, smallBuf, largeBuf, veryLargeStr, veryLargeBuf, mgetArray;
function lpad (input, len, chr) { function lpad (input, len, chr) {
var str = input.toString(); var str = input.toString();
@@ -39,7 +39,7 @@ function lpad (input, len, chr) {
return str; return str;
} }
metrics.Histogram.prototype.print_line = function () { metrics.Histogram.prototype.printLine = function () {
var obj = this.printObj(); var obj = this.printObj();
return lpad((obj.mean / 1e6).toFixed(2), 6) + '/' + lpad((obj.max / 1e6).toFixed(2), 6); return lpad((obj.mean / 1e6).toFixed(2), 6) + '/' + lpad((obj.max / 1e6).toFixed(2), 6);
}; };
@@ -49,58 +49,58 @@ function Test (args) {
this.args.pipeline = +pipeline; this.args.pipeline = +pipeline;
this.callback = null; this.callback = null;
this.clients = []; this.clients = [];
this.clients_ready = 0; this.clientsReady = 0;
this.commands_sent = 0; this.commandsSent = 0;
this.commands_completed = 0; this.commandsCompleted = 0;
this.max_pipeline = +pipeline; this.maxPipeline = +pipeline;
this.batch_pipeline = this.args.batch || 0; this.batchPipeline = this.args.batch || 0;
this.client_options = args.client_options || {}; this.clientOptions = args.clientOptions || {};
this.client_options.connect_timeout = 1000; this.clientOptions.connectTimeout = 1000;
if (client_options.path) { if (clientOptions.path) {
this.client_options.path = client_options.path; this.clientOptions.path = clientOptions.path;
} }
this.connect_latency = new metrics.Histogram(); this.connectLatency = new metrics.Histogram();
this.ready_latency = new metrics.Histogram(); this.readyLatency = new metrics.Histogram();
this.command_latency = new metrics.Histogram(); this.commandLatency = new metrics.Histogram();
} }
Test.prototype.run = function (callback) { Test.prototype.run = function (callback) {
var i; var i;
this.callback = callback; this.callback = callback;
for (i = 0; i < num_clients ; i++) { for (i = 0; i < numClients ; i++) {
this.new_client(i); this.newClient(i);
} }
}; };
Test.prototype.new_client = function (id) { Test.prototype.newClient = function (id) {
var self = this, new_client; var self = this, newClient;
new_client = redis.createClient(this.client_options); newClient = redis.createClient(this.clientOptions);
new_client.create_time = Date.now(); newClient.createTime = Date.now();
new_client.on('connect', function () { newClient.on('connect', function () {
self.connect_latency.update(Date.now() - new_client.create_time); self.connectLatency.update(Date.now() - newClient.createTime);
}); });
new_client.on('ready', function () { newClient.on('ready', function () {
if (!versions_logged) { if (!versionsLogged) {
console.log( console.log(
'clients: ' + num_clients + 'clients: ' + numClients +
', NodeJS: ' + process.versions.node + ', NodeJS: ' + process.versions.node +
', Redis: ' + new_client.server_info.redis_version + ', Redis: ' + newClient.serverInfo.redis_version +
', connected by: ' + (client_options.path ? 'socket' : 'tcp') ', connected by: ' + (clientOptions.path ? 'socket' : 'tcp')
); );
versions_logged = true; versionsLogged = true;
} }
self.ready_latency.update(Date.now() - new_client.create_time); self.readyLatency.update(Date.now() - newClient.createTime);
self.clients_ready++; self.clientsReady++;
if (self.clients_ready === self.clients.length) { if (self.clientsReady === self.clients.length) {
self.on_clients_ready(); self.onClientsReady();
} }
}); });
// If no redis server is running, start one // If no redis server is running, start one
new_client.on('error', function (err) { newClient.on('error', function (err) {
if (err.code === 'CONNECTION_BROKEN') { if (err.code === 'CONNECTION_BROKEN') {
throw err; throw err;
} }
@@ -109,56 +109,56 @@ Test.prototype.new_client = function (id) {
} }
rp = true; rp = true;
var conf = '../test/conf/redis.conf'; var conf = '../test/conf/redis.conf';
RedisProcess.start(function (err, _rp) { RedisProcess.start(function (err, Rp) {
if (err) { if (err) {
throw err; throw err;
} }
rp = _rp; rp = Rp;
}, path.resolve(__dirname, conf)); }, path.resolve(__dirname, conf));
}); });
self.clients[id] = new_client; self.clients[id] = newClient;
}; };
Test.prototype.on_clients_ready = function () { Test.prototype.onClientsReady = function () {
process.stdout.write(lpad(this.args.descr, 13) + ', ' + (this.args.batch ? lpad('batch ' + this.args.batch, 9) : lpad(this.args.pipeline, 9)) + '/' + this.clients_ready + ' '); process.stdout.write(lpad(this.args.descr, 13) + ', ' + (this.args.batch ? lpad('batch ' + this.args.batch, 9) : lpad(this.args.pipeline, 9)) + '/' + this.clientsReady + ' ');
this.test_start = Date.now(); this.testStart = Date.now();
this.fill_pipeline(); this.fillPipeline();
}; };
Test.prototype.fill_pipeline = function () { Test.prototype.fillPipeline = function () {
var pipeline = this.commands_sent - this.commands_completed; var pipeline = this.commandsSent - this.commandsCompleted;
if (this.test_start < Date.now() - run_time) { if (this.testStart < Date.now() - runTime) {
if (this.ended) { if (this.ended) {
return; return;
} }
this.ended = true; this.ended = true;
this.print_stats(); this.printStats();
this.stop_clients(); this.stopClients();
return; return;
} }
if (this.batch_pipeline) { if (this.batchPipeline) {
this.batch(); this.batch();
} else { } else {
while (pipeline < this.max_pipeline) { while (pipeline < this.maxPipeline) {
this.commands_sent++; this.commandsSent++;
pipeline++; pipeline++;
this.send_next(); this.sendNext();
} }
} }
}; };
Test.prototype.batch = function () { Test.prototype.batch = function () {
var self = this, var self = this,
cur_client = client_nr++ % this.clients.length, curClient = clientNr++ % this.clients.length,
start = process.hrtime(), start = process.hrtime(),
i = 0, i = 0,
batch = this.clients[cur_client].batch(); batch = this.clients[curClient].batch();
while (i++ < this.batch_pipeline) { while (i++ < this.batchPipeline) {
this.commands_sent++; this.commandsSent++;
batch[this.args.command](this.args.args); batch[this.args.command](this.args.args);
} }
@@ -166,13 +166,13 @@ Test.prototype.batch = function () {
if (err) { if (err) {
throw err; throw err;
} }
self.commands_completed += res.length; self.commandsCompleted += res.length;
self.command_latency.update(process.hrtime(start)[1]); self.commandLatency.update(process.hrtime(start)[1]);
self.fill_pipeline(); self.fillPipeline();
}); });
}; };
Test.prototype.stop_clients = function () { Test.prototype.stopClients = function () {
var self = this; var self = this;
this.clients.forEach(function (client, pos) { this.clients.forEach(function (client, pos) {
@@ -186,69 +186,69 @@ Test.prototype.stop_clients = function () {
}); });
}; };
Test.prototype.send_next = function () { Test.prototype.sendNext = function () {
var self = this, var self = this,
cur_client = this.commands_sent % this.clients.length, curClient = this.commandsSent % this.clients.length,
start = process.hrtime(); start = process.hrtime();
this.clients[cur_client][this.args.command](this.args.args, function (err, res) { this.clients[curClient][this.args.command](this.args.args, function (err, res) {
if (err) { if (err) {
throw err; throw err;
} }
self.commands_completed++; self.commandsCompleted++;
self.command_latency.update(process.hrtime(start)[1]); self.commandLatency.update(process.hrtime(start)[1]);
self.fill_pipeline(); self.fillPipeline();
}); });
}; };
Test.prototype.print_stats = function () { Test.prototype.printStats = function () {
var duration = Date.now() - this.test_start; var duration = Date.now() - this.testStart;
totalTime += duration; totalTime += duration;
console.log('avg/max: ' + this.command_latency.print_line() + lpad(duration, 5) + 'ms total, ' + console.log('avg/max: ' + this.commandLatency.printLine() + lpad(duration, 5) + 'ms total, ' +
lpad(Math.round(this.commands_completed / (duration / 1000)), 7) + ' ops/sec'); lpad(Math.round(this.commandsCompleted / (duration / 1000)), 7) + ' ops/sec');
}; };
small_str = '1234'; smallStr = '1234';
small_buf = new Buffer(small_str); smallBuf = new Buffer(smallStr);
large_str = (new Array(4096 + 1).join('-')); largeStr = (new Array(4096 + 1).join('-'));
large_buf = new Buffer(large_str); largeBuf = new Buffer(largeStr);
very_large_str = (new Array((4 * 1024 * 1024) + 1).join('-')); veryLargeStr = (new Array((4 * 1024 * 1024) + 1).join('-'));
very_large_buf = new Buffer(very_large_str); veryLargeBuf = new Buffer(veryLargeStr);
mget_array = (new Array(1025)).join('foo_rand000000000001;').split(';'); mgetArray = (new Array(1025)).join('fooRand000000000001;').split(';');
tests.push(new Test({descr: 'PING', command: 'ping', args: []})); tests.push(new Test({descr: 'PING', command: 'ping', args: []}));
tests.push(new Test({descr: 'PING', command: 'ping', args: [], batch: 50})); tests.push(new Test({descr: 'PING', command: 'ping', args: [], batch: 50}));
tests.push(new Test({descr: 'SET 4B str', command: 'set', args: ['foo_rand000000000000', small_str]})); tests.push(new Test({descr: 'SET 4B str', command: 'set', args: ['fooRand000000000000', smallStr]}));
tests.push(new Test({descr: 'SET 4B str', command: 'set', args: ['foo_rand000000000000', small_str], batch: 50})); tests.push(new Test({descr: 'SET 4B str', command: 'set', args: ['fooRand000000000000', smallStr], batch: 50}));
tests.push(new Test({descr: 'SET 4B buf', command: 'set', args: ['foo_rand000000000000', small_buf]})); tests.push(new Test({descr: 'SET 4B buf', command: 'set', args: ['fooRand000000000000', smallBuf]}));
tests.push(new Test({descr: 'SET 4B buf', command: 'set', args: ['foo_rand000000000000', small_buf], batch: 50})); tests.push(new Test({descr: 'SET 4B buf', command: 'set', args: ['fooRand000000000000', smallBuf], batch: 50}));
tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['foo_rand000000000000']})); tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['fooRand000000000000']}));
tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['foo_rand000000000000'], batch: 50})); tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['fooRand000000000000'], batch: 50}));
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['foo_rand000000000000'], client_options: { return_buffers: true} })); tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['fooRand000000000000'], clientOptions: { returnBuffers: true} }));
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['foo_rand000000000000'], batch: 50, client_options: { return_buffers: true} })); tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['fooRand000000000000'], batch: 50, clientOptions: { returnBuffers: true} }));
tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['foo_rand000000000001', large_str]})); tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['fooRand000000000001', largeStr]}));
tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['foo_rand000000000001', large_str], batch: 50})); tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['fooRand000000000001', largeStr], batch: 50}));
tests.push(new Test({descr: 'SET 4KiB buf', command: 'set', args: ['foo_rand000000000001', large_buf]})); tests.push(new Test({descr: 'SET 4KiB buf', command: 'set', args: ['fooRand000000000001', largeBuf]}));
tests.push(new Test({descr: 'SET 4KiB buf', command: 'set', args: ['foo_rand000000000001', large_buf], batch: 50})); tests.push(new Test({descr: 'SET 4KiB buf', command: 'set', args: ['fooRand000000000001', largeBuf], batch: 50}));
tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['foo_rand000000000001']})); tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['fooRand000000000001']}));
tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['foo_rand000000000001'], batch: 50})); tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['fooRand000000000001'], batch: 50}));
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['foo_rand000000000001'], client_options: { return_buffers: true} })); tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['fooRand000000000001'], clientOptions: { returnBuffers: true} }));
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['foo_rand000000000001'], batch: 50, client_options: { return_buffers: true} })); tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['fooRand000000000001'], batch: 50, clientOptions: { returnBuffers: true} }));
tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counter_rand000000000000']})); tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counterRand000000000000']}));
tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counter_rand000000000000'], batch: 50})); tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counterRand000000000000'], batch: 50}));
tests.push(new Test({descr: 'LPUSH', command: 'lpush', args: ['mylist', small_str]})); tests.push(new Test({descr: 'LPUSH', command: 'lpush', args: ['mylist', smallStr]}));
tests.push(new Test({descr: 'LPUSH', command: 'lpush', args: ['mylist', small_str], batch: 50})); tests.push(new Test({descr: 'LPUSH', command: 'lpush', args: ['mylist', smallStr], batch: 50}));
tests.push(new Test({descr: 'LRANGE 10', command: 'lrange', args: ['mylist', '0', '9']})); tests.push(new Test({descr: 'LRANGE 10', command: 'lrange', args: ['mylist', '0', '9']}));
tests.push(new Test({descr: 'LRANGE 10', command: 'lrange', args: ['mylist', '0', '9'], batch: 50})); tests.push(new Test({descr: 'LRANGE 10', command: 'lrange', args: ['mylist', '0', '9'], batch: 50}));
@@ -256,23 +256,23 @@ tests.push(new Test({descr: 'LRANGE 10', command: 'lrange', args: ['mylist', '0'
tests.push(new Test({descr: 'LRANGE 100', command: 'lrange', args: ['mylist', '0', '99']})); tests.push(new Test({descr: 'LRANGE 100', command: 'lrange', args: ['mylist', '0', '99']}));
tests.push(new Test({descr: 'LRANGE 100', command: 'lrange', args: ['mylist', '0', '99'], batch: 50})); tests.push(new Test({descr: 'LRANGE 100', command: 'lrange', args: ['mylist', '0', '99'], batch: 50}));
tests.push(new Test({descr: 'SET 4MiB str', command: 'set', args: ['foo_rand000000000002', very_large_str]})); tests.push(new Test({descr: 'SET 4MiB str', command: 'set', args: ['fooRand000000000002', veryLargeStr]}));
tests.push(new Test({descr: 'SET 4MiB str', command: 'set', args: ['foo_rand000000000002', very_large_str], batch: 20})); tests.push(new Test({descr: 'SET 4MiB str', command: 'set', args: ['fooRand000000000002', veryLargeStr], batch: 20}));
tests.push(new Test({descr: 'SET 4MiB buf', command: 'set', args: ['foo_rand000000000002', very_large_buf]})); tests.push(new Test({descr: 'SET 4MiB buf', command: 'set', args: ['fooRand000000000002', veryLargeBuf]}));
tests.push(new Test({descr: 'SET 4MiB buf', command: 'set', args: ['foo_rand000000000002', very_large_buf], batch: 20})); tests.push(new Test({descr: 'SET 4MiB buf', command: 'set', args: ['fooRand000000000002', veryLargeBuf], batch: 20}));
tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['foo_rand000000000002']})); tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['fooRand000000000002']}));
tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['foo_rand000000000002'], batch: 20})); tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['fooRand000000000002'], batch: 20}));
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['foo_rand000000000002'], client_options: { return_buffers: true} })); tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['fooRand000000000002'], clientOptions: { returnBuffers: true} }));
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['foo_rand000000000002'], batch: 20, client_options: { return_buffers: true} })); tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['fooRand000000000002'], batch: 20, clientOptions: { returnBuffers: true} }));
tests.push(new Test({descr: 'MGET 4MiB str', command: 'mget', args: mget_array})); tests.push(new Test({descr: 'MGET 4MiB str', command: 'mget', args: mgetArray}));
tests.push(new Test({descr: 'MGET 4MiB str', command: 'mget', args: mget_array, batch: 20})); tests.push(new Test({descr: 'MGET 4MiB str', command: 'mget', args: mgetArray, batch: 20}));
tests.push(new Test({descr: 'MGET 4MiB buf', command: 'mget', args: mget_array, client_options: { return_buffers: true} })); tests.push(new Test({descr: 'MGET 4MiB buf', command: 'mget', args: mgetArray, clientOptions: { returnBuffers: true} }));
tests.push(new Test({descr: 'MGET 4MiB buf', command: 'mget', args: mget_array, batch: 20, client_options: { return_buffers: true} })); tests.push(new Test({descr: 'MGET 4MiB buf', command: 'mget', args: mgetArray, batch: 20, clientOptions: { returnBuffers: true} }));
function next () { function next () {
var test = tests.shift(); var test = tests.shift();

View File

@@ -6,7 +6,7 @@ var client = redis.createClient();
// Extend the RedisClient prototype to add a custom method // Extend the RedisClient prototype to add a custom method
// This one converts the results from 'INFO' into a JavaScript Object // This one converts the results from 'INFO' into a JavaScript Object
redis.RedisClient.prototype.parse_info = function (callback) { redis.RedisClient.prototype.parseInfo = function (callback) {
this.info(function (err, res) { this.info(function (err, res) {
var lines = res.toString().split('\r\n').sort(); var lines = res.toString().split('\r\n').sort();
var obj = {}; var obj = {};
@@ -20,7 +20,7 @@ redis.RedisClient.prototype.parse_info = function (callback) {
}); });
}; };
client.parse_info(function (info) { client.parseInfo(function (info) {
console.dir(info); console.dir(info);
client.quit(); client.quit();
}); });

View File

@@ -4,7 +4,7 @@
var redis = require('redis'); var redis = require('redis');
var client = redis.createClient({ var client = redis.createClient({
return_buffers: true returnBuffers: true
}); });
var fs = require('fs'); var fs = require('fs');
var assert = require('assert'); var assert = require('assert');

View File

@@ -2,14 +2,14 @@
var redis = require('redis'); var redis = require('redis');
var client = redis.createClient(); var client = redis.createClient();
var set_size = 20; var setSize = 20;
client.sadd('bigset', 'a member'); client.sadd('bigset', 'a member');
client.sadd('bigset', 'another member'); client.sadd('bigset', 'another member');
while (set_size > 0) { while (setSize > 0) {
client.sadd('bigset', 'member ' + set_size); client.sadd('bigset', 'member ' + setSize);
set_size -= 1; setSize -= 1;
} }
// multi chain with an individual callback // multi chain with an individual callback

View File

@@ -5,7 +5,7 @@ var client1 = redis.createClient();
var client2 = redis.createClient(); var client2 = redis.createClient();
var client3 = redis.createClient(); var client3 = redis.createClient();
var client4 = redis.createClient(); var client4 = redis.createClient();
var msg_count = 0; var msgCount = 0;
client1.on('psubscribe', function (pattern, count) { client1.on('psubscribe', function (pattern, count) {
console.log('client1 psubscribed to ' + pattern + ', ' + count + ' total subscriptions'); console.log('client1 psubscribed to ' + pattern + ', ' + count + ' total subscriptions');
@@ -24,8 +24,8 @@ client1.on('punsubscribe', function (pattern, count) {
client1.on('pmessage', function (pattern, channel, message) { client1.on('pmessage', function (pattern, channel, message) {
console.log('(' + pattern + ') client1 received message on ' + channel + ': ' + message); console.log('(' + pattern + ') client1 received message on ' + channel + ': ' + message);
msg_count += 1; msgCount += 1;
if (msg_count === 3) { if (msgCount === 3) {
client1.punsubscribe(); client1.punsubscribe();
} }
}); });

View File

@@ -2,7 +2,7 @@
var redis = require('redis'); var redis = require('redis');
var client1 = redis.createClient(); var client1 = redis.createClient();
var msg_count = 0; var msgCount = 0;
var client2 = redis.createClient(); var client2 = redis.createClient();
// Most clients probably don't do much on 'subscribe'. This example uses it to coordinate things within one program. // Most clients probably don't do much on 'subscribe'. This example uses it to coordinate things within one program.
@@ -25,8 +25,8 @@ client1.on('unsubscribe', function (channel, count) {
client1.on('message', function (channel, message) { client1.on('message', function (channel, message) {
console.log('client1 channel ' + channel + ': ' + message); console.log('client1 channel ' + channel + ': ' + message);
msg_count += 1; msgCount += 1;
if (msg_count === 3) { if (msgCount === 3) {
client1.unsubscribe(); client1.unsubscribe();
} }
}); });

View File

@@ -3,14 +3,14 @@
var client = require('redis').createClient(); var client = require('redis').createClient();
// build a map of all keys and their types // build a map of all keys and their types
client.keys('*', function (err, all_keys) { client.keys('*', function (err, allKeys) {
var key_types = {}; var keyTypes = {};
all_keys.forEach(function (key, pos) { // use second arg of forEach to get pos allKeys.forEach(function (key, pos) { // use second arg of forEach to get pos
client.type(key, function (err, type) { client.type(key, function (err, type) {
key_types[key] = type; keyTypes[key] = type;
if (pos === all_keys.length - 1) { // callbacks all run in order if (pos === allKeys.length - 1) { // callbacks all run in order
console.dir(key_types); console.dir(keyTypes);
} }
}); });
}); });

View File

@@ -3,27 +3,27 @@
// A simple web server that generates dyanmic content based on responses from Redis // A simple web server that generates dyanmic content based on responses from Redis
var http = require('http'); var http = require('http');
var redis_client = require('redis').createClient(); var redisClient = require('redis').createClient();
http.createServer(function (request, response) { // The server http.createServer(function (request, response) { // The server
response.writeHead(200, { response.writeHead(200, {
'Content-Type': 'text/plain' 'Content-Type': 'text/plain'
}); });
var redis_info, total_requests; var redisInfo, totalRequests;
redis_client.info(function (err, reply) { redisClient.info(function (err, reply) {
redis_info = reply; // stash response in outer scope redisInfo = reply; // stash response in outer scope
}); });
redis_client.incr('requests', function (err, reply) { redisClient.incr('requests', function (err, reply) {
total_requests = reply; // stash response in outer scope totalRequests = reply; // stash response in outer scope
}); });
redis_client.hincrby('ip', request.connection.remoteAddress, 1); redisClient.hincrby('ip', request.connection.remoteAddress, 1);
redis_client.hgetall('ip', function (err, reply) { redisClient.hgetall('ip', function (err, reply) {
// This is the last reply, so all of the previous replies must have completed already // This is the last reply, so all of the previous replies must have completed already
response.write('This page was generated after talking to redis.\n\n' + response.write('This page was generated after talking to redis.\n\n' +
'Redis info:\n' + redis_info + '\n' + 'Redis info:\n' + redisInfo + '\n' +
'Total requests: ' + total_requests + '\n\n' + 'Total requests: ' + totalRequests + '\n\n' +
'IP count: \n'); 'IP count: \n');
Object.keys(reply).forEach(function (ip) { Object.keys(reply).forEach(function (ip) {
response.write(' ' + ip + ': ' + reply[ip] + '\n'); response.write(' ' + ip + ': ' + reply[ip] + '\n');

721
index.js

File diff suppressed because it is too large Load Diff

View File

@@ -2,12 +2,12 @@
var betterStackTraces = /development/i.test(process.env.NODE_ENV) || /\bredis\b/i.test(process.env.NODE_DEBUG); var betterStackTraces = /development/i.test(process.env.NODE_ENV) || /\bredis\b/i.test(process.env.NODE_DEBUG);
function Command (command, args, callback, call_on_write) { function Command (command, args, callback, callOnWrite) {
this.command = command; this.command = command;
this.args = args; this.args = args;
this.buffer_args = false; this.bufferArgs = false;
this.callback = callback; this.callback = callback;
this.call_on_write = call_on_write; this.callOnWrite = callOnWrite;
if (betterStackTraces) { if (betterStackTraces) {
this.error = new Error(); this.error = new Error();
} }

View File

@@ -59,7 +59,7 @@ commands.list.forEach(function (command) {
arr[i] = arguments[i]; arr[i] = arguments[i];
} }
} }
return this.internal_send_command(new Command(command, arr, callback)); return this.internalSendCommand(new Command(command, arr, callback));
}; };
if (changeFunctionName) { if (changeFunctionName) {
Object.defineProperty(RedisClient.prototype[command], 'name', { Object.defineProperty(RedisClient.prototype[command], 'name', {

View File

@@ -3,27 +3,28 @@
var utils = require('./utils'); var utils = require('./utils');
var URL = require('url'); var URL = require('url');
module.exports = function createClient (port_arg, host_arg, options) { module.exports = function createClient (portArg, hostArg, options) {
if (typeof port_arg === 'number' || typeof port_arg === 'string' && /^\d+$/.test(port_arg)) { if (typeof portArg === 'number' || typeof portArg === 'string' && /^\d+$/.test(portArg)) {
var host; var host;
if (typeof host_arg === 'string') { if (typeof hostArg === 'string') {
host = host_arg; host = hostArg;
} else { } else {
if (options && host_arg) { if (options && hostArg) {
throw new TypeError('Unknown type of connection in createClient()'); throw new TypeError('Unknown type of connection in createClient()');
} }
options = options || host_arg; options = options || hostArg;
} }
options = utils.clone(options); options = utils.clone(options);
options.host = host || options.host; options.host = host || options.host;
options.port = port_arg; options.port = portArg;
} else if (typeof port_arg === 'string' || port_arg && port_arg.url) { } else if (typeof portArg === 'string' || portArg && portArg.url) {
options = utils.clone(port_arg.url ? port_arg : host_arg || options); options = utils.clone(portArg.url ? portArg : hostArg || options);
var parsed = URL.parse(port_arg.url || port_arg, true, true);
var parsed = URL.parse(portArg.url || portArg, true, true);
// [redis:]//[[user][:password]@][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]] // [redis:]//[[user][:password]@][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]
if (parsed.slashes) { // We require slashes if (parsed.slashes) { // We require slashes
@@ -31,7 +32,7 @@ module.exports = function createClient (port_arg, host_arg, options) {
options.password = parsed.auth.split(':')[1]; options.password = parsed.auth.split(':')[1];
} }
if (parsed.protocol && parsed.protocol !== 'redis:') { if (parsed.protocol && parsed.protocol !== 'redis:') {
console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!'); console.warn('nodeRedis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!');
} }
if (parsed.pathname && parsed.pathname !== '/') { if (parsed.pathname && parsed.pathname !== '/') {
options.db = parsed.pathname.substr(1); options.db = parsed.pathname.substr(1);
@@ -48,7 +49,7 @@ module.exports = function createClient (port_arg, host_arg, options) {
// If options are passed twice, only the parsed options will be used // If options are passed twice, only the parsed options will be used
if (elem in options) { if (elem in options) {
if (options[elem] === parsed.query[elem]) { if (options[elem] === parsed.query[elem]) {
console.warn('node_redis: WARNING: You passed the ' + elem + ' option twice!'); console.warn('nodeRedis: WARNING: You passed the ' + elem + ' option twice!');
} else { } else {
throw new RangeError('The ' + elem + ' option is added twice and does not match'); throw new RangeError('The ' + elem + ' option is added twice and does not match');
} }
@@ -59,14 +60,14 @@ module.exports = function createClient (port_arg, host_arg, options) {
} else if (parsed.hostname) { } else if (parsed.hostname) {
throw new RangeError('The redis url must begin with slashes "//" or contain slashes after the redis protocol'); throw new RangeError('The redis url must begin with slashes "//" or contain slashes after the redis protocol');
} else { } else {
options.path = port_arg; options.path = portArg;
} }
} else if (typeof port_arg === 'object' || port_arg === undefined) { } else if (typeof portArg === 'object' || portArg === undefined) {
options = utils.clone(port_arg || options); options = utils.clone(portArg || options);
options.host = options.host || host_arg; options.host = options.host || hostArg;
if (port_arg && arguments.length !== 1) { if (portArg && arguments.length !== 1) {
throw new TypeError('To many arguments passed to createClient. Please only pass the options object'); throw new TypeError('To many arguments passed to createClient. Please only pass the options object');
} }
} }

View File

@@ -3,7 +3,7 @@
var index = require('../'); var index = require('../');
function debug () { function debug () {
if (index.debug_mode) { if (index.debugMode) {
console.error.apply(null, arguments); console.error.apply(null, arguments);
} }
} }

View File

@@ -11,7 +11,7 @@ All documented and exposed API belongs in here
**********************************************/ **********************************************/
// Redirect calls to the appropriate function and use to send arbitrary / not supported commands // Redirect calls to the appropriate function and use to send arbitrary / not supported commands
RedisClient.prototype.send_command = RedisClient.prototype.sendCommand = function (command, args, callback) { RedisClient.prototype.sendCommand = function (command, args, callback) {
// Throw to fail early instead of relying in order in this case // Throw to fail early instead of relying in order in this case
if (typeof command !== 'string') { if (typeof command !== 'string') {
throw new TypeError('Wrong input type "' + (command !== null && command !== undefined ? command.constructor.name : command) + '" for command name'); throw new TypeError('Wrong input type "' + (command !== null && command !== undefined ? command.constructor.name : command) + '" for command name');
@@ -37,7 +37,7 @@ RedisClient.prototype.send_command = RedisClient.prototype.sendCommand = functio
// but this might change from time to time and at the moment there's no good way to distinguishe them // but this might change from time to time and at the moment there's no good way to distinguishe them
// from each other, so let's just do it do it this way for the time being // from each other, so let's just do it do it this way for the time being
if (command === 'multi' || typeof this[command] !== 'function') { if (command === 'multi' || typeof this[command] !== 'function') {
return this.internal_send_command(new Command(command, args, callback)); return this.internalSendCommand(new Command(command, args, callback));
} }
if (typeof callback === 'function') { if (typeof callback === 'function') {
args = args.concat([callback]); // Prevent manipulating the input array args = args.concat([callback]); // Prevent manipulating the input array
@@ -48,20 +48,20 @@ RedisClient.prototype.send_command = RedisClient.prototype.sendCommand = functio
RedisClient.prototype.end = function (flush) { RedisClient.prototype.end = function (flush) {
// Flush queue if wanted // Flush queue if wanted
if (flush) { if (flush) {
this.flush_and_error({ this.flushAndError({
message: 'Connection forcefully ended and command aborted.', message: 'Connection forcefully ended and command aborted.',
code: 'NR_CLOSED' code: 'NR_CLOSED'
}); });
} else if (arguments.length === 0) { } else if (arguments.length === 0) {
this.warn( this.warn(
'Using .end() without the flush parameter is deprecated and throws from v.3.0.0 on.\n' + 'Using .end() without the flush parameter is deprecated and throws from v.3.0.0 on.\n' +
'Please check the doku (https://github.com/NodeRedis/node_redis) and explictly use flush.' 'Please check the doku (https://github.com/NodeRedis/nodeRedis) and explictly use flush.'
); );
} }
// Clear retry_timer // Clear retryTimer
if (this.retry_timer) { if (this.retryTimer) {
clearTimeout(this.retry_timer); clearTimeout(this.retryTimer);
this.retry_timer = null; this.retryTimer = null;
} }
this.stream.removeAllListeners(); this.stream.removeAllListeners();
this.stream.on('error', noop); this.stream.on('error', noop);
@@ -88,24 +88,24 @@ RedisClient.prototype.duplicate = function (options, callback) {
callback = options; callback = options;
options = null; options = null;
} }
var existing_options = utils.clone(this.options); var existingOptions = utils.clone(this.options);
options = utils.clone(options); options = utils.clone(options);
for (var elem in options) { for (var elem in options) {
existing_options[elem] = options[elem]; existingOptions[elem] = options[elem];
} }
var client = new RedisClient(existing_options); var client = new RedisClient(existingOptions);
client.selected_db = this.selected_db; client.selectedDb = this.selectedDb;
if (typeof callback === 'function') { if (typeof callback === 'function') {
var ready_listener = function () { var readyListener = function () {
callback(null, client); callback(null, client);
client.removeAllListeners(error_listener); client.removeAllListeners(errorListener);
}; };
var error_listener = function (err) { var errorListener = function (err) {
callback(err); callback(err);
client.end(true); client.end(true);
}; };
client.once('ready', ready_listener); client.once('ready', readyListener);
client.once('error', error_listener); client.once('error', errorListener);
return; return;
} }
return client; return client;

View File

@@ -4,7 +4,7 @@ var utils = require('./utils');
var debug = require('./debug'); var debug = require('./debug');
var Multi = require('./multi'); var Multi = require('./multi');
var Command = require('./command'); var Command = require('./command');
var no_password_is_set = /no password is set/; var noPasswordIsSet = /no password is set/;
var loading = /LOADING/; var loading = /LOADING/;
var RedisClient = require('../').RedisClient; var RedisClient = require('../').RedisClient;
@@ -14,7 +14,7 @@ var RedisClient = require('../').RedisClient;
The callback may be hooked as needed. The same does not apply to the rest of the function. The callback may be hooked as needed. The same does not apply to the rest of the function.
State should not be set outside of the callback if not absolutly necessary. State should not be set outside of the callback if not absolutly necessary.
This is important to make sure it works the same as single command or in a multi context. This is important to make sure it works the same as single command or in a multi context.
To make sure everything works with the offline queue use the "call_on_write" function. To make sure everything works with the offline queue use the "callOnWrite" function.
This is going to be executed while writing to the stream. This is going to be executed while writing to the stream.
TODO: Implement individal command generation as soon as possible to prevent divergent code TODO: Implement individal command generation as soon as possible to prevent divergent code
@@ -23,7 +23,7 @@ var RedisClient = require('../').RedisClient;
RedisClient.prototype.multi = RedisClient.prototype.MULTI = function multi (args) { RedisClient.prototype.multi = RedisClient.prototype.MULTI = function multi (args) {
var multi = new Multi(this, args); var multi = new Multi(this, args);
multi.exec = multi.EXEC = multi.exec_transaction; multi.exec = multi.EXEC = multi.execTransaction;
return multi; return multi;
}; };
@@ -32,45 +32,45 @@ RedisClient.prototype.batch = RedisClient.prototype.BATCH = function batch (args
return new Multi(this, args); return new Multi(this, args);
}; };
function select_callback (self, db, callback) { function selectCallback (self, db, callback) {
return function (err, res) { return function (err, res) {
if (err === null) { if (err === null) {
// Store db in this.select_db to restore it on reconnect // Store db in this.selectDb to restore it on reconnect
self.selected_db = db; self.selectedDb = db;
} }
utils.callback_or_emit(self, callback, err, res); utils.callbackOrEmit(self, callback, err, res);
}; };
} }
RedisClient.prototype.select = RedisClient.prototype.SELECT = function select (db, callback) { RedisClient.prototype.select = RedisClient.prototype.SELECT = function select (db, callback) {
return this.internal_send_command(new Command('select', [db], select_callback(this, db, callback))); return this.internalSendCommand(new Command('select', [db], selectCallback(this, db, callback)));
}; };
Multi.prototype.select = Multi.prototype.SELECT = function select (db, callback) { Multi.prototype.select = Multi.prototype.SELECT = function select (db, callback) {
this.queue.push(new Command('select', [db], select_callback(this._client, db, callback))); this.queue.push(new Command('select', [db], selectCallback(this._client, db, callback)));
return this; return this;
}; };
RedisClient.prototype.monitor = RedisClient.prototype.MONITOR = function monitor (callback) { RedisClient.prototype.monitor = RedisClient.prototype.MONITOR = function monitor (callback) {
// Use a individual command, as this is a special case that does not has to be checked for any other command // Use a individual command, as this is a special case that does not has to be checked for any other command
var self = this; var self = this;
var call_on_write = function () { var callOnWrite = function () {
// Activating monitor mode has to happen before Redis returned the callback. The monitor result is returned first. // Activating monitor mode has to happen before Redis returned the callback. The monitor result is returned first.
// Therefore we expect the command to be properly processed. If this is not the case, it's not an issue either. // Therefore we expect the command to be properly processed. If this is not the case, it's not an issue either.
self.monitoring = true; self.monitoring = true;
}; };
return this.internal_send_command(new Command('monitor', [], callback, call_on_write)); return this.internalSendCommand(new Command('monitor', [], callback, callOnWrite));
}; };
// Only works with batch, not in a transaction // Only works with batch, not in a transaction
Multi.prototype.monitor = Multi.prototype.MONITOR = function monitor (callback) { Multi.prototype.monitor = Multi.prototype.MONITOR = function monitor (callback) {
// Use a individual command, as this is a special case that does not has to be checked for any other command // Use a individual command, as this is a special case that does not has to be checked for any other command
if (this.exec !== this.exec_transaction) { if (this.exec !== this.execTransaction) {
var self = this; var self = this;
var call_on_write = function () { var callOnWrite = function () {
self._client.monitoring = true; self._client.monitoring = true;
}; };
this.queue.push(new Command('monitor', [], callback, call_on_write)); this.queue.push(new Command('monitor', [], callback, callOnWrite));
return this; return this;
} }
// Set multi monitoring to indicate the exec that it should abort // Set multi monitoring to indicate the exec that it should abort
@@ -79,7 +79,7 @@ Multi.prototype.monitor = Multi.prototype.MONITOR = function monitor (callback)
return this; return this;
}; };
function quit_callback (self, callback) { function quitCallback (self, callback) {
return function (err, res) { return function (err, res) {
if (err && err.code === 'NR_CLOSED') { if (err && err.code === 'NR_CLOSED') {
// Pretent the quit command worked properly in this case. // Pretent the quit command worked properly in this case.
@@ -90,7 +90,7 @@ function quit_callback (self, callback) {
err = null; err = null;
res = 'OK'; res = 'OK';
} }
utils.callback_or_emit(self, callback, err, res); utils.callbackOrEmit(self, callback, err, res);
if (self.stream.writable) { if (self.stream.writable) {
// If the socket is still alive, kill it. This could happen if quit got a NR_CLOSED error code // If the socket is still alive, kill it. This could happen if quit got a NR_CLOSED error code
self.stream.destroy(); self.stream.destroy();
@@ -101,40 +101,40 @@ function quit_callback (self, callback) {
RedisClient.prototype.QUIT = RedisClient.prototype.quit = function quit (callback) { RedisClient.prototype.QUIT = RedisClient.prototype.quit = function quit (callback) {
// TODO: Consider this for v.3 // TODO: Consider this for v.3
// Allow the quit command to be fired as soon as possible to prevent it landing in the offline queue. // Allow the quit command to be fired as soon as possible to prevent it landing in the offline queue.
// this.ready = this.offline_queue.length === 0; // this.ready = this.offlineQueue.length === 0;
var backpressure_indicator = this.internal_send_command(new Command('quit', [], quit_callback(this, callback))); var backpressureIndicator = this.internalSendCommand(new Command('quit', [], quitCallback(this, callback)));
// Calling quit should always end the connection, no matter if there's a connection or not // Calling quit should always end the connection, no matter if there's a connection or not
this.closing = true; this.closing = true;
this.ready = false; this.ready = false;
return backpressure_indicator; return backpressureIndicator;
}; };
// Only works with batch, not in a transaction // Only works with batch, not in a transaction
Multi.prototype.QUIT = Multi.prototype.quit = function quit (callback) { Multi.prototype.QUIT = Multi.prototype.quit = function quit (callback) {
var self = this._client; var self = this._client;
var call_on_write = function () { var callOnWrite = function () {
// If called in a multi context, we expect redis is available // If called in a multi context, we expect redis is available
self.closing = true; self.closing = true;
self.ready = false; self.ready = false;
}; };
this.queue.push(new Command('quit', [], quit_callback(self, callback), call_on_write)); this.queue.push(new Command('quit', [], quitCallback(self, callback), callOnWrite));
return this; return this;
}; };
function info_callback (self, callback) { function infoCallback (self, callback) {
return function (err, res) { return function (err, res) {
if (res) { if (res) {
var obj = {}; var obj = {};
var lines = res.toString().split('\r\n'); var lines = res.toString().split('\r\n');
var line, parts, sub_parts; var line, parts, subParts;
for (var i = 0; i < lines.length; i++) { for (var i = 0; i < lines.length; i++) {
parts = lines[i].split(':'); parts = lines[i].split(':');
if (parts[1]) { if (parts[1]) {
if (parts[0].indexOf('db') === 0) { if (parts[0].indexOf('db') === 0) {
sub_parts = parts[1].split(','); subParts = parts[1].split(',');
obj[parts[0]] = {}; obj[parts[0]] = {};
while (line = sub_parts.pop()) { while (line = subParts.pop()) {
line = line.split('='); line = line.split('=');
obj[parts[0]][line[0]] = +line[1]; obj[parts[0]][line[0]] = +line[1];
} }
@@ -150,15 +150,15 @@ function info_callback (self, callback) {
}); });
} }
// Expose info key/vals to users // Expose info key/vals to users
self.server_info = obj; self.serverInfo = obj;
} else { } else {
self.server_info = {}; self.serverInfo = {};
} }
utils.callback_or_emit(self, callback, err, res); utils.callbackOrEmit(self, callback, err, res);
}; };
} }
// Store info in this.server_info after each call // Store info in this.serverInfo after each call
RedisClient.prototype.info = RedisClient.prototype.INFO = function info (section, callback) { RedisClient.prototype.info = RedisClient.prototype.INFO = function info (section, callback) {
var args = []; var args = [];
if (typeof section === 'function') { if (typeof section === 'function') {
@@ -166,7 +166,7 @@ RedisClient.prototype.info = RedisClient.prototype.INFO = function info (section
} else if (section !== undefined) { } else if (section !== undefined) {
args = Array.isArray(section) ? section : [section]; args = Array.isArray(section) ? section : [section];
} }
return this.internal_send_command(new Command('info', args, info_callback(this, callback))); return this.internalSendCommand(new Command('info', args, infoCallback(this, callback)));
}; };
Multi.prototype.info = Multi.prototype.INFO = function info (section, callback) { Multi.prototype.info = Multi.prototype.INFO = function info (section, callback) {
@@ -176,14 +176,14 @@ Multi.prototype.info = Multi.prototype.INFO = function info (section, callback)
} else if (section !== undefined) { } else if (section !== undefined) {
args = Array.isArray(section) ? section : [section]; args = Array.isArray(section) ? section : [section];
} }
this.queue.push(new Command('info', args, info_callback(this._client, callback))); this.queue.push(new Command('info', args, infoCallback(this._client, callback)));
return this; return this;
}; };
function auth_callback (self, pass, callback) { function authCallback (self, pass, callback) {
return function (err, res) { return function (err, res) {
if (err) { if (err) {
if (no_password_is_set.test(err.message)) { if (noPasswordIsSet.test(err.message)) {
self.warn('Warning: Redis server does not require a password, but a password was supplied.'); self.warn('Warning: Redis server does not require a password, but a password was supplied.');
err = null; err = null;
res = 'OK'; res = 'OK';
@@ -196,29 +196,29 @@ function auth_callback (self, pass, callback) {
return; return;
} }
} }
utils.callback_or_emit(self, callback, err, res); utils.callbackOrEmit(self, callback, err, res);
}; };
} }
RedisClient.prototype.auth = RedisClient.prototype.AUTH = function auth (pass, callback) { RedisClient.prototype.auth = RedisClient.prototype.AUTH = function auth (pass, callback) {
debug('Sending auth to ' + this.address + ' id ' + this.connection_id); debug('Sending auth to ' + this.address + ' id ' + this.connectionId);
// Stash auth for connect and reconnect. // Stash auth for connect and reconnect.
this.auth_pass = pass; this.authPass = pass;
var ready = this.ready; var ready = this.ready;
this.ready = ready || this.offline_queue.length === 0; this.ready = ready || this.offlineQueue.length === 0;
var tmp = this.internal_send_command(new Command('auth', [pass], auth_callback(this, pass, callback))); var tmp = this.internalSendCommand(new Command('auth', [pass], authCallback(this, pass, callback)));
this.ready = ready; this.ready = ready;
return tmp; return tmp;
}; };
// Only works with batch, not in a transaction // Only works with batch, not in a transaction
Multi.prototype.auth = Multi.prototype.AUTH = function auth (pass, callback) { Multi.prototype.auth = Multi.prototype.AUTH = function auth (pass, callback) {
debug('Sending auth to ' + this.address + ' id ' + this.connection_id); debug('Sending auth to ' + this.address + ' id ' + this.connectionId);
// Stash auth for connect and reconnect. // Stash auth for connect and reconnect.
this.auth_pass = pass; this.authPass = pass;
this.queue.push(new Command('auth', [pass], auth_callback(this._client, callback))); this.queue.push(new Command('auth', [pass], authCallback(this._client, callback)));
return this; return this;
}; };
@@ -253,18 +253,18 @@ RedisClient.prototype.client = RedisClient.prototype.CLIENT = function client ()
} }
} }
var self = this; var self = this;
var call_on_write = undefined; var callOnWrite = undefined;
// CLIENT REPLY ON|OFF|SKIP // CLIENT REPLY ON|OFF|SKIP
/* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */ /* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */
if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') { if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') {
var reply_on_off = arr[1].toString().toUpperCase(); var replyOnOff = arr[1].toString().toUpperCase();
if (reply_on_off === 'ON' || reply_on_off === 'OFF' || reply_on_off === 'SKIP') { if (replyOnOff === 'ON' || replyOnOff === 'OFF' || replyOnOff === 'SKIP') {
call_on_write = function () { callOnWrite = function () {
self.reply = reply_on_off; self.reply = replyOnOff;
}; };
} }
} }
return this.internal_send_command(new Command('client', arr, callback, call_on_write)); return this.internalSendCommand(new Command('client', arr, callback, callOnWrite));
}; };
Multi.prototype.client = Multi.prototype.CLIENT = function client () { Multi.prototype.client = Multi.prototype.CLIENT = function client () {
@@ -298,18 +298,18 @@ Multi.prototype.client = Multi.prototype.CLIENT = function client () {
} }
} }
var self = this._client; var self = this._client;
var call_on_write = undefined; var callOnWrite = undefined;
// CLIENT REPLY ON|OFF|SKIP // CLIENT REPLY ON|OFF|SKIP
/* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */ /* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */
if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') { if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') {
var reply_on_off = arr[1].toString().toUpperCase(); var replyOnOff = arr[1].toString().toUpperCase();
if (reply_on_off === 'ON' || reply_on_off === 'OFF' || reply_on_off === 'SKIP') { if (replyOnOff === 'ON' || replyOnOff === 'OFF' || replyOnOff === 'SKIP') {
call_on_write = function () { callOnWrite = function () {
self.reply = reply_on_off; self.reply = replyOnOff;
}; };
} }
} }
this.queue.push(new Command('client', arr, callback, call_on_write)); this.queue.push(new Command('client', arr, callback, callOnWrite));
return this; return this;
}; };
@@ -349,7 +349,7 @@ RedisClient.prototype.hmset = RedisClient.prototype.HMSET = function hmset () {
arr[i] = arguments[i]; arr[i] = arguments[i];
} }
} }
return this.internal_send_command(new Command('hmset', arr, callback)); return this.internalSendCommand(new Command('hmset', arr, callback));
}; };
Multi.prototype.hmset = Multi.prototype.HMSET = function hmset () { Multi.prototype.hmset = Multi.prototype.HMSET = function hmset () {
@@ -413,10 +413,10 @@ RedisClient.prototype.subscribe = RedisClient.prototype.SUBSCRIBE = function sub
} }
} }
var self = this; var self = this;
var call_on_write = function () { var callOnWrite = function () {
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
}; };
return this.internal_send_command(new Command('subscribe', arr, callback, call_on_write)); return this.internalSendCommand(new Command('subscribe', arr, callback, callOnWrite));
}; };
Multi.prototype.subscribe = Multi.prototype.SUBSCRIBE = function subscribe () { Multi.prototype.subscribe = Multi.prototype.SUBSCRIBE = function subscribe () {
@@ -440,10 +440,10 @@ Multi.prototype.subscribe = Multi.prototype.SUBSCRIBE = function subscribe () {
} }
} }
var self = this._client; var self = this._client;
var call_on_write = function () { var callOnWrite = function () {
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
}; };
this.queue.push(new Command('subscribe', arr, callback, call_on_write)); this.queue.push(new Command('subscribe', arr, callback, callOnWrite));
return this; return this;
}; };
@@ -468,11 +468,11 @@ RedisClient.prototype.unsubscribe = RedisClient.prototype.UNSUBSCRIBE = function
} }
} }
var self = this; var self = this;
var call_on_write = function () { var callOnWrite = function () {
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback // Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
}; };
return this.internal_send_command(new Command('unsubscribe', arr, callback, call_on_write)); return this.internalSendCommand(new Command('unsubscribe', arr, callback, callOnWrite));
}; };
Multi.prototype.unsubscribe = Multi.prototype.UNSUBSCRIBE = function unsubscribe () { Multi.prototype.unsubscribe = Multi.prototype.UNSUBSCRIBE = function unsubscribe () {
@@ -496,11 +496,11 @@ Multi.prototype.unsubscribe = Multi.prototype.UNSUBSCRIBE = function unsubscribe
} }
} }
var self = this._client; var self = this._client;
var call_on_write = function () { var callOnWrite = function () {
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback // Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
}; };
this.queue.push(new Command('unsubscribe', arr, callback, call_on_write)); this.queue.push(new Command('unsubscribe', arr, callback, callOnWrite));
return this; return this;
}; };
@@ -525,10 +525,10 @@ RedisClient.prototype.psubscribe = RedisClient.prototype.PSUBSCRIBE = function p
} }
} }
var self = this; var self = this;
var call_on_write = function () { var callOnWrite = function () {
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
}; };
return this.internal_send_command(new Command('psubscribe', arr, callback, call_on_write)); return this.internalSendCommand(new Command('psubscribe', arr, callback, callOnWrite));
}; };
Multi.prototype.psubscribe = Multi.prototype.PSUBSCRIBE = function psubscribe () { Multi.prototype.psubscribe = Multi.prototype.PSUBSCRIBE = function psubscribe () {
@@ -552,10 +552,10 @@ Multi.prototype.psubscribe = Multi.prototype.PSUBSCRIBE = function psubscribe ()
} }
} }
var self = this._client; var self = this._client;
var call_on_write = function () { var callOnWrite = function () {
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
}; };
this.queue.push(new Command('psubscribe', arr, callback, call_on_write)); this.queue.push(new Command('psubscribe', arr, callback, callOnWrite));
return this; return this;
}; };
@@ -580,11 +580,11 @@ RedisClient.prototype.punsubscribe = RedisClient.prototype.PUNSUBSCRIBE = functi
} }
} }
var self = this; var self = this;
var call_on_write = function () { var callOnWrite = function () {
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback // Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
}; };
return this.internal_send_command(new Command('punsubscribe', arr, callback, call_on_write)); return this.internalSendCommand(new Command('punsubscribe', arr, callback, callOnWrite));
}; };
Multi.prototype.punsubscribe = Multi.prototype.PUNSUBSCRIBE = function punsubscribe () { Multi.prototype.punsubscribe = Multi.prototype.PUNSUBSCRIBE = function punsubscribe () {
@@ -608,10 +608,10 @@ Multi.prototype.punsubscribe = Multi.prototype.PUNSUBSCRIBE = function punsubscr
} }
} }
var self = this._client; var self = this._client;
var call_on_write = function () { var callOnWrite = function () {
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback // Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1; self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
}; };
this.queue.push(new Command('punsubscribe', arr, callback, call_on_write)); this.queue.push(new Command('punsubscribe', arr, callback, callOnWrite));
return this; return this;
}; };

View File

@@ -7,25 +7,25 @@ var Command = require('./command');
function Multi (client, args) { function Multi (client, args) {
this._client = client; this._client = client;
this.queue = new Queue(); this.queue = new Queue();
var command, tmp_args; var command, tmpArgs;
if (args) { // Either undefined or an array. Fail hard if it's not an array if (args) { // Either undefined or an array. Fail hard if it's not an array
for (var i = 0; i < args.length; i++) { for (var i = 0; i < args.length; i++) {
command = args[i][0]; command = args[i][0];
tmp_args = args[i].slice(1); tmpArgs = args[i].slice(1);
if (Array.isArray(command)) { if (Array.isArray(command)) {
this[command[0]].apply(this, command.slice(1).concat(tmp_args)); this[command[0]].apply(this, command.slice(1).concat(tmpArgs));
} else { } else {
this[command].apply(this, tmp_args); this[command].apply(this, tmpArgs);
} }
} }
} }
} }
function pipeline_transaction_command (self, command_obj, index) { function pipelineTransactionCommand (self, commandObj, index) {
// Queueing is done first, then the commands are executed // Queueing is done first, then the commands are executed
var tmp = command_obj.callback; var tmp = commandObj.callback;
command_obj.callback = function (err, reply) { commandObj.callback = function (err, reply) {
// Ignore the multi command. This is applied by node_redis and the user does not benefit by it // Ignore the multi command. This is applied by nodeRedis and the user does not benefit by it
if (err && index !== -1) { if (err && index !== -1) {
if (tmp) { if (tmp) {
tmp(err); tmp(err);
@@ -34,22 +34,22 @@ function pipeline_transaction_command (self, command_obj, index) {
self.errors.push(err); self.errors.push(err);
} }
// Keep track of who wants buffer responses: // Keep track of who wants buffer responses:
// By the time the callback is called the command_obj got the buffer_args attribute attached // By the time the callback is called the commandObj got the bufferArgs attribute attached
self.wants_buffers[index] = command_obj.buffer_args; self.wantsBuffers[index] = commandObj.bufferArgs;
command_obj.callback = tmp; commandObj.callback = tmp;
}; };
self._client.internal_send_command(command_obj); self._client.internalSendCommand(commandObj);
} }
Multi.prototype.exec_atomic = Multi.prototype.EXEC_ATOMIC = Multi.prototype.execAtomic = function exec_atomic (callback) { Multi.prototype.execAtomic = Multi.prototype.EXEC_ATOMIC = Multi.prototype.execAtomic = function execAtomic (callback) {
if (this.queue.length < 2) { if (this.queue.length < 2) {
return this.exec_batch(callback); return this.execBatch(callback);
} }
return this.exec(callback); return this.exec(callback);
}; };
function multi_callback (self, err, replies) { function multiCallback (self, err, replies) {
var i = 0, command_obj; var i = 0, commandObj;
if (err) { if (err) {
err.errors = self.errors; err.errors = self.errors;
@@ -63,22 +63,22 @@ function multi_callback (self, err, replies) {
} }
if (replies) { if (replies) {
while (command_obj = self.queue.shift()) { while (commandObj = self.queue.shift()) {
if (replies[i] instanceof Error) { if (replies[i] instanceof Error) {
var match = replies[i].message.match(utils.err_code); var match = replies[i].message.match(utils.errCode);
// LUA script could return user errors that don't behave like all other errors! // LUA script could return user errors that don't behave like all other errors!
if (match) { if (match) {
replies[i].code = match[1]; replies[i].code = match[1];
} }
replies[i].command = command_obj.command.toUpperCase(); replies[i].command = commandObj.command.toUpperCase();
if (typeof command_obj.callback === 'function') { if (typeof commandObj.callback === 'function') {
command_obj.callback(replies[i]); commandObj.callback(replies[i]);
} }
} else { } else {
// If we asked for strings, even in detect_buffers mode, then return strings: // If we asked for strings, even in detectBuffers mode, then return strings:
replies[i] = self._client.handle_reply(replies[i], command_obj.command, self.wants_buffers[i]); replies[i] = self._client.handleReply(replies[i], commandObj.command, self.wantsBuffers[i]);
if (typeof command_obj.callback === 'function') { if (typeof commandObj.callback === 'function') {
command_obj.callback(null, replies[i]); commandObj.callback(null, replies[i]);
} }
} }
i++; i++;
@@ -90,37 +90,37 @@ function multi_callback (self, err, replies) {
} }
} }
Multi.prototype.exec_transaction = function exec_transaction (callback) { Multi.prototype.execTransaction = function execTransaction (callback) {
if (this.monitoring || this._client.monitoring) { if (this.monitoring || this._client.monitoring) {
var err = new RangeError( var err = new RangeError(
'Using transaction with a client that is in monitor mode does not work due to faulty return values of Redis.' 'Using transaction with a client that is in monitor mode does not work due to faulty return values of Redis.'
); );
err.command = 'EXEC'; err.command = 'EXEC';
err.code = 'EXECABORT'; err.code = 'EXECABORT';
return utils.reply_in_order(this._client, callback, err); return utils.replyInOrder(this._client, callback, err);
} }
var self = this; var self = this;
var len = self.queue.length; var len = self.queue.length;
self.errors = []; self.errors = [];
self.callback = callback; self.callback = callback;
self._client.cork(); self._client.cork();
self.wants_buffers = new Array(len); self.wantsBuffers = new Array(len);
pipeline_transaction_command(self, new Command('multi', []), -1); pipelineTransactionCommand(self, new Command('multi', []), -1);
// Drain queue, callback will catch 'QUEUED' or error // Drain queue, callback will catch 'QUEUED' or error
for (var index = 0; index < len; index++) { for (var index = 0; index < len; index++) {
// The commands may not be shifted off, since they are needed in the result handler // The commands may not be shifted off, since they are needed in the result handler
pipeline_transaction_command(self, self.queue.get(index), index); pipelineTransactionCommand(self, self.queue.get(index), index);
} }
self._client.internal_send_command(new Command('exec', [], function (err, replies) { self._client.internalSendCommand(new Command('exec', [], function (err, replies) {
multi_callback(self, err, replies); multiCallback(self, err, replies);
})); }));
self._client.uncork(); self._client.uncork();
return !self._client.should_buffer; return !self._client.shouldBuffer;
}; };
function batch_callback (self, cb, i) { function batchCallback (self, cb, i) {
return function batch_callback (err, res) { return function batchCallback (err, res) {
if (err) { if (err) {
self.results[i] = err; self.results[i] = err;
// Add the position to the error // Add the position to the error
@@ -132,24 +132,24 @@ function batch_callback (self, cb, i) {
}; };
} }
Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = function exec_batch (callback) { Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.execBatch = function execBatch (callback) {
var self = this; var self = this;
var len = self.queue.length; var len = self.queue.length;
var index = 0; var index = 0;
var command_obj; var commandObj;
if (len === 0) { if (len === 0) {
utils.reply_in_order(self._client, callback, null, []); utils.replyInOrder(self._client, callback, null, []);
return !self._client.should_buffer; return !self._client.shouldBuffer;
} }
self._client.cork(); self._client.cork();
if (!callback) { if (!callback) {
while (command_obj = self.queue.shift()) { while (commandObj = self.queue.shift()) {
self._client.internal_send_command(command_obj); self._client.internalSendCommand(commandObj);
} }
self._client.uncork(); self._client.uncork();
return !self._client.should_buffer; return !self._client.shouldBuffer;
} }
var callback_without_own_cb = function (err, res) { var callbackWithoutOwnCb = function (err, res) {
if (err) { if (err) {
self.results.push(err); self.results.push(err);
// Add the position to the error // Add the position to the error
@@ -161,27 +161,27 @@ Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = funct
// Do not emit an error here. Otherwise each error would result in one emit. // Do not emit an error here. Otherwise each error would result in one emit.
// The errors will be returned in the result anyway // The errors will be returned in the result anyway
}; };
var last_callback = function (cb) { var lastCallback = function (cb) {
return function (err, res) { return function (err, res) {
cb(err, res); cb(err, res);
callback(null, self.results); callback(null, self.results);
}; };
}; };
self.results = []; self.results = [];
while (command_obj = self.queue.shift()) { while (commandObj = self.queue.shift()) {
if (typeof command_obj.callback === 'function') { if (typeof commandObj.callback === 'function') {
command_obj.callback = batch_callback(self, command_obj.callback, index); commandObj.callback = batchCallback(self, commandObj.callback, index);
} else { } else {
command_obj.callback = callback_without_own_cb; commandObj.callback = callbackWithoutOwnCb;
} }
if (typeof callback === 'function' && index === len - 1) { if (typeof callback === 'function' && index === len - 1) {
command_obj.callback = last_callback(command_obj.callback); commandObj.callback = lastCallback(commandObj.callback);
} }
this._client.internal_send_command(command_obj); this._client.internalSendCommand(commandObj);
index++; index++;
} }
self._client.uncork(); self._client.uncork();
return !self._client.should_buffer; return !self._client.shouldBuffer;
}; };
module.exports = Multi; module.exports = Multi;

View File

@@ -30,10 +30,8 @@ function replyToStrings (reply) {
return reply; return reply;
} }
var camelCase;
// Deep clone arbitrary objects with arrays. Can't handle cyclic structures (results in a range error) // Deep clone arbitrary objects with arrays. Can't handle cyclic structures (results in a range error)
// Any attribute with a non primitive value besides object and array will be passed by reference (e.g. Buffers, Maps, Functions) // Any attribute with a non primitive value besides object and array will be passed by reference (e.g. Buffers, Maps, Functions)
// All capital letters are going to be replaced with a lower case letter and a underscore infront of it
function clone (obj) { function clone (obj) {
var copy; var copy;
if (Array.isArray(obj)) { if (Array.isArray(obj)) {
@@ -48,18 +46,7 @@ function clone (obj) {
var elems = Object.keys(obj); var elems = Object.keys(obj);
var elem; var elem;
while (elem = elems.pop()) { while (elem = elems.pop()) {
if (elem === 'tls') { // special handle tls copy[elem] = clone(obj[elem]);
copy[elem] = obj[elem];
continue;
}
// Accept camelCase options and convert them to snake_case
var snake_case = elem.replace(/[A-Z][^A-Z]/g, '_$&').toLowerCase();
// If camelCase is detected, pass it to the client, so all variables are going to be camelCased
// There are no deep nested options objects yet, but let's handle this future proof
if (snake_case !== elem.toLowerCase()) {
camelCase = true;
}
copy[snake_case] = clone(obj[elem]);
} }
return copy; return copy;
} }
@@ -67,12 +54,7 @@ function clone (obj) {
} }
function convenienceClone (obj) { function convenienceClone (obj) {
camelCase = false; return clone(obj) || {};
obj = clone(obj) || {};
if (camelCase) {
obj.camel_case = true;
}
return obj;
} }
function callbackOrEmit (self, callback, err, res) { function callbackOrEmit (self, callback, err, res) {
@@ -86,20 +68,19 @@ function callbackOrEmit (self, callback, err, res) {
function replyInOrder (self, callback, err, res, queue) { function replyInOrder (self, callback, err, res, queue) {
// If the queue is explicitly passed, use that, otherwise fall back to the offline queue first, // If the queue is explicitly passed, use that, otherwise fall back to the offline queue first,
// as there might be commands in both queues at the same time // as there might be commands in both queues at the same time
var command_obj; var commandObj;
/* istanbul ignore if: TODO: Remove this as soon as we test Redis 3.2 on travis */
if (queue) { if (queue) {
command_obj = queue.peekBack(); commandObj = queue.peekBack();
} else { } else {
command_obj = self.offline_queue.peekBack() || self.command_queue.peekBack(); commandObj = self.offlineQueue.peekBack() || self.commandQueue.peekBack();
} }
if (!command_obj) { if (!commandObj) {
process.nextTick(function () { process.nextTick(function () {
callbackOrEmit(self, callback, err, res); callbackOrEmit(self, callback, err, res);
}); });
} else { } else {
var tmp = command_obj.callback; var tmp = commandObj.callback;
command_obj.callback = tmp ? commandObj.callback = tmp ?
function (e, r) { function (e, r) {
tmp(e, r); tmp(e, r);
callbackOrEmit(self, callback, err, res); callbackOrEmit(self, callback, err, res);
@@ -114,11 +95,11 @@ function replyInOrder (self, callback, err, res, queue) {
} }
module.exports = { module.exports = {
reply_to_strings: replyToStrings, replyToStrings: replyToStrings,
reply_to_object: replyToObject, replyToObject: replyToObject,
err_code: /^([A-Z]+)\s+(.+)$/, errCode: /^([A-Z]+)\s+(.+)$/,
monitor_regex: /^[0-9]{10,11}\.[0-9]+ \[[0-9]+ .+\]( ".+?")+$/, monitor_regex: /^[0-9]{10,11}\.[0-9]+ \[[0-9]+ .+\]( ".+?")+$/,
clone: convenienceClone, clone: convenienceClone,
callback_or_emit: callbackOrEmit, callbackOrEmit: callbackOrEmit,
reply_in_order: replyInOrder replyInOrder: replyInOrder
}; };

View File

@@ -58,8 +58,8 @@ describe('client authentication', function () {
assert(now - time < 225, 'Time should be below 255 ms (the reconnect should only take a bit above 100 ms) and is ' + (now - time)); assert(now - time < 225, 'Time should be below 255 ms (the reconnect should only take a bit above 100 ms) and is ' + (now - time));
done(); done();
}); });
var tmp = client.command_queue.get(0).callback; var tmp = client.commandQueue.get(0).callback;
client.command_queue.get(0).callback = function (err, res) { client.commandQueue.get(0).callback = function (err, res) {
client.auth = function (pass, callback) { client.auth = function (pass, callback) {
callback(null, 'retry worked'); callback(null, 'retry worked');
}; };
@@ -115,15 +115,15 @@ describe('client authentication', function () {
client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT + '?db=2&password=' + auth); client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT + '?db=2&password=' + auth);
assert.strictEqual(client.options.db, '2'); assert.strictEqual(client.options.db, '2');
assert.strictEqual(client.options.password, auth); assert.strictEqual(client.options.password, auth);
assert.strictEqual(client.auth_pass, auth); assert.strictEqual(client.authPass, auth);
client.on('ready', function () { client.on('ready', function () {
// Set a key so the used database is returned in the info command // Set a key so the used database is returned in the info command
client.set('foo', 'bar'); client.set('foo', 'bar');
client.get('foo'); client.get('foo');
assert.strictEqual(client.server_info.db2, undefined); assert.strictEqual(client.serverInfo.db2, undefined);
// Using the info command should update the server_info // Using the info command should update the serverInfo
client.info(function (err, res) { client.info(function (err, res) {
assert(typeof client.server_info.db2 === 'object'); assert(typeof client.serverInfo.db2 === 'object');
}); });
client.flushdb(done); client.flushdb(done);
}); });
@@ -134,18 +134,18 @@ describe('client authentication', function () {
if (helper.redisProcess().spawnFailed()) this.skip(); if (helper.redisProcess().spawnFailed()) this.skip();
var args = config.configureClient(ip, { var args = config.configureClient(ip, {
auth_pass: auth authPass: auth
}); });
client = redis.createClient.apply(null, args); client = redis.createClient.apply(null, args);
client.on('ready', done); client.on('ready', done);
}); });
it('allows auth and no_ready_check to be provided as config option for client', function (done) { it('allows auth and noReadyCheck to be provided as config option for client', function (done) {
if (helper.redisProcess().spawnFailed()) this.skip(); if (helper.redisProcess().spawnFailed()) this.skip();
var args = config.configureClient(ip, { var args = config.configureClient(ip, {
password: auth, password: auth,
no_ready_check: true noReadyCheck: true
}); });
client = redis.createClient.apply(null, args); client = redis.createClient.apply(null, args);
client.on('ready', done); client.on('ready', done);
@@ -166,9 +166,9 @@ describe('client authentication', function () {
client = redis.createClient.apply(null, args); client = redis.createClient.apply(null, args);
client.auth(auth); client.auth(auth);
client.on('ready', function () { client.on('ready', function () {
if (this.times_connected < 3) { if (this.timesConnected < 3) {
var interval = setInterval(function () { var interval = setInterval(function () {
if (client.commandQueueLength !== 0) { if (client.commandQueue.length !== 0) {
return; return;
} }
clearInterval(interval); clearInterval(interval);
@@ -176,7 +176,7 @@ describe('client authentication', function () {
client.stream.destroy(); client.stream.destroy();
client.set('foo', 'bar'); client.set('foo', 'bar');
client.get('foo'); // Errors would bubble client.get('foo'); // Errors would bubble
assert.strictEqual(client.offlineQueueLength, 2); assert.strictEqual(client.offlineQueue.length, 2);
}, 1); }, 1);
} else { } else {
done(); done();
@@ -218,7 +218,7 @@ describe('client authentication', function () {
if (helper.redisProcess().spawnFailed()) this.skip(); if (helper.redisProcess().spawnFailed()) this.skip();
var args = config.configureClient(ip, { var args = config.configureClient(ip, {
auth_pass: auth authPass: auth
}); });
client = redis.createClient.apply(null, args); client = redis.createClient.apply(null, args);
client.on('ready', function () { client.on('ready', function () {
@@ -226,11 +226,11 @@ describe('client authentication', function () {
}); });
}); });
it('does not allow any commands to be processed if not authenticated using no_ready_check true', function (done) { it('does not allow any commands to be processed if not authenticated using noReadyCheck true', function (done) {
if (helper.redisProcess().spawnFailed()) this.skip(); if (helper.redisProcess().spawnFailed()) this.skip();
var args = config.configureClient(ip, { var args = config.configureClient(ip, {
no_ready_check: true noReadyCheck: true
}); });
client = redis.createClient.apply(null, args); client = redis.createClient.apply(null, args);
client.on('ready', function () { client.on('ready', function () {
@@ -257,7 +257,7 @@ describe('client authentication', function () {
it('should emit an error if the provided password is faulty', function (done) { it('should emit an error if the provided password is faulty', function (done) {
if (helper.redisProcess().spawnFailed()) this.skip(); if (helper.redisProcess().spawnFailed()) this.skip();
client = redis.createClient({ client = redis.createClient({
password: 'wrong_password' password: 'wrongPassword'
}); });
client.once('error', function (err) { client.once('error', function (err) {
assert.strictEqual(err.message, 'ERR invalid password'); assert.strictEqual(err.message, 'ERR invalid password');
@@ -275,7 +275,7 @@ describe('client authentication', function () {
client.set('foo', 'bar'); client.set('foo', 'bar');
client.subscribe('somechannel', 'another channel', function (err, res) { client.subscribe('somechannel', 'another channel', function (err, res) {
client.once('ready', function () { client.once('ready', function () {
assert.strictEqual(client.pub_sub_mode, 1); assert.strictEqual(client.pubSubMode, 1);
client.get('foo', function (err, res) { client.get('foo', function (err, res) {
assert(/ERR only \(P\)SUBSCRIBE \/ \(P\)UNSUBSCRIBE/.test(err.message)); assert(/ERR only \(P\)SUBSCRIBE \/ \(P\)UNSUBSCRIBE/.test(err.message));
done(); done();
@@ -284,7 +284,7 @@ describe('client authentication', function () {
}); });
client.once('ready', function () { client.once('ready', function () {
// Coherent behavior with all other offline commands fires commands before emitting but does not wait till they return // Coherent behavior with all other offline commands fires commands before emitting but does not wait till they return
assert.strictEqual(client.pub_sub_mode, 2); assert.strictEqual(client.pubSubMode, 2);
client.ping(function () { // Make sure all commands were properly processed already client.ping(function () { // Make sure all commands were properly processed already
client.stream.destroy(); client.stream.destroy();
}); });
@@ -302,7 +302,7 @@ describe('client authentication', function () {
noReadyCheck: true noReadyCheck: true
}); });
client = redis.createClient.apply(null, args); client = redis.createClient.apply(null, args);
assert.strictEqual(client.selected_db, undefined); assert.strictEqual(client.selectedDb, undefined);
var end = helper.callFuncAfter(done, 8); var end = helper.callFuncAfter(done, 8);
client.on('monitor', function () { client.on('monitor', function () {
end(); // Should be called for each command after monitor end(); // Should be called for each command after monitor
@@ -310,9 +310,9 @@ describe('client authentication', function () {
client.batch() client.batch()
.auth(auth) .auth(auth)
.SELECT(5, function (err, res) { .SELECT(5, function (err, res) {
assert.strictEqual(client.selected_db, 5); assert.strictEqual(client.selectedDb, 5);
assert.strictEqual(res, 'OK'); assert.strictEqual(res, 'OK');
assert.notDeepEqual(client.serverInfo.db5, { avg_ttl: 0, expires: 0, keys: 1 }); assert.notDeepEqual(client.serverInfo.db5, { avgTtl: 0, expires: 0, keys: 1 });
}) })
.monitor() .monitor()
.set('foo', 'bar', helper.isString('OK')) .set('foo', 'bar', helper.isString('OK'))

View File

@@ -23,7 +23,7 @@ describe("The 'blpop' method", function () {
it('pops value immediately if list contains values', function (done) { it('pops value immediately if list contains values', function (done) {
bclient = redis.createClient.apply(null, args); bclient = redis.createClient.apply(null, args);
redis.debug_mode = true; redis.debugMode = true;
var text = ''; var text = '';
var unhookIntercept = intercept(function (data) { var unhookIntercept = intercept(function (data) {
text += data; text += data;
@@ -32,7 +32,7 @@ describe("The 'blpop' method", function () {
client.rpush('blocking list', 'initial value', helper.isNumber(1)); client.rpush('blocking list', 'initial value', helper.isNumber(1));
unhookIntercept(); unhookIntercept();
assert(/^Send 127\.0\.0\.1:6379 id [0-9]+: \*3\r\n\$5\r\nrpush\r\n\$13\r\nblocking list\r\n\$13\r\ninitial value\r\n\n$/.test(text)); assert(/^Send 127\.0\.0\.1:6379 id [0-9]+: \*3\r\n\$5\r\nrpush\r\n\$13\r\nblocking list\r\n\$13\r\ninitial value\r\n\n$/.test(text));
redis.debug_mode = false; redis.debugMode = false;
bclient.blpop('blocking list', 0, function (err, value) { bclient.blpop('blocking list', 0, function (err, value) {
assert.strictEqual(value[0], 'blocking list'); assert.strictEqual(value[0], 'blocking list');
assert.strictEqual(value[1], 'initial value'); assert.strictEqual(value[1], 'initial value');

View File

@@ -33,8 +33,8 @@ describe("The 'hgetall' method", function () {
}); });
it('handles fetching keys set using an object', function (done) { it('handles fetching keys set using an object', function (done) {
client.batch().HMSET('msg_test', { message: 'hello' }, undefined).exec(); client.batch().HMSET('msgTest', { message: 'hello' }, undefined).exec();
client.hgetall('msg_test', function (err, obj) { client.hgetall('msgTest', function (err, obj) {
assert.strictEqual(1, Object.keys(obj).length); assert.strictEqual(1, Object.keys(obj).length);
assert.strictEqual(obj.message, 'hello'); assert.strictEqual(obj.message, 'hello');
done(err); done(err);
@@ -52,7 +52,7 @@ describe("The 'hgetall' method", function () {
describe('binary client', function () { describe('binary client', function () {
var client; var client;
var args = config.configureClient(ip, { var args = config.configureClient(ip, {
return_buffers: true returnBuffers: true
}); });
beforeEach(function (done) { beforeEach(function (done) {

View File

@@ -52,7 +52,7 @@ describe("The 'incr' method", function () {
}); });
it('count above the safe integers as strings', function (done) { it('count above the safe integers as strings', function (done) {
args[2].string_numbers = true; args[2].stringNumbers = true;
client = redis.createClient.apply(null, args); client = redis.createClient.apply(null, args);
// Set a value to the maximum safe allowed javascript number (2^53) // Set a value to the maximum safe allowed javascript number (2^53)
client.set(key, MAX_SAFE_INTEGER, helper.isNotError()); client.set(key, MAX_SAFE_INTEGER, helper.isNotError());

View File

@@ -41,24 +41,24 @@ describe("The 'info' method", function () {
client.set('foo', 'bar'); client.set('foo', 'bar');
client.info('keyspace'); client.info('keyspace');
client.select(2, function () { client.select(2, function () {
assert.strictEqual(Object.keys(client.server_info).length, 2, 'Key length should be three'); assert.strictEqual(Object.keys(client.serverInfo).length, 2, 'Key length should be three');
assert.strictEqual(typeof client.server_info.db0, 'object', 'db0 keyspace should be an object'); assert.strictEqual(typeof client.serverInfo.db0, 'object', 'db0 keyspace should be an object');
}); });
client.info(['keyspace']); client.info(['keyspace']);
client.set('foo', 'bar'); client.set('foo', 'bar');
client.info('all', function (err, res) { client.info('all', function (err, res) {
assert(Object.keys(client.server_info).length > 3, 'Key length should be way above three'); assert(Object.keys(client.serverInfo).length > 3, 'Key length should be way above three');
assert.strictEqual(typeof client.server_info.redis_version, 'string'); assert.strictEqual(typeof client.serverInfo.redis_version, 'string');
assert.strictEqual(typeof client.server_info.db2, 'object'); assert.strictEqual(typeof client.serverInfo.db2, 'object');
done(); done();
}); });
}); });
it('check redis v.2.4 support', function (done) { it('check redis v.2.4 support', function (done) {
var end = helper.callFuncAfter(done, 2); var end = helper.callFuncAfter(done, 2);
client.internal_send_command = function (command_obj) { client.internalSendCommand = function (commandObj) {
assert.strictEqual(command_obj.args.length, 0); assert.strictEqual(commandObj.args.length, 0);
assert.strictEqual(command_obj.command, 'info'); assert.strictEqual(commandObj.command, 'info');
end(); end();
}; };
client.info(); client.info();

View File

@@ -31,22 +31,22 @@ describe("The 'keys' method", function () {
}); });
it('handles a large packet size', function (done) { it('handles a large packet size', function (done) {
var keys_values = []; var keysValues = [];
for (var i = 0; i < 200; i++) { for (var i = 0; i < 200; i++) {
var key_value = [ var keyValue = [
'multibulk:' + crypto.randomBytes(256).toString('hex'), // use long strings as keys to ensure generation of large packet 'multibulk:' + crypto.randomBytes(256).toString('hex'), // use long strings as keys to ensure generation of large packet
'test val ' + i 'test val ' + i
]; ];
keys_values.push(key_value); keysValues.push(keyValue);
} }
client.mset(keys_values.reduce(function (a, b) { client.mset(keysValues.reduce(function (a, b) {
return a.concat(b); return a.concat(b);
}), helper.isString('OK')); }), helper.isString('OK'));
client.keys('multibulk:*', function (err, results) { client.keys('multibulk:*', function (err, results) {
assert.deepEqual(keys_values.map(function (val) { assert.deepEqual(keysValues.map(function (val) {
return val[0]; return val[0];
}).sort(), results.sort()); }).sort(), results.sort());
return done(err); return done(err);

View File

@@ -46,10 +46,10 @@ describe("The 'select' method", function () {
it('changes the database and calls the callback', function (done) { it('changes the database and calls the callback', function (done) {
// default value of null means database 0 will be used. // default value of null means database 0 will be used.
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined'); assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
var buffering = client.SELECT(1, function (err, res) { var buffering = client.SELECT(1, function (err, res) {
helper.isNotError()(err, res); helper.isNotError()(err, res);
assert.strictEqual(client.selected_db, 1, 'db should be 1 after select'); assert.strictEqual(client.selectedDb, 1, 'db should be 1 after select');
done(); done();
}); });
assert(typeof buffering === 'boolean'); assert(typeof buffering === 'boolean');
@@ -58,10 +58,10 @@ describe("The 'select' method", function () {
describe('and a callback is specified', function () { describe('and a callback is specified', function () {
describe('with a valid db index', function () { describe('with a valid db index', function () {
it('selects the appropriate database', function (done) { it('selects the appropriate database', function (done) {
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined'); assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
client.select(1, function (err) { client.select(1, function (err) {
assert.equal(err, null); assert.equal(err, null);
assert.equal(client.selected_db, 1, 'we should have selected the new valid DB'); assert.equal(client.selectedDb, 1, 'we should have selected the new valid DB');
done(); done();
}); });
}); });
@@ -69,7 +69,7 @@ describe("The 'select' method", function () {
describe('with an invalid db index', function () { describe('with an invalid db index', function () {
it('returns an error', function (done) { it('returns an error', function (done) {
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined'); assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
client.select(9999, function (err) { client.select(9999, function (err) {
assert.equal(err.code, 'ERR'); assert.equal(err.code, 'ERR');
assert.equal(err.message, 'ERR invalid DB index'); assert.equal(err.message, 'ERR invalid DB index');
@@ -82,10 +82,10 @@ describe("The 'select' method", function () {
describe('and no callback is specified', function () { describe('and no callback is specified', function () {
describe('with a valid db index', function () { describe('with a valid db index', function () {
it('selects the appropriate database', function (done) { it('selects the appropriate database', function (done) {
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined'); assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
client.select(1); client.select(1);
setTimeout(function () { setTimeout(function () {
assert.equal(client.selected_db, 1, 'we should have selected the new valid DB'); assert.equal(client.selectedDb, 1, 'we should have selected the new valid DB');
done(); done();
}, 25); }, 25);
}); });
@@ -93,7 +93,7 @@ describe("The 'select' method", function () {
describe('with an invalid db index', function () { describe('with an invalid db index', function () {
it('emits an error when callback not provided', function (done) { it('emits an error when callback not provided', function (done) {
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined'); assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
client.on('error', function (err) { client.on('error', function (err) {
assert.strictEqual(err.command, 'SELECT'); assert.strictEqual(err.command, 'SELECT');
@@ -108,14 +108,14 @@ describe("The 'select' method", function () {
describe('reconnection occurs', function () { describe('reconnection occurs', function () {
it('selects the appropriate database after a reconnect', function (done) { it('selects the appropriate database after a reconnect', function (done) {
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined'); assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
client.select(3); client.select(3);
client.set('foo', 'bar', function () { client.set('foo', 'bar', function () {
client.stream.destroy(); client.stream.destroy();
}); });
client.once('ready', function () { client.once('ready', function () {
assert.strictEqual(client.selected_db, 3); assert.strictEqual(client.selectedDb, 3);
assert(typeof client.server_info.db3 === 'object'); assert(typeof client.serverInfo.db3 === 'object');
done(); done();
}); });
}); });

View File

@@ -39,9 +39,9 @@ describe("The 'srem' method", function () {
}); });
}); });
it('allows multiple values to be removed with send_command', function (done) { it('allows multiple values to be removed with sendCommand', function (done) {
client.send_command('sadd', ['set0', 'member0', 'member1', 'member2'], helper.isNumber(3)); client.sendCommand('sadd', ['set0', 'member0', 'member1', 'member2'], helper.isNumber(3));
client.send_command('srem', ['set0', 'member1', 'member2'], helper.isNumber(2)); client.sendCommand('srem', ['set0', 'member1', 'member2'], helper.isNumber(2));
client.smembers('set0', function (err, res) { client.smembers('set0', function (err, res) {
assert.strictEqual(res.length, 1); assert.strictEqual(res.length, 1);
assert.ok(~res.indexOf('member0')); assert.ok(~res.indexOf('member0'));

View File

@@ -28,7 +28,7 @@ describe("The 'zscan' method", function () {
for (var i = 0; i < 500; i++) { for (var i = 0; i < 500; i++) {
hash['key_' + i] = 'value_' + i; hash['key_' + i] = 'value_' + i;
set.push('member_' + i); set.push('member_' + i);
zset.push(i, 'z_member_' + i); zset.push(i, 'zMember_' + i);
} }
client.hmset('hash:1', hash); client.hmset('hash:1', hash);
client.sadd('set:1', set); client.sadd('set:1', set);

View File

@@ -45,7 +45,7 @@ describe('master slave sync', function () {
var firstInfo; var firstInfo;
slave = redis.createClient({ slave = redis.createClient({
port: port, port: port,
retry_strategy: function (options) { retryStrategy: function (options) {
// Try to reconnect in very small intervals to catch the master_link_status down before the sync completes // Try to reconnect in very small intervals to catch the master_link_status down before the sync completes
return 10; return 10;
} }
@@ -57,7 +57,7 @@ describe('master slave sync', function () {
i++; i++;
tmp(err, res); tmp(err, res);
if (!firstInfo || Object.keys(firstInfo).length === 0) { if (!firstInfo || Object.keys(firstInfo).length === 0) {
firstInfo = slave.server_info; firstInfo = slave.serverInfo;
} }
}; };
@@ -68,7 +68,7 @@ describe('master slave sync', function () {
var end = helper.callFuncAfter(done, 2); var end = helper.callFuncAfter(done, 2);
slave.on('ready', function () { slave.on('ready', function () {
assert.strictEqual(this.server_info.master_link_status, 'up'); assert.strictEqual(this.serverInfo.master_link_status, 'up');
assert.strictEqual(firstInfo.master_link_status, 'down'); assert.strictEqual(firstInfo.master_link_status, 'down');
assert(i > 1); assert(i > 1);
this.get('foo300', function (err, res) { this.get('foo300', function (err, res) {

View File

@@ -29,7 +29,7 @@ describe('connection tests', function () {
assert.strictEqual(client.stream.listeners('error').length, 1); assert.strictEqual(client.stream.listeners('error').length, 1);
assert.strictEqual(client.address, '"Private stream"'); assert.strictEqual(client.address, '"Private stream"');
// Pretent a reconnect event // Pretent a reconnect event
client.create_stream(); client.createStream();
assert.strictEqual(client.stream, socket); assert.strictEqual(client.stream, socket);
assert.strictEqual(client.stream.listeners('error').length, 1); assert.strictEqual(client.stream.listeners('error').length, 1);
}); });
@@ -40,7 +40,7 @@ describe('connection tests', function () {
var called = 0; var called = 0;
client = redis.createClient({ client = redis.createClient({
port: 9999, port: 9999,
retry_strategy: function (options) { retryStrategy: function (options) {
var bool = client.quit(function (err, res) { var bool = client.quit(function (err, res) {
assert.strictEqual(res, 'OK'); assert.strictEqual(res, 'OK');
assert.strictEqual(err, null); assert.strictEqual(err, null);
@@ -77,7 +77,7 @@ describe('connection tests', function () {
it('calling quit while the connection is down without offline queue should end the connection right away', function (done) { it('calling quit while the connection is down without offline queue should end the connection right away', function (done) {
var called = false; var called = false;
client = redis.createClient(9999, { client = redis.createClient(9999, {
enable_offline_queue: false enableOfflineQueue: false
}); });
client.set('foo', 'bar', function (err, res) { client.set('foo', 'bar', function (err, res) {
assert.strictEqual(err.message, 'SET can\'t be processed. The connection is not yet established and the offline queue is deactivated.'); assert.strictEqual(err.message, 'SET can\'t be processed. The connection is not yet established and the offline queue is deactivated.');
@@ -96,7 +96,7 @@ describe('connection tests', function () {
it('calling quit while connected without offline queue should end the connection when all commands have finished', function (done) { it('calling quit while connected without offline queue should end the connection when all commands have finished', function (done) {
var called = false; var called = false;
client = redis.createClient({ client = redis.createClient({
enable_offline_queue: false enableOfflineQueue: false
}); });
client.on('ready', function () { client.on('ready', function () {
client.set('foo', 'bar', function (err, res) { client.set('foo', 'bar', function (err, res) {
@@ -154,9 +154,9 @@ describe('connection tests', function () {
describe('on lost connection', function () { describe('on lost connection', function () {
it('end connection while retry is still ongoing', function (done) { it('end connection while retry is still ongoing', function (done) {
var connect_timeout = 1000; // in ms var connectTimeout = 1000; // in ms
client = redis.createClient({ client = redis.createClient({
connect_timeout: connect_timeout connectTimeout: connectTimeout
}); });
client.once('ready', function () { client.once('ready', function () {
@@ -165,7 +165,7 @@ describe('connection tests', function () {
client.on('reconnecting', function (params) { client.on('reconnecting', function (params) {
client.end(true); client.end(true);
assert.strictEqual(params.times_connected, 1); assert.strictEqual(params.timesConnected, 1);
setTimeout(done, 5); setTimeout(done, 5);
}); });
}); });
@@ -178,7 +178,7 @@ describe('connection tests', function () {
retryStrategy: function () {} retryStrategy: function () {}
}; };
client = redis.createClient(options); client = redis.createClient(options);
assert.strictEqual(client.connection_options.family, ip === 'IPv6' ? 6 : 4); assert.strictEqual(client.connectionOptions.family, ip === 'IPv6' ? 6 : 4);
assert.strictEqual(Object.keys(options).length, 4); assert.strictEqual(Object.keys(options).length, 4);
var end = helper.callFuncAfter(done, 2); var end = helper.callFuncAfter(done, 2);
@@ -220,10 +220,10 @@ describe('connection tests', function () {
}); });
}); });
it('retry_strategy used to reconnect', function (done) { it('retryStrategy used to reconnect', function (done) {
client = redis.createClient({ client = redis.createClient({
retry_strategy: function (options) { retryStrategy: function (options) {
if (options.total_retry_time > 150) { if (options.totalRetryTime > 150) {
client.set('foo', 'bar', function (err, res) { client.set('foo', 'bar', function (err, res) {
assert.strictEqual(err.message, 'Stream connection ended and command aborted.'); assert.strictEqual(err.message, 'Stream connection ended and command aborted.');
assert.strictEqual(err.code, 'NR_CLOSED'); assert.strictEqual(err.code, 'NR_CLOSED');
@@ -265,18 +265,18 @@ describe('connection tests', function () {
describe('when not connected', function () { describe('when not connected', function () {
it.skip('emit an error after the socket timeout exceeded the connect_timeout time', function (done) { it.skip('emit an error after the socket timeout exceeded the connectTimeout time', function (done) {
var connect_timeout = 500; // in ms var connectTimeout = 500; // in ms
client = redis.createClient({ client = redis.createClient({
// Auto detect ipv4 and use non routable ip to trigger the timeout // Auto detect ipv4 and use non routable ip to trigger the timeout
host: '10.255.255.1', host: '10.255.255.1',
connect_timeout: connect_timeout connectTimeout: connectTimeout
}); });
process.nextTick(function () { process.nextTick(function () {
assert.strictEqual(client.stream.listeners('timeout').length, 1); assert.strictEqual(client.stream.listeners('timeout').length, 1);
}); });
assert.strictEqual(client.address, '10.255.255.1:6379'); assert.strictEqual(client.address, '10.255.255.1:6379');
assert.strictEqual(client.connection_options.family, 4); assert.strictEqual(client.connectionOptions.family, 4);
client.on('reconnecting', function (params) { client.on('reconnecting', function (params) {
throw new Error('No reconnect, since no connection was ever established'); throw new Error('No reconnect, since no connection was ever established');
@@ -291,19 +291,19 @@ describe('connection tests', function () {
// The code execution on windows is very slow at times // The code execution on windows is very slow at times
var add = process.platform !== 'win32' ? 15 : 200; var add = process.platform !== 'win32' ? 15 : 200;
var now = Date.now(); var now = Date.now();
assert(now - time < connect_timeout + add, 'The real timeout time should be below ' + (connect_timeout + add) + 'ms but is: ' + (now - time)); assert(now - time < connectTimeout + add, 'The real timeout time should be below ' + (connectTimeout + add) + 'ms but is: ' + (now - time));
// Timers sometimes trigger early (e.g. 1ms to early) // Timers sometimes trigger early (e.g. 1ms to early)
assert(now - time >= connect_timeout - 5, 'The real timeout time should be above ' + connect_timeout + 'ms, but it is: ' + (now - time)); assert(now - time >= connectTimeout - 5, 'The real timeout time should be above ' + connectTimeout + 'ms, but it is: ' + (now - time));
done(); done();
}); });
}); });
it('use the system socket timeout if the connect_timeout has not been provided', function (done) { it('use the system socket timeout if the connectTimeout has not been provided', function (done) {
client = redis.createClient({ client = redis.createClient({
host: '2001:db8::ff00:42:8329' // auto detect ip v6 host: '2001:db8::ff00:42:8329' // auto detect ip v6
}); });
assert.strictEqual(client.address, '2001:db8::ff00:42:8329:6379'); assert.strictEqual(client.address, '2001:db8::ff00:42:8329:6379');
assert.strictEqual(client.connection_options.family, 6); assert.strictEqual(client.connectionOptions.family, 6);
process.nextTick(function () { process.nextTick(function () {
assert.strictEqual(client.stream.listeners('timeout').length, 0); assert.strictEqual(client.stream.listeners('timeout').length, 0);
done(); done();
@@ -312,7 +312,7 @@ describe('connection tests', function () {
it('clears the socket timeout after a connection has been established', function (done) { it('clears the socket timeout after a connection has been established', function (done) {
client = redis.createClient({ client = redis.createClient({
connect_timeout: 1000 connectTimeout: 1000
}); });
process.nextTick(function () { process.nextTick(function () {
assert.strictEqual(client.stream._idleTimeout, 1000); assert.strictEqual(client.stream._idleTimeout, 1000);
@@ -328,7 +328,7 @@ describe('connection tests', function () {
client = redis.createClient({ client = redis.createClient({
host: 'localhost', host: 'localhost',
port: '6379', port: '6379',
connect_timeout: 1000 connectTimeout: 1000
}); });
client.once('ready', done); client.once('ready', done);
@@ -340,7 +340,7 @@ describe('connection tests', function () {
} }
client = redis.createClient({ client = redis.createClient({
path: '/tmp/redis.sock', path: '/tmp/redis.sock',
connect_timeout: 1000 connectTimeout: 1000
}); });
var end = helper.callFuncAfter(done, 2); var end = helper.callFuncAfter(done, 2);
@@ -371,7 +371,7 @@ describe('connection tests', function () {
it('connects with a port only', function (done) { it('connects with a port only', function (done) {
client = redis.createClient(6379); client = redis.createClient(6379);
assert.strictEqual(client.connection_options.family, 4); assert.strictEqual(client.connectionOptions.family, 4);
client.on('error', done); client.on('error', done);
client.once('ready', function () { client.once('ready', function () {
@@ -406,7 +406,7 @@ describe('connection tests', function () {
it('connects correctly to localhost and no ready check', function (done) { it('connects correctly to localhost and no ready check', function (done) {
client = redis.createClient(undefined, undefined, { client = redis.createClient(undefined, undefined, {
no_ready_check: true noReadyCheck: true
}); });
client.on('error', done); client.on('error', done);
@@ -421,7 +421,7 @@ describe('connection tests', function () {
it('connects correctly to the provided host with the port set to undefined', function (done) { it('connects correctly to the provided host with the port set to undefined', function (done) {
client = redis.createClient(undefined, 'localhost', { client = redis.createClient(undefined, 'localhost', {
no_ready_check: true noReadyCheck: true
}); });
client.on('error', done); client.on('error', done);
assert.strictEqual(client.address, 'localhost:6379'); assert.strictEqual(client.address, 'localhost:6379');
@@ -442,16 +442,16 @@ describe('connection tests', function () {
cb(new Error("ERR unknown command 'info'")); cb(new Error("ERR unknown command 'info'"));
}; };
client.once('ready', function () { client.once('ready', function () {
assert.strictEqual(Object.keys(client.server_info).length, 0); assert.strictEqual(Object.keys(client.serverInfo).length, 0);
done(); done();
}); });
}); });
it('fake the stream to mock redis', function () { it('fake the stream to mock redis', function () {
// This is needed for libraries that want to mock the stream like fakeredis // This is needed for libraries that want to mock the stream like fakeredis
var temp = redis.RedisClient.prototype.create_stream; var temp = redis.RedisClient.prototype.createStream;
var create_stream_string = String(temp); var createStreamString = String(temp);
redis.RedisClient.prototype.create_stream = function () { redis.RedisClient.prototype.createStream = function () {
this.connected = true; this.connected = true;
this.ready = true; this.ready = true;
}; };
@@ -460,15 +460,15 @@ describe('connection tests', function () {
assert.strictEqual(client.ready, true); assert.strictEqual(client.ready, true);
assert.strictEqual(client.connected, true); assert.strictEqual(client.connected, true);
client.end = function () {}; client.end = function () {};
assert(create_stream_string !== String(redis.RedisClient.prototype.create_stream)); assert(createStreamString !== String(redis.RedisClient.prototype.createStream));
redis.RedisClient.prototype.create_stream = temp; redis.RedisClient.prototype.createStream = temp;
assert(create_stream_string === String(redis.RedisClient.prototype.create_stream)); assert(createStreamString === String(redis.RedisClient.prototype.createStream));
}); });
if (ip === 'IPv4') { if (ip === 'IPv4') {
it('allows connecting with the redis url to the default host and port, select db 3 and warn about duplicate db option', function (done) { it('allows connecting with the redis url to the default host and port, select db 3 and warn about duplicate db option', function (done) {
client = redis.createClient('redis:///3?db=3'); client = redis.createClient('redis:///3?db=3');
assert.strictEqual(client.selected_db, '3'); assert.strictEqual(client.selectedDb, '3');
client.on('ready', done); client.on('ready', done);
}); });
@@ -484,9 +484,9 @@ describe('connection tests', function () {
it('allows connecting with the redis url as first parameter and the options as second parameter', function (done) { it('allows connecting with the redis url as first parameter and the options as second parameter', function (done) {
client = redis.createClient('//127.0.0.1', { client = redis.createClient('//127.0.0.1', {
connect_timeout: 1000 connectTimeout: 1000
}); });
assert.strictEqual(client.options.connect_timeout, 1000); assert.strictEqual(client.options.connectTimeout, 1000);
client.on('ready', done); client.on('ready', done);
}); });
@@ -494,8 +494,8 @@ describe('connection tests', function () {
client = redis.createClient({ client = redis.createClient({
url: 'http://foo:porkchopsandwiches@' + config.HOST[ip] + '/3' url: 'http://foo:porkchopsandwiches@' + config.HOST[ip] + '/3'
}); });
assert.strictEqual(client.auth_pass, 'porkchopsandwiches'); assert.strictEqual(client.authPass, 'porkchopsandwiches');
assert.strictEqual(+client.selected_db, 3); assert.strictEqual(+client.selectedDb, 3);
assert(!client.options.port); assert(!client.options.port);
assert.strictEqual(client.options.host, config.HOST[ip]); assert.strictEqual(client.options.host, config.HOST[ip]);
client.on('ready', done); client.on('ready', done);
@@ -503,7 +503,7 @@ describe('connection tests', function () {
it('allows connecting with the redis url and no auth and options as second parameter', function (done) { it('allows connecting with the redis url and no auth and options as second parameter', function (done) {
var options = { var options = {
detect_buffers: false detectBuffers: false
}; };
client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT, options); client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT, options);
assert.strictEqual(Object.keys(options).length, 1); assert.strictEqual(Object.keys(options).length, 1);
@@ -512,7 +512,7 @@ describe('connection tests', function () {
it('allows connecting with the redis url and no auth and options as third parameter', function (done) { it('allows connecting with the redis url and no auth and options as third parameter', function (done) {
client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT, null, { client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT, null, {
detect_buffers: false detectBuffers: false
}); });
client.on('ready', done); client.on('ready', done);
}); });
@@ -529,8 +529,8 @@ describe('connection tests', function () {
tmp(function (err, res) { tmp(function (err, res) {
if (!delayed) { if (!delayed) {
assert(!err); assert(!err);
client.server_info.loading = 1; client.serverInfo.loading = 1;
client.server_info.loading_eta_seconds = 0.5; client.serverInfo.loading_eta_seconds = 0.5;
delayed = true; delayed = true;
time = Date.now(); time = Date.now();
} }
@@ -560,8 +560,8 @@ describe('connection tests', function () {
if (!delayed) { if (!delayed) {
assert(!err); assert(!err);
// Try reconnecting after one second even if redis tells us the time needed is above one second // Try reconnecting after one second even if redis tells us the time needed is above one second
client.server_info.loading = 1; client.serverInfo.loading = 1;
client.server_info.loading_eta_seconds = 2.5; client.serverInfo.loading_eta_seconds = 2.5;
delayed = true; delayed = true;
time = Date.now(); time = Date.now();
} }

View File

@@ -5,11 +5,11 @@ var config = require('./lib/config');
var helper = require('./helper'); var helper = require('./helper');
var redis = config.redis; var redis = config.redis;
describe('detect_buffers', function () { describe('detectBuffers', function () {
var client; var client;
var args = config.configureClient('localhost', { var args = config.configureClient('localhost', {
detect_buffers: true detectBuffers: true
}); });
beforeEach(function (done) { beforeEach(function (done) {

View File

@@ -49,7 +49,7 @@ describe('stack traces', function () {
// This is always going to return good stack traces // This is always going to return good stack traces
it('should always return good stack traces for rejected offline commands', function (done) { it('should always return good stack traces for rejected offline commands', function (done) {
var client = redis.createClient({ var client = redis.createClient({
enable_offline_queue: false enableOfflineQueue: false
}); });
client.set('foo', function (err, res) { client.set('foo', function (err, res) {
assert(/good_traces.spec.js/.test(err.stack)); assert(/good_traces.spec.js/.test(err.stack));

View File

@@ -6,7 +6,7 @@ var config = require('./lib/config');
var RedisProcess = require('./lib/redis-process'); var RedisProcess = require('./lib/redis-process');
var StunnelProcess = require('./lib/stunnel-process'); var StunnelProcess = require('./lib/stunnel-process');
var rp; var rp;
var stunnel_process; var stunnelProcess;
function startRedis (conf, done, port) { function startRedis (conf, done, port) {
RedisProcess.start(function (err, _rp) { RedisProcess.start(function (err, _rp) {
@@ -46,15 +46,15 @@ module.exports = {
}, },
startRedis: startRedis, startRedis: startRedis,
stopStunnel: function (done) { stopStunnel: function (done) {
if (stunnel_process) { if (stunnelProcess) {
StunnelProcess.stop(stunnel_process, done); StunnelProcess.stop(stunnelProcess, done);
} else { } else {
done(); done();
} }
}, },
startStunnel: function (done) { startStunnel: function (done) {
StunnelProcess.start(function (err, _stunnel_process) { StunnelProcess.start(function (err, _stunnelProcess) {
stunnel_process = _stunnel_process; stunnelProcess = _stunnelProcess;
return done(err); return done(err);
}, path.resolve(__dirname, './conf')); }, path.resolve(__dirname, './conf'));
}, },
@@ -138,18 +138,18 @@ module.exports = {
if (done) done(); if (done) done();
}; };
}, },
serverVersionAtLeast: function (connection, desired_version) { serverVersionAtLeast: function (connection, desiredVersion) {
// Wait until a connection has established (otherwise a timeout is going to be triggered at some point) // Wait until a connection has established (otherwise a timeout is going to be triggered at some point)
if (Object.keys(connection.server_info).length === 0) { if (Object.keys(connection.serverInfo).length === 0) {
throw new Error('Version check not possible as the client is not yet ready or did not expose the version'); throw new Error('Version check not possible as the client is not yet ready or did not expose the version');
} }
// Return true if the server version >= desired_version // Return true if the server version >= desiredVersion
var version = connection.server_info.versions; var version = connection.serverInfo.versions;
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
if (version[i] > desired_version[i]) { if (version[i] > desiredVersion[i]) {
return true; return true;
} }
if (version[i] < desired_version[i]) { if (version[i] < desiredVersion[i]) {
if (this.skip) this.skip(); if (this.skip) this.skip();
return false; return false;
} }
@@ -166,9 +166,9 @@ module.exports = {
protocols.push('IPv6', '/tmp/redis.sock'); protocols.push('IPv6', '/tmp/redis.sock');
} }
var options = [{ var options = [{
detect_buffers: true detectBuffers: true
}, { }, {
detect_buffers: false detectBuffers: false
}]; }];
options.forEach(function (options) { options.forEach(function (options) {
var strOptions = ''; var strOptions = '';
@@ -209,7 +209,7 @@ module.exports = {
}, },
killConnection: function (client) { killConnection: function (client) {
// Change the connection option to a non existing one and destroy the stream // Change the connection option to a non existing one and destroy the stream
client.connection_options = { client.connectionOptions = {
port: 65535, port: 65535,
host: '127.0.0.1', host: '127.0.0.1',
family: 4 family: 4

View File

@@ -1,4 +1,4 @@
// Spawned by the good_stacks.spec.js tests // Spawned by the goodStacks.spec.js tests
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');

View File

@@ -16,15 +16,15 @@ function once (cb) {
}; };
} }
function StunnelProcess (conf_dir) { function StunnelProcess (confDir) {
EventEmitter.call(this); EventEmitter.call(this);
// set up an stunnel to redis; edit the conf file to include required absolute paths // set up an stunnel to redis; edit the conf file to include required absolute paths
var conf_file = path.resolve(conf_dir, 'stunnel.conf'); var confFile = path.resolve(confDir, 'stunnel.conf');
var conf_text = fs.readFileSync(conf_file + '.template').toString().replace(/__dirname/g, conf_dir); var confText = fs.readFileSync(confFile + '.template').toString().replace(/__dirname,/g, confDir);
fs.writeFileSync(conf_file, conf_text); fs.writeFileSync(confFile, confText);
var stunnel = this.stunnel = spawn('stunnel', [conf_file]); var stunnel = this.stunnel = spawn('stunnel', [confFile]);
// handle child process events, and failure to set up tunnel // handle child process events, and failure to set up tunnel
var self = this; var self = this;
@@ -68,9 +68,9 @@ StunnelProcess.prototype.stop = function (done) {
}; };
module.exports = { module.exports = {
start: function (done, conf_dir) { start: function (done, confDir) {
done = once(done); done = once(done);
var stunnel = new StunnelProcess(conf_dir); var stunnel = new StunnelProcess(confDir);
stunnel.once('error', done.bind(done)); stunnel.once('error', done.bind(done));
stunnel.once('started', done.bind(done, null, stunnel)); stunnel.once('started', done.bind(done, null, stunnel));
}, },

View File

@@ -1,4 +1,4 @@
// spawned by the unref tests in node_redis.spec.js. // spawned by the unref tests in nodeRedis.spec.js.
// when configured, unref causes the client to exit // when configured, unref causes the client to exit
// as soon as there are no outstanding commands. // as soon as there are no outstanding commands.
'use strict'; 'use strict';

View File

@@ -22,8 +22,8 @@ describe("The 'multi' method", function () {
var end = helper.callFuncAfter(done, 100); var end = helper.callFuncAfter(done, 100);
// Some random object created from http://beta.json-generator.com/ // Some random object created from http://beta.json-generator.com/
var test_obj = { var testObj = {
'_id': '5642c4c33d4667c4a1fefd99', 'index': 0, 'guid': '5baf1f1c-7621-41e7-ae7a-f8c6f3199b0f', 'isActive': true, 'Id': '5642c4c33d4667c4a1fefd99', 'index': 0, 'guid': '5baf1f1c-7621-41e7-ae7a-f8c6f3199b0f', 'isActive': true,
'balance': '$1,028.63', 'picture': 'http://placehold.it/32x32', 'age': 31, 'eyeColor': 'green', 'name': {'first': 'Shana', 'last': 'Long'}, 'balance': '$1,028.63', 'picture': 'http://placehold.it/32x32', 'age': 31, 'eyeColor': 'green', 'name': {'first': 'Shana', 'last': 'Long'},
'company': 'MANGLO', 'email': 'shana.long@manglo.us', 'phone': '+1 (926) 405-3105', 'address': '747 Dank Court, Norfolk, Ohio, 1112', 'company': 'MANGLO', 'email': 'shana.long@manglo.us', 'phone': '+1 (926) 405-3105', 'address': '747 Dank Court, Norfolk, Ohio, 1112',
'about': 'Eu pariatur in nisi occaecat enim qui consequat nostrud cupidatat id. ' + 'about': 'Eu pariatur in nisi occaecat enim qui consequat nostrud cupidatat id. ' +
@@ -38,14 +38,14 @@ describe("The 'multi' method", function () {
return; return;
} }
// To demonstrate a big payload for hash set field values, let's create a big array // To demonstrate a big payload for hash set field values, let's create a big array
var test_arr = []; var testArr = [];
var i = 0; var i = 0;
for (; i < 80; i++) { for (; i < 80; i++) {
var new_obj = JSON.parse(JSON.stringify(test_obj)); var newObj = JSON.parse(JSON.stringify(testObj));
test_arr.push(new_obj); testArr.push(newObj);
} }
var json = JSON.stringify(test_arr); var json = JSON.stringify(testArr);
zlib.deflate(new Buffer(json), function (err, buffer) { zlib.deflate(new Buffer(json), function (err, buffer) {
if (err) { if (err) {
done(err); done(err);
@@ -165,13 +165,13 @@ describe("The 'multi' method", function () {
}); });
// Check if Redis still has the error // Check if Redis still has the error
client.monitor(); client.monitor();
client.send_command('multi'); client.sendCommand('multi');
client.send_command('set', ['foo', 'bar']); client.sendCommand('set', ['foo', 'bar']);
client.send_command('get', ['foo']); client.sendCommand('get', ['foo']);
client.send_command('exec', function (err, res) { client.sendCommand('exec', function (err, res) {
// res[0] is going to be the monitor result of set // res[0] is going to be the monitor result of set
// res[1] is going to be the result of the set command // res[1] is going to be the result of the set command
assert(utils.monitor_regex.test(res[0])); assert(utils.monitorRegex.test(res[0]));
assert.strictEqual(res[1], 'OK'); assert.strictEqual(res[1], 'OK');
assert.strictEqual(res.length, 2); assert.strictEqual(res.length, 2);
client.end(false); client.end(false);
@@ -184,7 +184,7 @@ describe("The 'multi' method", function () {
multi1.set('m1', '123'); multi1.set('m1', '123');
multi1.get('m1'); multi1.get('m1');
multi1.exec(done); multi1.exec(done);
assert.strictEqual(client.offline_queue.length, 4); assert.strictEqual(client.offlineQueue.length, 4);
}); });
it('executes a pipelined multi properly after a reconnect in combination with the offline queue', function (done) { it('executes a pipelined multi properly after a reconnect in combination with the offline queue', function (done) {
@@ -328,15 +328,15 @@ describe("The 'multi' method", function () {
multi1.exec(function () { multi1.exec(function () {
// Redis 2.6.5+ will abort transactions with errors // Redis 2.6.5+ will abort transactions with errors
// see: http://redis.io/topics/transactions // see: http://redis.io/topics/transactions
var multibar_expected = 1; var multibarExpected = 1;
var multifoo_expected = 1; var multifooExpected = 1;
// Confirm that the previous command, while containing an error, still worked. // Confirm that the previous command, while containing an error, still worked.
multi2 = client.multi(); multi2 = client.multi();
multi2.incr('multibar', helper.isNumber(multibar_expected)); multi2.incr('multibar', helper.isNumber(multibarExpected));
multi2.incr('multifoo', helper.isNumber(multifoo_expected)); multi2.incr('multifoo', helper.isNumber(multifooExpected));
multi2.exec(function (err, replies) { multi2.exec(function (err, replies) {
assert.strictEqual(multibar_expected, replies[0]); assert.strictEqual(multibarExpected, replies[0]);
assert.strictEqual(multifoo_expected, replies[1]); assert.strictEqual(multifooExpected, replies[1]);
return done(); return done();
}); });
}); });
@@ -608,20 +608,20 @@ describe("The 'multi' method", function () {
client.get('foo', helper.isString('bar', done)); client.get('foo', helper.isString('bar', done));
}); });
it('should not use a transaction with exec_atomic if no command is used', function () { it('should not use a transaction with execAtomic if no command is used', function () {
var multi = client.multi(); var multi = client.multi();
var test = false; var test = false;
multi.exec_batch = function () { multi.execBatch = function () {
test = true; test = true;
}; };
multi.exec_atomic(); multi.execAtomic();
assert(test); assert(test);
}); });
it('should not use a transaction with exec_atomic if only one command is used', function () { it('should not use a transaction with execAtomic if only one command is used', function () {
var multi = client.multi(); var multi = client.multi();
var test = false; var test = false;
multi.exec_batch = function () { multi.execBatch = function () {
test = true; test = true;
}; };
multi.set('baz', 'binary'); multi.set('baz', 'binary');
@@ -629,15 +629,15 @@ describe("The 'multi' method", function () {
assert(test); assert(test);
}); });
it('should use transaction with exec_atomic and more than one command used', function (done) { it('should use transaction with execAtomic and more than one command used', function (done) {
var multi = client.multi(); var multi = client.multi();
var test = false; var test = false;
multi.exec_batch = function () { multi.execBatch = function () {
test = true; test = true;
}; };
multi.set('baz', 'binary'); multi.set('baz', 'binary');
multi.get('baz'); multi.get('baz');
multi.exec_atomic(done); multi.execAtomic(done);
assert(!test); assert(!test);
}); });
@@ -695,23 +695,23 @@ describe("The 'multi' method", function () {
// subscribe => enters subscribe mode and this does not work in combination with exec (the same for psubscribe, unsubscribe...) // subscribe => enters subscribe mode and this does not work in combination with exec (the same for psubscribe, unsubscribe...)
// //
// Make sure send_command is not called // Make sure sendCommand is not called
client.send_command = function () { client.sendCommand = function () {
throw new Error('failed'); throw new Error('failed');
}; };
assert.strictEqual(client.selected_db, undefined); assert.strictEqual(client.selectedDb, undefined);
var multi = client.multi(); var multi = client.multi();
multi.select(5, function (err, res) { multi.select(5, function (err, res) {
assert.strictEqual(client.selected_db, 5); assert.strictEqual(client.selectedDb, 5);
assert.strictEqual(res, 'OK'); assert.strictEqual(res, 'OK');
assert.notDeepEqual(client.server_info.db5, { avg_ttl: 0, expires: 0, keys: 1 }); assert.notDeepEqual(client.serverInfo.db5, { avg_ttl: 0, expires: 0, keys: 1 });
}); });
// multi.client('reply', 'on', helper.isString('OK')); // Redis v.3.2 // multi.client('reply', 'on', helper.isString('OK')); // Redis v.3.2
multi.set('foo', 'bar', helper.isString('OK')); multi.set('foo', 'bar', helper.isString('OK'));
multi.info(function (err, res) { multi.info(function (err, res) {
assert.strictEqual(res.indexOf('# Server\r\nredis_version:'), 0); assert.strictEqual(res.indexOf('# Server\r\nredis_version:'), 0);
assert.deepEqual(client.server_info.db5, { avg_ttl: 0, expires: 0, keys: 1 }); assert.deepEqual(client.serverInfo.db5, { avg_ttl: 0, expires: 0, keys: 1 });
}); });
multi.get('foo', helper.isString('bar')); multi.get('foo', helper.isString('bar'));
multi.exec(function (err, res) { multi.exec(function (err, res) {

View File

@@ -10,21 +10,21 @@ var fork = require('child_process').fork;
var redis = config.redis; var redis = config.redis;
var client; var client;
describe('The node_redis client', function () { describe('The nodeRedis client', function () {
it('individual commands sanity check', function (done) { it('individual commands sanity check', function (done) {
// All commands should work the same in multi context or without // All commands should work the same in multi context or without
// Therefor individual commands always have to be handled in both cases // Therefor individual commands always have to be handled in both cases
fs.readFile(path.resolve(__dirname, '../lib/individualCommands.js'), 'utf8', function (err, data) { fs.readFile(path.resolve(__dirname, '../lib/individualCommands.js'), 'utf8', function (err, data) {
var client_prototype = data.match(/(\n| = )RedisClient\.prototype.[a-zA-Z_]+/g); var clientPrototype = data.match(/(\n| = )RedisClient\.prototype.[a-zA-Z_]+/g);
var multi_prototype = data.match(/(\n| = )Multi\.prototype\.[a-zA-Z_]+/g); var multiPrototype = data.match(/(\n| = )Multi\.prototype\.[a-zA-Z_]+/g);
// Check that every entry RedisClient entry has a correspondend Multi entry // Check that every entry RedisClient entry has a correspondend Multi entry
assert.strictEqual(client_prototype.filter(function (entry) { assert.strictEqual(clientPrototype.filter(function (entry) {
return multi_prototype.indexOf(entry.replace('RedisClient', 'Multi')) === -1; return multiPrototype.indexOf(entry.replace('RedisClient', 'Multi')) === -1;
}).length, 4); // multi and batch are included too }).length, 4); // multi and batch are included too
assert.strictEqual(client_prototype.length, multi_prototype.length + 4); assert.strictEqual(clientPrototype.length, multiPrototype.length + 4);
// Check that all entries exist in uppercase and in lowercase variants // Check that all entries exist in uppercase and in lowercase variants
assert.strictEqual(data.match(/(\n| = )RedisClient\.prototype.[a-z_]+/g).length * 2, client_prototype.length); assert.strictEqual(data.match(/(\n| = )RedisClient\.prototype.[a-z_]+/g).length * 2, clientPrototype.length);
done(); done();
}); });
}); });
@@ -46,13 +46,13 @@ describe('The node_redis client', function () {
}); });
client.once('reconnecting', function () { client.once('reconnecting', function () {
process.nextTick(function () { process.nextTick(function () {
assert.strictEqual(client.reply_parser.buffer, null); assert.strictEqual(client.replyParser.buffer, null);
done(); done();
}); });
}); });
var partialInput = new Buffer('$100\r\nabcdef'); var partialInput = new Buffer('$100\r\nabcdef');
client.reply_parser.execute(partialInput); client.replyParser.execute(partialInput);
assert.strictEqual(client.reply_parser.buffer.inspect(), partialInput.inspect()); assert.strictEqual(client.replyParser.buffer.inspect(), partialInput.inspect());
client.stream.destroy(); client.stream.destroy();
}); });
@@ -74,10 +74,10 @@ describe('The node_redis client', function () {
describe('duplicate', function () { describe('duplicate', function () {
it('check if all options got copied properly', function (done) { it('check if all options got copied properly', function (done) {
client.selected_db = 2; client.selectedDb = 2;
var client2 = client.duplicate(); var client2 = client.duplicate();
assert.strictEqual(client.connectionId + 1, client2.connection_id); assert.strictEqual(client.connectionId + 1, client2.connectionId);
assert.strictEqual(client2.selected_db, 2); assert.strictEqual(client2.selectedDb, 2);
assert(client.connected); assert(client.connected);
assert(!client2.connected); assert(!client2.connected);
for (var elem in client.options) { for (var elem in client.options) {
@@ -99,16 +99,16 @@ describe('The node_redis client', function () {
it('check if all new options replaced the old ones', function (done) { it('check if all new options replaced the old ones', function (done) {
var client2 = client.duplicate({ var client2 = client.duplicate({
no_ready_check: true noReadyCheck: true
}); });
assert(client.connected); assert(client.connected);
assert(!client2.connected); assert(!client2.connected);
assert.strictEqual(client.options.no_ready_check, undefined); assert.strictEqual(client.options.noReadyCheck, undefined);
assert.strictEqual(client2.options.no_ready_check, true); assert.strictEqual(client2.options.noReadyCheck, true);
assert.notDeepEqual(client.options, client2.options); assert.notDeepEqual(client.options, client2.options);
for (var elem in client.options) { for (var elem in client.options) {
if (client.options.hasOwnProperty(elem)) { if (client.options.hasOwnProperty(elem)) {
if (elem !== 'no_ready_check') { if (elem !== 'noReadyCheck') {
assert.strictEqual(client2.options[elem], client.options[elem]); assert.strictEqual(client2.options[elem], client.options[elem]);
} }
} }
@@ -173,12 +173,12 @@ describe('The node_redis client', function () {
str += str; str += str;
} }
var called = false; var called = false;
var temp = client.write_buffers.bind(client); var temp = client.writeBuffers.bind(client);
assert(client.fire_strings); assert(client.fireStrings);
client.write_buffers = function (data) { client.writeBuffers = function (data) {
called = true; called = true;
// To increase write performance for strings the value is converted to a buffer // To increase write performance for strings the value is converted to a buffer
assert(!client.fire_strings); assert(!client.fireStrings);
temp(data); temp(data);
}; };
client.multi().set('foo', str).get('foo', function (err, res) { client.multi().set('foo', str).get('foo', function (err, res) {
@@ -188,46 +188,46 @@ describe('The node_redis client', function () {
assert.strictEqual(res[1], str); assert.strictEqual(res[1], str);
done(); done();
}); });
assert(client.fire_strings); assert(client.fireStrings);
}); });
}); });
describe('send_command', function () { describe('sendCommand', function () {
it('omitting args should be fine', function (done) { it('omitting args should be fine', function (done) {
client.server_info = {}; client.serverInfo = {};
client.send_command('info'); client.sendCommand('info');
client.send_command('ping', function (err, res) { client.sendCommand('ping', function (err, res) {
assert.strictEqual(res, 'PONG'); assert.strictEqual(res, 'PONG');
// Check if the previous info command used the internal individual info command // Check if the previous info command used the internal individual info command
assert.notDeepEqual(client.server_info, {}); assert.notDeepEqual(client.serverInfo, {});
client.server_info = {}; client.serverInfo = {};
}); });
client.send_command('info', null, undefined); client.sendCommand('info', null, undefined);
client.send_command('ping', null, function (err, res) { client.sendCommand('ping', null, function (err, res) {
assert.strictEqual(res, 'PONG'); assert.strictEqual(res, 'PONG');
// Check if the previous info command used the internal individual info command // Check if the previous info command used the internal individual info command
assert.notDeepEqual(client.server_info, {}); assert.notDeepEqual(client.serverInfo, {});
client.server_info = {}; client.serverInfo = {};
}); });
client.send_command('info', undefined, undefined); client.sendCommand('info', undefined, undefined);
client.send_command('ping', function (err, res) { client.sendCommand('ping', function (err, res) {
assert.strictEqual(res, 'PONG'); assert.strictEqual(res, 'PONG');
// Check if the previous info command used the internal individual info command // Check if the previous info command used the internal individual info command
assert.notDeepEqual(client.server_info, {}); assert.notDeepEqual(client.serverInfo, {});
client.server_info = {}; client.serverInfo = {};
}); });
client.send_command('info', undefined, function (err, res) { client.sendCommand('info', undefined, function (err, res) {
assert(/redis_version/.test(res)); assert(/redis_version/.test(res));
// The individual info command should also be called by using send_command // The individual info command should also be called by using sendCommand
// console.log(info, client.server_info); // console.log(info, client.serverInfo);
assert.notDeepEqual(client.server_info, {}); assert.notDeepEqual(client.serverInfo, {});
done(); done();
}); });
}); });
it('using multi with sendCommand should work as individual command instead of using the internal multi', function (done) { it('using multi with sendCommand should work as individual command instead of using the internal multi', function (done) {
// This is necessary to keep backwards compatibility and it is the only way to handle multis as you want in node_redis // This is necessary to keep backwards compatibility and it is the only way to handle multis as you want in nodeRedis
client.sendCommand('multi'); client.sendCommand('multi');
client.sendCommand('set', ['foo', 'bar'], helper.isString('QUEUED')); client.sendCommand('set', ['foo', 'bar'], helper.isString('QUEUED'));
client.get('foo'); client.get('foo');
@@ -240,9 +240,9 @@ describe('The node_redis client', function () {
}); });
it('multi should be handled special', function (done) { it('multi should be handled special', function (done) {
client.send_command('multi', undefined, helper.isString('OK')); client.sendCommand('multi', undefined, helper.isString('OK'));
var args = ['test', 'bla']; var args = ['test', 'bla'];
client.send_command('set', args, helper.isString('QUEUED')); client.sendCommand('set', args, helper.isString('QUEUED'));
assert.deepEqual(args, ['test', 'bla']); // Check args manipulation assert.deepEqual(args, ['test', 'bla']); // Check args manipulation
client.get('test', helper.isString('QUEUED')); client.get('test', helper.isString('QUEUED'));
client.exec(function (err, res) { client.exec(function (err, res) {
@@ -255,13 +255,13 @@ describe('The node_redis client', function () {
it('using another type as cb should throw', function () { it('using another type as cb should throw', function () {
try { try {
client.send_command('set', ['test', 'bla'], [true]); client.sendCommand('set', ['test', 'bla'], [true]);
throw new Error('failed'); throw new Error('failed');
} catch (err) { } catch (err) {
assert.strictEqual(err.message, 'Wrong input type "Array" for callback function'); assert.strictEqual(err.message, 'Wrong input type "Array" for callback function');
} }
try { try {
client.send_command('set', ['test', 'bla'], null); client.sendCommand('set', ['test', 'bla'], null);
throw new Error('failed'); throw new Error('failed');
} catch (err) { } catch (err) {
assert.strictEqual(err.message, 'Wrong input type "null" for callback function'); assert.strictEqual(err.message, 'Wrong input type "null" for callback function');
@@ -270,19 +270,19 @@ describe('The node_redis client', function () {
it('command argument has to be of type string', function () { it('command argument has to be of type string', function () {
try { try {
client.send_command(true, ['test', 'bla'], function () {}); client.sendCommand(true, ['test', 'bla'], function () {});
throw new Error('failed'); throw new Error('failed');
} catch (err) { } catch (err) {
assert.strictEqual(err.message, 'Wrong input type "Boolean" for command name'); assert.strictEqual(err.message, 'Wrong input type "Boolean" for command name');
} }
try { try {
client.send_command(undefined, ['test', 'bla'], function () {}); client.sendCommand(undefined, ['test', 'bla'], function () {});
throw new Error('failed'); throw new Error('failed');
} catch (err) { } catch (err) {
assert.strictEqual(err.message, 'Wrong input type "undefined" for command name'); assert.strictEqual(err.message, 'Wrong input type "undefined" for command name');
} }
try { try {
client.send_command(null, ['test', 'bla'], function () {}); client.sendCommand(null, ['test', 'bla'], function () {});
throw new Error('failed'); throw new Error('failed');
} catch (err) { } catch (err) {
assert.strictEqual(err.message, 'Wrong input type "null" for command name'); assert.strictEqual(err.message, 'Wrong input type "null" for command name');
@@ -291,7 +291,7 @@ describe('The node_redis client', function () {
it('args may only be of type Array or undefined', function () { it('args may only be of type Array or undefined', function () {
try { try {
client.send_command('info', 123); client.sendCommand('info', 123);
throw new Error('failed'); throw new Error('failed');
} catch (err) { } catch (err) {
assert.strictEqual(err.message, 'Wrong input type "Number" for args'); assert.strictEqual(err.message, 'Wrong input type "Number" for args');
@@ -300,7 +300,7 @@ describe('The node_redis client', function () {
it('passing a callback as args and as callback should throw', function () { it('passing a callback as args and as callback should throw', function () {
try { try {
client.send_command('info', function a () {}, function b () {}); client.sendCommand('info', function a () {}, function b () {});
throw new Error('failed'); throw new Error('failed');
} catch (err) { } catch (err) {
assert.strictEqual(err.message, 'Wrong input type "Function" for args'); assert.strictEqual(err.message, 'Wrong input type "Function" for args');
@@ -308,9 +308,9 @@ describe('The node_redis client', function () {
}); });
it('multi should be handled special', function (done) { it('multi should be handled special', function (done) {
client.send_command('multi', undefined, helper.isString('OK')); client.sendCommand('multi', undefined, helper.isString('OK'));
var args = ['test', 'bla']; var args = ['test', 'bla'];
client.send_command('set', args, helper.isString('QUEUED')); client.sendCommand('set', args, helper.isString('QUEUED'));
assert.deepEqual(args, ['test', 'bla']); // Check args manipulation assert.deepEqual(args, ['test', 'bla']); // Check args manipulation
client.get('test', helper.isString('QUEUED')); client.get('test', helper.isString('QUEUED'));
client.exec(function (err, res) { client.exec(function (err, res) {
@@ -322,7 +322,7 @@ describe('The node_redis client', function () {
}); });
it('the args array may contain a arbitrary number of arguments', function (done) { it('the args array may contain a arbitrary number of arguments', function (done) {
client.send_command('mset', ['foo', 1, 'bar', 2, 'baz', 3], helper.isString('OK')); client.sendCommand('mset', ['foo', 1, 'bar', 2, 'baz', 3], helper.isString('OK'));
client.mget(['foo', 'bar', 'baz'], function (err, res) { client.mget(['foo', 'bar', 'baz'], function (err, res) {
// As the multi command is handled individually by the user he also has to handle the return value // As the multi command is handled individually by the user he also has to handle the return value
assert.strictEqual(res[0].toString(), '1'); assert.strictEqual(res[0].toString(), '1');
@@ -332,8 +332,8 @@ describe('The node_redis client', function () {
}); });
}); });
it('send_command with callback as args', function (done) { it('sendCommand with callback as args', function (done) {
client.send_command('abcdef', function (err, res) { client.sendCommand('abcdef', function (err, res) {
assert.strictEqual(err.message, "ERR unknown command 'abcdef'"); assert.strictEqual(err.message, "ERR unknown command 'abcdef'");
done(); done();
}); });
@@ -341,11 +341,11 @@ describe('The node_redis client', function () {
}); });
describe('retry_unfulfilled_commands', function () { describe('retryUnfulfilledCommands', function () {
it('should retry all commands instead of returning an error if a command did not yet return after a connection loss', function (done) { it('should retry all commands instead of returning an error if a command did not yet return after a connection loss', function (done) {
var bclient = redis.createClient({ var bclient = redis.createClient({
retry_unfulfilled_commands: true retryUnfulfilledCommands: true
}); });
bclient.blpop('blocking list 2', 5, function (err, value) { bclient.blpop('blocking list 2', 5, function (err, value) {
assert.strictEqual(value[0], 'blocking list 2'); assert.strictEqual(value[0], 'blocking list 2');
@@ -426,8 +426,8 @@ describe('The node_redis client', function () {
} }
}); });
it('emits an aggregate error if no callback was present for multiple commands in debug_mode', function (done) { it('emits an aggregate error if no callback was present for multiple commands in debugMode', function (done) {
redis.debug_mode = true; redis.debugMode = true;
var unhookIntercept = intercept(function (data) { var unhookIntercept = intercept(function (data) {
return ''; // Don't print the debug messages return ''; // Don't print the debug messages
}); });
@@ -449,11 +449,11 @@ describe('The node_redis client', function () {
}); });
client.end(true); client.end(true);
unhookIntercept(); unhookIntercept();
redis.debug_mode = false; redis.debugMode = false;
}); });
it('emits an abort error if no callback was present for a single commands', function (done) { it('emits an abort error if no callback was present for a single commands', function (done) {
redis.debug_mode = true; redis.debugMode = true;
var unhookIntercept = intercept(function (data) { var unhookIntercept = intercept(function (data) {
return ''; // Don't print the debug messages return ''; // Don't print the debug messages
}); });
@@ -470,10 +470,10 @@ describe('The node_redis client', function () {
}); });
client.end(true); client.end(true);
unhookIntercept(); unhookIntercept();
redis.debug_mode = false; redis.debugMode = false;
}); });
it('does not emit abort errors if no callback was present while not being in debug_mode ', function (done) { it('does not emit abort errors if no callback was present while not being in debugMode ', function (done) {
client.set('foo', 'bar'); client.set('foo', 'bar');
client.end(true); client.end(true);
setTimeout(done, 100); setTimeout(done, 100);
@@ -492,7 +492,7 @@ describe('The node_redis client', function () {
client.quit(function () { client.quit(function () {
client.get('foo', function (err, res) { client.get('foo', function (err, res) {
assert.strictEqual(err.message, 'Stream connection ended and command aborted. It might have been processed.'); assert.strictEqual(err.message, 'Stream connection ended and command aborted. It might have been processed.');
assert.strictEqual(client.offline_queue.length, 0); assert.strictEqual(client.offlineQueue.length, 0);
done(); done();
}); });
}); });
@@ -506,7 +506,7 @@ describe('The node_redis client', function () {
client.get('foo', function (err, res) { client.get('foo', function (err, res) {
assert.strictEqual(err.message, 'GET can\'t be processed. The connection is already closed.'); assert.strictEqual(err.message, 'GET can\'t be processed. The connection is already closed.');
assert.strictEqual(err.command, 'GET'); assert.strictEqual(err.command, 'GET');
assert.strictEqual(client.offline_queue.length, 0); assert.strictEqual(client.offlineQueue.length, 0);
done(); done();
}); });
}, 50); }, 50);
@@ -518,7 +518,7 @@ describe('The node_redis client', function () {
client.on('error', function (err) { client.on('error', function (err) {
assert.strictEqual(err.message, 'SET can\'t be processed. The connection is already closed.'); assert.strictEqual(err.message, 'SET can\'t be processed. The connection is already closed.');
assert.strictEqual(err.command, 'SET'); assert.strictEqual(err.command, 'SET');
assert.strictEqual(client.offline_queue_length, 0); assert.strictEqual(client.offlineQueue.length, 0);
done(); done();
}); });
setTimeout(function () { setTimeout(function () {
@@ -530,13 +530,13 @@ describe('The node_redis client', function () {
describe('when redis closes unexpectedly', function () { describe('when redis closes unexpectedly', function () {
it('reconnects and can retrieve the pre-existing data', function (done) { it('reconnects and can retrieve the pre-existing data', function (done) {
client.on('reconnecting', function on_recon (params) { client.on('reconnecting', function onRecon (params) {
client.on('connect', function on_connect () { client.on('connect', function onConnect () {
var end = helper.callFuncAfter(function () { var end = helper.callFuncAfter(function () {
client.removeListener('connect', on_connect); client.removeListener('connect', onConnect);
client.removeListener('reconnecting', on_recon); client.removeListener('reconnecting', onRecon);
assert.strictEqual(client.server_info.db0.keys, 2); assert.strictEqual(client.serverInfo.db0.keys, 2);
assert.strictEqual(Object.keys(client.server_info.db0).length, 3); assert.strictEqual(Object.keys(client.serverInfo.db0).length, 3);
done(); done();
}, 4); }, 4);
client.get('recon 1', helper.isString('one', end)); client.get('recon 1', helper.isString('one', end));
@@ -555,11 +555,11 @@ describe('The node_redis client', function () {
}); });
it('reconnects properly when monitoring', function (done) { it('reconnects properly when monitoring', function (done) {
client.on('reconnecting', function on_recon (params) { client.on('reconnecting', function onRecon (params) {
client.on('ready', function on_ready () { client.on('ready', function onReady () {
assert.strictEqual(client.monitoring, true, 'monitoring after reconnect'); assert.strictEqual(client.monitoring, true, 'monitoring after reconnect');
client.removeListener('ready', on_ready); client.removeListener('ready', onReady);
client.removeListener('reconnecting', on_recon); client.removeListener('reconnecting', onRecon);
done(); done();
}); });
}); });
@@ -579,7 +579,7 @@ describe('The node_redis client', function () {
describe("and it's subscribed to a channel", function () { describe("and it's subscribed to a channel", function () {
// "Connection in subscriber mode, only subscriber commands may be used" // "Connection in subscriber mode, only subscriber commands may be used"
it('reconnects, unsubscribes, and can retrieve the pre-existing data', function (done) { it('reconnects, unsubscribes, and can retrieve the pre-existing data', function (done) {
client.on('ready', function on_connect () { client.on('ready', function onConnect () {
client.unsubscribe(helper.isNotError()); client.unsubscribe(helper.isNotError());
client.on('unsubscribe', function (channel, count) { client.on('unsubscribe', function (channel, count) {
@@ -599,7 +599,7 @@ describe('The node_redis client', function () {
}); });
it('reconnects, unsubscribes, and can retrieve the pre-existing data of a explicit channel', function (done) { it('reconnects, unsubscribes, and can retrieve the pre-existing data of a explicit channel', function (done) {
client.on('ready', function on_connect () { client.on('ready', function onConnect () {
client.unsubscribe('recon channel', helper.isNotError()); client.unsubscribe('recon channel', helper.isNotError());
client.on('unsubscribe', function (channel, count) { client.on('unsubscribe', function (channel, count) {
@@ -709,7 +709,7 @@ describe('The node_redis client', function () {
monitorClient.on('monitor', function (time, args, rawOutput) { monitorClient.on('monitor', function (time, args, rawOutput) {
assert.strictEqual(monitorClient.monitoring, true); assert.strictEqual(monitorClient.monitoring, true);
responses.push(args); responses.push(args);
assert(utils.monitor_regex.test(rawOutput), rawOutput); assert(utils.monitorRegex.test(rawOutput), rawOutput);
if (responses.length === 6) { if (responses.length === 6) {
assert.deepEqual(responses[0], ['mget', 'some', 'keys', 'foo', 'bar']); assert.deepEqual(responses[0], ['mget', 'some', 'keys', 'foo', 'bar']);
assert.deepEqual(responses[1], ['set', 'json', '{"foo":"123","bar":"sdflkdfsjk","another":false}']); assert.deepEqual(responses[1], ['set', 'json', '{"foo":"123","bar":"sdflkdfsjk","another":false}']);
@@ -722,9 +722,9 @@ describe('The node_redis client', function () {
}); });
}); });
it('monitors returns strings in the rawOutput even with return_buffers activated', function (done) { it('monitors returns strings in the rawOutput even with returnBuffers activated', function (done) {
var monitorClient = redis.createClient({ var monitorClient = redis.createClient({
return_buffers: true returnBuffers: true
}); });
monitorClient.MONITOR(function (err, res) { monitorClient.MONITOR(function (err, res) {
@@ -735,7 +735,7 @@ describe('The node_redis client', function () {
monitorClient.on('monitor', function (time, args, rawOutput) { monitorClient.on('monitor', function (time, args, rawOutput) {
assert.strictEqual(typeof rawOutput, 'string'); assert.strictEqual(typeof rawOutput, 'string');
assert(utils.monitor_regex.test(rawOutput), rawOutput); assert(utils.monitorRegex.test(rawOutput), rawOutput);
assert.deepEqual(args, ['mget', 'hello', 'world']); assert.deepEqual(args, ['mget', 'hello', 'world']);
// Quit immediatly ends monitoring mode and therefore does not stream back the quit command // Quit immediatly ends monitoring mode and therefore does not stream back the quit command
monitorClient.quit(done); monitorClient.quit(done);
@@ -748,7 +748,7 @@ describe('The node_redis client', function () {
client.mget('hello', 'world'); client.mget('hello', 'world');
client.on('monitor', function (time, args, rawOutput) { client.on('monitor', function (time, args, rawOutput) {
assert.strictEqual(client.monitoring, true); assert.strictEqual(client.monitoring, true);
assert(utils.monitor_regex.test(rawOutput), rawOutput); assert(utils.monitorRegex.test(rawOutput), rawOutput);
assert.deepEqual(args, ['mget', 'hello', 'world']); assert.deepEqual(args, ['mget', 'hello', 'world']);
if (i++ === 2) { if (i++ === 2) {
// End after two reconnects // End after two reconnects
@@ -769,7 +769,7 @@ describe('The node_redis client', function () {
}); });
client.on('monitor', function (time, args, rawOutput) { client.on('monitor', function (time, args, rawOutput) {
assert.strictEqual(client.monitoring, true); assert.strictEqual(client.monitoring, true);
assert(utils.monitor_regex.test(rawOutput), rawOutput); assert(utils.monitorRegex.test(rawOutput), rawOutput);
assert.deepEqual(args, ['mget', 'hello', 'world']); assert.deepEqual(args, ['mget', 'hello', 'world']);
if (i++ === 2) { if (i++ === 2) {
// End after two reconnects // End after two reconnects
@@ -822,7 +822,7 @@ describe('The node_redis client', function () {
var called = false; var called = false;
client.on('monitor', function (time, args, rawOutput) { client.on('monitor', function (time, args, rawOutput) {
responses.push(args); responses.push(args);
assert(utils.monitor_regex.test(rawOutput), rawOutput); assert(utils.monitorRegex.test(rawOutput), rawOutput);
if (responses.length === 7) { if (responses.length === 7) {
assert.deepEqual(responses[0], ['subscribe', '/foo', '/bar']); assert.deepEqual(responses[0], ['subscribe', '/foo', '/bar']);
assert.deepEqual(responses[1], ['unsubscribe', '/bar']); assert.deepEqual(responses[1], ['unsubscribe', '/bar']);
@@ -851,10 +851,10 @@ describe('The node_redis client', function () {
describe('utf8', function () { describe('utf8', function () {
it('handles utf-8 keys', function (done) { it('handles utf-8 keys', function (done) {
var utf8_sample = 'ಠ_ಠ'; var utf8Sample = 'ಠ_ಠ';
client.set(['utf8test', utf8_sample], helper.isString('OK')); client.set(['utf8test', utf8Sample], helper.isString('OK'));
client.get(['utf8test'], function (err, obj) { client.get(['utf8test'], function (err, obj) {
assert.strictEqual(utf8_sample, obj); assert.strictEqual(utf8Sample, obj);
done(err); done(err);
}); });
}); });
@@ -904,14 +904,14 @@ describe('The node_redis client', function () {
// assert(fired); // assert(fired);
// done(); // done();
// }); // });
// assert.strictEqual(client.offline_queue.length, 1); // assert.strictEqual(client.offlineQueue.length, 1);
// assert.strictEqual(client.command_queue.length, 1); // assert.strictEqual(client.commandQueue.length, 1);
// client.on('connect', function () { // client.on('connect', function () {
// assert.strictEqual(client.offline_queue.length, 1); // assert.strictEqual(client.offlineQueue.length, 1);
// assert.strictEqual(client.command_queue.length, 1); // assert.strictEqual(client.commandQueue.length, 1);
// }); // });
// client.on('ready', function () { // client.on('ready', function () {
// assert.strictEqual(client.offline_queue.length, 0); // assert.strictEqual(client.offlineQueue.length, 0);
// }); // });
// }); // });
}); });
@@ -942,13 +942,13 @@ describe('The node_redis client', function () {
// ready is called in a reply // ready is called in a reply
process.nextTick(function () { process.nextTick(function () {
// Fail the set answer. Has no corresponding command obj and will therefore land in the error handler and set // Fail the set answer. Has no corresponding command obj and will therefore land in the error handler and set
client.reply_parser.execute(new Buffer('a*1\r*1\r$1`zasd\r\na')); client.replyParser.execute(new Buffer('a*1\r*1\r$1`zasd\r\na'));
}); });
}); });
}); });
}); });
describe('enable_offline_queue', function () { describe('enableOfflineQueue', function () {
describe('true', function () { describe('true', function () {
it('does not return an error and enqueues operation', function (done) { it('does not return an error and enqueues operation', function (done) {
client = redis.createClient(9999); client = redis.createClient(9999);
@@ -964,7 +964,7 @@ describe('The node_redis client', function () {
}); });
setTimeout(function () { setTimeout(function () {
assert.strictEqual(client.offline_queue.length, 1); assert.strictEqual(client.offlineQueue.length, 1);
finished = true; finished = true;
done(); done();
}, 25); }, 25);
@@ -974,6 +974,7 @@ describe('The node_redis client', function () {
it.skip('enqueues operation and keep the queue while trying to reconnect', function (done) { it.skip('enqueues operation and keep the queue while trying to reconnect', function (done) {
client = redis.createClient(9999, null, { client = redis.createClient(9999, null, {
retryStrategy: function (options) { retryStrategy: function (options) {
console.log(options)
if (options.attempt < 4) { if (options.attempt < 4) {
return 200; return 200;
} }
@@ -984,7 +985,7 @@ describe('The node_redis client', function () {
client.on('error', function (err) { client.on('error', function (err) {
if (err.code === 'CONNECTION_BROKEN') { if (err.code === 'CONNECTION_BROKEN') {
assert(i, 3); assert(i, 3);
assert.strictEqual(client.offline_queue.length, 0); assert.strictEqual(client.offlineQueue.length, 0);
assert.strictEqual(err.origin.code, 'ECONNREFUSED'); assert.strictEqual(err.origin.code, 'ECONNREFUSED');
if (!(err instanceof redis.AbortError)) { if (!(err instanceof redis.AbortError)) {
done(); done();
@@ -1001,10 +1002,10 @@ describe('The node_redis client', function () {
client.on('reconnecting', function (params) { client.on('reconnecting', function (params) {
i++; i++;
assert.equal(params.attempt, i); assert.equal(params.attempt, i);
assert.strictEqual(params.times_connected, 0); assert.strictEqual(params.timesConnected, 0);
assert(params.error instanceof Error); assert(params.error instanceof Error);
assert(typeof params.total_retry_time === 'number'); assert(typeof params.totalRetryTime === 'number');
assert.strictEqual(client.offline_queue.length, 2); assert.strictEqual(client.offlineQueue.length, 2);
}); });
// Should work with either a callback or without // Should work with either a callback or without
@@ -1012,7 +1013,7 @@ describe('The node_redis client', function () {
client.set('foo', 'bar', function (err, result) { client.set('foo', 'bar', function (err, result) {
assert(i, 3); assert(i, 3);
assert(err); assert(err);
assert.strictEqual(client.offline_queue.length, 0); assert.strictEqual(client.offlineQueue.length, 0);
}); });
}); });
@@ -1031,20 +1032,20 @@ describe('The node_redis client', function () {
multi.set('foo' + (i + 2), 'bar' + (i + 2)); multi.set('foo' + (i + 2), 'bar' + (i + 2));
} }
multi.exec(); multi.exec();
assert.equal(client.command_queue_length, 15); assert.equal(client.commandQueue.length, 15);
helper.killConnection(client); helper.killConnection(client);
}); });
var end = helper.callFuncAfter(done, 3); var end = helper.callFuncAfter(done, 3);
client.on('error', function (err) { client.on('error', function (err) {
if (err.command === 'EXEC') { if (err.command === 'EXEC') {
assert.strictEqual(client.command_queue.length, 0); assert.strictEqual(client.commandQueue.length, 0);
assert.strictEqual(err.errors.length, 9); assert.strictEqual(err.errors.length, 9);
assert.strictEqual(err.errors[1].command, 'SET'); assert.strictEqual(err.errors[1].command, 'SET');
assert.deepEqual(err.errors[1].args, ['foo1', 'bar1']); assert.deepEqual(err.errors[1].args, ['foo1', 'bar1']);
end(); end();
} else if (err.code === 'UNCERTAIN_STATE') { } else if (err.code === 'UNCERTAIN_STATE') {
assert.strictEqual(client.command_queue.length, 0); assert.strictEqual(client.commandQueue.length, 0);
assert.strictEqual(err.errors.length, 4); assert.strictEqual(err.errors.length, 4);
assert.strictEqual(err.errors[0].command, 'SET'); assert.strictEqual(err.errors[0].command, 'SET');
assert.deepEqual(err.errors[0].args, ['foo0', 'bar0']); assert.deepEqual(err.errors[0].args, ['foo0', 'bar0']);
@@ -1063,7 +1064,7 @@ describe('The node_redis client', function () {
it('stream not writable', function (done) { it('stream not writable', function (done) {
client = redis.createClient({ client = redis.createClient({
enable_offline_queue: false enableOfflineQueue: false
}); });
client.on('ready', function () { client.on('ready', function () {
client.stream.destroy(); client.stream.destroy();
@@ -1076,13 +1077,13 @@ describe('The node_redis client', function () {
it('emit an error and does not enqueues operation', function (done) { it('emit an error and does not enqueues operation', function (done) {
client = redis.createClient(9999, null, { client = redis.createClient(9999, null, {
enable_offline_queue: false enableOfflineQueue: false
}); });
var end = helper.callFuncAfter(done, 3); var end = helper.callFuncAfter(done, 3);
client.on('error', function (err) { client.on('error', function (err) {
assert(/offline queue is deactivated|ECONNREFUSED/.test(err.message)); assert(/offline queue is deactivated|ECONNREFUSED/.test(err.message));
assert.equal(client.command_queue.length, 0); assert.equal(client.commandQueue.length, 0);
end(); end();
}); });
@@ -1099,10 +1100,10 @@ describe('The node_redis client', function () {
it('flushes the command queue if connection is lost', function (done) { it('flushes the command queue if connection is lost', function (done) {
client = redis.createClient({ client = redis.createClient({
enable_offline_queue: false enableOfflineQueue: false
}); });
redis.debug_mode = true; redis.debugMode = true;
var unhookIntercept = intercept(function () { var unhookIntercept = intercept(function () {
return ''; return '';
}); });
@@ -1118,13 +1119,13 @@ describe('The node_redis client', function () {
multi.set('foo' + (i + 2), 'bar' + (i + 2)); multi.set('foo' + (i + 2), 'bar' + (i + 2));
} }
multi.exec(); multi.exec();
assert.equal(client.command_queue.length, 15); assert.equal(client.commandQueue.length, 15);
helper.killConnection(client); helper.killConnection(client);
}); });
var end = helper.callFuncAfter(done, 3); var end = helper.callFuncAfter(done, 3);
client.on('error', function (err) { client.on('error', function (err) {
assert.equal(client.command_queue.length, 0); assert.equal(client.commandQueue.length, 0);
if (err.command === 'EXEC') { if (err.command === 'EXEC') {
assert.equal(err.errors.length, 9); assert.equal(err.errors.length, 9);
end(); end();
@@ -1135,7 +1136,7 @@ describe('The node_redis client', function () {
assert.equal(err.code, 'ECONNREFUSED'); assert.equal(err.code, 'ECONNREFUSED');
assert.equal(err.errno, 'ECONNREFUSED'); assert.equal(err.errno, 'ECONNREFUSED');
assert.equal(err.syscall, 'connect'); assert.equal(err.syscall, 'connect');
redis.debug_mode = false; redis.debugMode = false;
client.end(true); client.end(true);
unhookIntercept(); unhookIntercept();
end(); end();

View File

@@ -35,7 +35,7 @@ describe('publish/subscribe', function () {
beforeEach(function (done) { beforeEach(function (done) {
sub.end(false); sub.end(false);
sub = redis.createClient({ sub = redis.createClient({
disable_resubscribing: true disableResubscribing: true
}); });
sub.once('connect', function () { sub.once('connect', function () {
done(); done();
@@ -57,7 +57,7 @@ describe('publish/subscribe', function () {
sub.on('reconnecting', function () { sub.on('reconnecting', function () {
a = true; a = true;
sub.on('ready', function () { sub.on('ready', function () {
assert.strictEqual(sub.command_queue.length, 0); assert.strictEqual(sub.commandQueue.length, 0);
done(); done();
}); });
}); });
@@ -66,11 +66,11 @@ describe('publish/subscribe', function () {
}); });
}); });
describe('string_numbers and pub sub', function () { describe('stringNumbers and pub sub', function () {
beforeEach(function (done) { beforeEach(function (done) {
sub.end(false); sub.end(false);
sub = redis.createClient({ sub = redis.createClient({
string_numbers: true stringNumbers: true
}); });
sub.once('connect', function () { sub.once('connect', function () {
done(); done();
@@ -90,8 +90,8 @@ describe('publish/subscribe', function () {
}); });
sub.subscribe(channel, channel2); sub.subscribe(channel, channel2);
sub.unsubscribe(function (err, res) { // Do not pass a channel here! sub.unsubscribe(function (err, res) { // Do not pass a channel here!
assert.strictEqual(sub.pub_sub_mode, 2); assert.strictEqual(sub.pubSubMode, 2);
assert.deepEqual(sub.subscription_set, {}); assert.deepEqual(sub.subscriptionSet, {});
end(); end();
}); });
sub.set('foo', 'bar', helper.isString('OK')); sub.set('foo', 'bar', helper.isString('OK'));
@@ -121,7 +121,7 @@ describe('publish/subscribe', function () {
var a = false; var a = false;
sub.end(true); sub.end(true);
sub = redis.createClient({ sub = redis.createClient({
detect_buffers: true detectBuffers: true
}); });
sub.on('subscribe', function (chnl, count) { sub.on('subscribe', function (chnl, count) {
if (chnl.inspect() === new Buffer([0xAA, 0xBB, 0x00, 0xF0]).inspect()) { if (chnl.inspect() === new Buffer([0xAA, 0xBB, 0x00, 0xF0]).inspect()) {
@@ -178,7 +178,7 @@ describe('publish/subscribe', function () {
sub.subscribe(channel); sub.subscribe(channel);
}); });
it('handles SUB_UNSUB_MSG_SUB', function (done) { it('handles SUB UNSUB MSG SUB', function (done) {
sub.subscribe('chan8'); sub.subscribe('chan8');
sub.subscribe('chan9'); sub.subscribe('chan9');
sub.unsubscribe('chan9'); sub.unsubscribe('chan9');
@@ -186,7 +186,7 @@ describe('publish/subscribe', function () {
sub.subscribe('chan9', done); sub.subscribe('chan9', done);
}); });
it('handles SUB_UNSUB_MSG_SUB 2', function (done) { it('handles SUB UNSUB MSG SUB 2', function (done) {
sub.psubscribe('abc*', helper.isString('abc*')); sub.psubscribe('abc*', helper.isString('abc*'));
sub.subscribe('xyz'); sub.subscribe('xyz');
sub.unsubscribe('xyz'); sub.unsubscribe('xyz');
@@ -263,7 +263,7 @@ describe('publish/subscribe', function () {
it('handles multiple channels with the same channel name properly, even with buffers', function (done) { it('handles multiple channels with the same channel name properly, even with buffers', function (done) {
var channels = ['a', 'b', 'a', new Buffer('a'), 'c', 'b']; var channels = ['a', 'b', 'a', new Buffer('a'), 'c', 'b'];
var subscribed_channels = [1, 2, 2, 2, 3, 3]; var subscribedChannels = [1, 2, 2, 2, 3, 3];
var i = 0; var i = 0;
sub.subscribe(channels); sub.subscribe(channels);
sub.on('subscribe', function (channel, count) { sub.on('subscribe', function (channel, count) {
@@ -272,7 +272,7 @@ describe('publish/subscribe', function () {
} else { } else {
assert.strictEqual(channel, channels[i].toString()); assert.strictEqual(channel, channels[i].toString());
} }
assert.strictEqual(count, subscribed_channels[i]); assert.strictEqual(count, subscribedChannels[i]);
i++; i++;
}); });
sub.unsubscribe('a', 'c', 'b'); sub.unsubscribe('a', 'c', 'b');
@@ -486,24 +486,25 @@ describe('publish/subscribe', function () {
describe('psubscribe', function () { describe('psubscribe', function () {
it('allows all channels to be subscribed to using a * pattern', function (done) { it('allows all channels to be subscribed to using a * pattern', function (done) {
sub.subscribe('/foo');
var sub2 = redis.createClient({ var sub2 = redis.createClient({
return_buffers: true returnBuffers: true
}); });
sub2.on('ready', function () { sub.subscribe('/foo', function () {
sub2.batch().psubscribe('*', helper.isString('*')).exec(); sub2.on('ready', function () {
sub2.subscribe('/foo'); sub2.batch().psubscribe('*', helper.isString('*')).exec();
sub2.on('pmessage', function (pattern, channel, message) { sub2.subscribe('/foo');
assert.strictEqual(pattern.inspect(), new Buffer('*').inspect()); sub2.on('pmessage', function (pattern, channel, message) {
assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect()); assert.strictEqual(pattern.inspect(), new Buffer('*').inspect());
assert.strictEqual(message.inspect(), new Buffer('hello world').inspect()); assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect());
sub2.quit(done); assert.strictEqual(message.inspect(), new Buffer('hello world').inspect());
sub2.quit(done);
});
pub.pubsub('numsub', '/foo', function (err, res) {
assert.deepEqual(res, ['/foo', 2]);
});
// sub2 is counted twice as it subscribed with psubscribe and subscribe
pub.publish('/foo', 'hello world', helper.isNumber(3));
}); });
pub.pubsub('numsub', '/foo', function (err, res) {
assert.deepEqual(res, ['/foo', 2]);
});
// sub2 is counted twice as it subscribed with psubscribe and subscribe
pub.publish('/foo', 'hello world', helper.isNumber(3));
}); });
}); });
@@ -513,21 +514,14 @@ describe('publish/subscribe', function () {
sub.set('foo', data, function () { sub.set('foo', data, function () {
sub.get('foo'); sub.get('foo');
sub.stream.once('data', function () { sub.stream.once('data', function () {
assert.strictEqual(sub.message_buffers, false); assert.strictEqual(sub.messageBuffers, false);
assert.strictEqual(sub.shouldBuffer, false); assert.strictEqual(sub.shouldBuffer, false);
sub.on('pmessageBuffer', function (pattern, channel, message) { sub.on('pmessageBuffer', function (pattern, channel, message) {
if (parser !== 'javascript' && typeof pattern === 'string') {
pattern = new Buffer(pattern);
channel = new Buffer(channel);
}
assert.strictEqual(pattern.inspect(), new Buffer('*').inspect()); assert.strictEqual(pattern.inspect(), new Buffer('*').inspect());
assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect()); assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect());
sub.quit(end); sub.quit(end);
}); });
if (parser === 'javascript') { assert.notStrictEqual(sub.messageBuffers, sub.buffers);
assert.notStrictEqual(sub.message_buffers, sub.buffers);
}
}); });
var batch = sub.batch(); var batch = sub.batch();
batch.psubscribe('*'); batch.psubscribe('*');
@@ -553,7 +547,7 @@ describe('publish/subscribe', function () {
}); });
pub.publish('/foo', 'hello world', helper.isNumber(2)); pub.publish('/foo', 'hello world', helper.isNumber(2));
}); });
// Either message_buffers or buffers has to be true, but not both at the same time // Either messageBuffers or buffers has to be true, but not both at the same time
sub.on('pmessage', function (pattern, channel, message) { sub.on('pmessage', function (pattern, channel, message) {
assert.strictEqual(pattern, '*'); assert.strictEqual(pattern, '*');
assert.strictEqual(channel, '/foo'); assert.strictEqual(channel, '/foo');

View File

@@ -25,7 +25,7 @@ describe('rename commands', function () {
beforeEach(function (done) { beforeEach(function (done) {
if (helper.redisProcess().spawnFailed()) return done(); if (helper.redisProcess().spawnFailed()) return done();
client = redis.createClient({ client = redis.createClient({
rename_commands: { renameCommands: {
set: '807081f5afa96845a02816a28b7258c3', set: '807081f5afa96845a02816a28b7258c3',
GETRANGE: '9e3102b15cf231c4e9e940f284744fe0' GETRANGE: '9e3102b15cf231c4e9e940f284744fe0'
} }
@@ -120,7 +120,7 @@ describe('rename commands', function () {
client.end(true); client.end(true);
client = redis.createClient({ client = redis.createClient({
rename_commands: { renameCommands: {
set: '807081f5afa96845a02816a28b7258c3' set: '807081f5afa96845a02816a28b7258c3'
}, },
prefix: 'baz' prefix: 'baz'

View File

@@ -5,29 +5,29 @@ var config = require('./lib/config');
var helper = require('./helper'); var helper = require('./helper');
var redis = config.redis; var redis = config.redis;
describe('return_buffers', function () { describe('returnBuffers', function () {
helper.allTests(function (ip, basicArgs) { helper.allTests(function (ip, basicArgs) {
describe('using ' + ip, function () { describe('using ' + ip, function () {
var client; var client;
var args = config.configureClient(ip, { var args = config.configureClient(ip, {
return_buffers: true, returnBuffers: true,
detect_buffers: true detectBuffers: true
}); });
beforeEach(function (done) { beforeEach(function (done) {
client = redis.createClient.apply(null, args); client = redis.createClient.apply(null, args);
var i = 1; var i = 1;
if (args[2].detect_buffers) { if (args[2].detectBuffers) {
// Test if detect_buffer option was deactivated // Test if detectBuffer option was deactivated
assert.strictEqual(client.options.detect_buffers, false); assert.strictEqual(client.options.detectBuffers, false);
args[2].detect_buffers = false; args[2].detectBuffers = false;
i++; i++;
} }
var end = helper.callFuncAfter(done, i); var end = helper.callFuncAfter(done, i);
client.on('warning', function (msg) { client.on('warning', function (msg) {
assert.strictEqual(msg, 'WARNING: You activated return_buffers and detect_buffers at the same time. The return value is always going to be a buffer.'); assert.strictEqual(msg, 'WARNING: You activated returnBuffers and detectBuffers at the same time. The return value is always going to be a buffer.');
end(); end();
}); });
client.once('error', done); client.once('error', done);
@@ -244,7 +244,7 @@ describe('return_buffers', function () {
var message = new Buffer('test message'); var message = new Buffer('test message');
var args = config.configureClient(ip, { var args = config.configureClient(ip, {
return_buffers: true returnBuffers: true
}); });
beforeEach(function (done) { beforeEach(function (done) {

View File

@@ -8,20 +8,20 @@ var path = require('path');
var redis = config.redis; var redis = config.redis;
var utils = require('../lib/utils'); var utils = require('../lib/utils');
var tls_options = { var tlsOptions = {
servername: 'redis.js.org', servername: 'redis.js.org',
rejectUnauthorized: true, rejectUnauthorized: true,
ca: [ String(fs.readFileSync(path.resolve(__dirname, './conf/redis.js.org.cert'))) ] ca: [ String(fs.readFileSync(path.resolve(__dirname, './conf/redis.js.org.cert'))) ]
}; };
var tls_port = 6380; var tlsPort = 6380;
// Use skip instead of returning to indicate what tests really got skipped // Use skip instead of returning to indicate what tests really got skipped
var skip = false; var skip = false;
// Wait until stunnel4 is in the travis whitelist // Wait until stunnel4 is in the travis whitelist
// Check: https://github.com/travis-ci/apt-package-whitelist/issues/403 // Check: https://github.com/travis-ci/apt-package-whitelist/issues/403
// If this is merged, remove the travis env checks // If this is merged, remove the travis env checks
describe('TLS connection tests', function () { describe.skip('TLS connection tests', function () {
before(function (done) { before(function (done) {
// Print the warning when the tests run instead of while starting mocha // Print the warning when the tests run instead of while starting mocha
@@ -53,14 +53,14 @@ describe('TLS connection tests', function () {
describe('on lost connection', function () { describe('on lost connection', function () {
it.skip('emit an error after max retry timeout and do not try to reconnect afterwards', function (done) { it.skip('emit an error after max retry timeout and do not try to reconnect afterwards', function (done) {
if (skip) this.skip(); if (skip) this.skip();
var connect_timeout = 500; // in ms var connectTimeout = 500; // in ms
client = redis.createClient({ client = redis.createClient({
connect_timeout: connect_timeout, connectTimeout: connectTimeout,
port: tls_port, port: tlsPort,
tls: tls_options tls: tlsOptions
}); });
var time = 0; var time = 0;
assert.strictEqual(client.address, '127.0.0.1:' + tls_port); assert.strictEqual(client.address, '127.0.0.1:' + tlsPort);
client.once('ready', function () { client.once('ready', function () {
helper.killConnection(client); helper.killConnection(client);
@@ -73,12 +73,12 @@ describe('TLS connection tests', function () {
client.on('error', function (err) { client.on('error', function (err) {
if (/Redis connection in broken state: connection timeout.*?exceeded./.test(err.message)) { if (/Redis connection in broken state: connection timeout.*?exceeded./.test(err.message)) {
process.nextTick(function () { process.nextTick(function () {
assert.strictEqual(time, connect_timeout); assert.strictEqual(time, connectTimeout);
assert.strictEqual(client.emitted_end, true); assert.strictEqual(client.emittedEnd, true);
assert.strictEqual(client.connected, false); assert.strictEqual(client.connected, false);
assert.strictEqual(client.ready, false); assert.strictEqual(client.ready, false);
assert.strictEqual(client.closing, true); assert.strictEqual(client.closing, true);
assert.strictEqual(time, connect_timeout); assert.strictEqual(time, connectTimeout);
done(); done();
}); });
} }
@@ -90,18 +90,18 @@ describe('TLS connection tests', function () {
it('connect with host and port provided in the tls object', function (done) { it('connect with host and port provided in the tls object', function (done) {
if (skip) this.skip(); if (skip) this.skip();
var tls = utils.clone(tls_options); var tls = utils.clone(tlsOptions);
tls.port = tls_port; tls.port = tlsPort;
tls.host = 'localhost'; tls.host = 'localhost';
client = redis.createClient({ client = redis.createClient({
connect_timeout: 1000, connectTimeout: 1000,
tls: tls tls: tls
}); });
// verify connection is using TCP, not UNIX socket // verify connection is using TCP, not UNIX socket
assert.strictEqual(client.connection_options.host, 'localhost'); assert.strictEqual(client.connectionOptions.host, 'localhost');
assert.strictEqual(client.connection_options.port, tls_port); assert.strictEqual(client.connectionOptions.port, tlsPort);
assert.strictEqual(client.address, 'localhost:' + tls_port); assert.strictEqual(client.address, 'localhost:' + tlsPort);
assert(client.stream.encrypted); assert(client.stream.encrypted);
client.set('foo', 'bar'); client.set('foo', 'bar');
@@ -110,15 +110,15 @@ describe('TLS connection tests', function () {
it('fails to connect because the cert is not correct', function (done) { it('fails to connect because the cert is not correct', function (done) {
if (skip) this.skip(); if (skip) this.skip();
var faulty_cert = utils.clone(tls_options); var faultyCert = utils.clone(tlsOptions);
faulty_cert.ca = [ String(fs.readFileSync(path.resolve(__dirname, './conf/faulty.cert'))) ]; faultyCert.ca = [ String(fs.readFileSync(path.resolve(__dirname, './conf/faulty.cert'))) ];
client = redis.createClient({ client = redis.createClient({
host: 'localhost', host: 'localhost',
connect_timeout: 1000, connectTimeout: 1000,
port: tls_port, port: tlsPort,
tls: faulty_cert tls: faultyCert
}); });
assert.strictEqual(client.address, 'localhost:' + tls_port); assert.strictEqual(client.address, 'localhost:' + tlsPort);
client.on('error', function (err) { client.on('error', function (err) {
assert(/DEPTH_ZERO_SELF_SIGNED_CERT/.test(err.code || err.message), err); assert(/DEPTH_ZERO_SELF_SIGNED_CERT/.test(err.code || err.message), err);
client.end(true); client.end(true);

View File

@@ -122,9 +122,9 @@ describe('createClient options', function () {
}); });
unhookIntercept(); unhookIntercept();
assert.strictEqual(text, assert.strictEqual(text,
'node_redis: WARNING: You passed the db option twice!\n' + 'nodeRedis: WARNING: You passed the db option twice!\n' +
'node_redis: WARNING: You passed the port option twice!\n' + 'nodeRedis: WARNING: You passed the port option twice!\n' +
'node_redis: WARNING: You passed the password option twice!\n' 'nodeRedis: WARNING: You passed the password option twice!\n'
); );
assert.strictEqual(Object.keys(options).length, 5); assert.strictEqual(Object.keys(options).length, 5);
assert.strictEqual(options.option.length, 3); assert.strictEqual(options.option.length, 3);
@@ -162,7 +162,7 @@ describe('createClient options', function () {
unhookIntercept(); unhookIntercept();
assert.strictEqual(Object.keys(options).length, 1); assert.strictEqual(Object.keys(options).length, 1);
assert.strictEqual(options.host, 'abc'); assert.strictEqual(options.host, 'abc');
assert.strictEqual(text, 'node_redis: WARNING: You passed "http" as protocol instead of the "redis" protocol!\n'); assert.strictEqual(text, 'nodeRedis: WARNING: You passed "http" as protocol instead of the "redis" protocol!\n');
}); });
}); });

View File

@@ -28,25 +28,6 @@ describe('utils.js', function () {
assert.strictEqual(Object.keys(b).length, 0); assert.strictEqual(Object.keys(b).length, 0);
}); });
it('transform camelCase options to snake_case and add the camel_case option', function () {
var a = utils.clone({
optionOneTwo: true,
retryStrategy: false,
nested: {
onlyContainCamelCaseOnce: true
},
tls: {
rejectUnauthorized: true
}
});
assert.strictEqual(Object.keys(a).length, 5);
assert.strictEqual(a.option_one_two, true);
assert.strictEqual(a.retry_strategy, false);
assert.strictEqual(a.camel_case, true);
assert.strictEqual(a.tls.rejectUnauthorized, true);
assert.strictEqual(Object.keys(a.nested).length, 1);
});
it('throws on circular data', function () { it('throws on circular data', function () {
try { try {
var a = {}; var a = {};
@@ -59,36 +40,36 @@ describe('utils.js', function () {
}); });
}); });
describe('reply_in_order', function () { describe('replyInOrder', function () {
var err_count = 0; var errCount = 0;
var res_count = 0; var resCount = 0;
var emitted = false; var emitted = false;
var clientMock = { var clientMock = {
emit: function () { emitted = true; }, emit: function () { emitted = true; },
offline_queue: new Queue(), offlineQueue: new Queue(),
command_queue: new Queue() commandQueue: new Queue()
}; };
var create_command_obj = function () { var createCommandObj = function () {
return { return {
callback: function (err, res) { callback: function (err, res) {
if (err) err_count++; if (err) errCount++;
else res_count++; else resCount++;
} }
}; };
}; };
beforeEach(function () { beforeEach(function () {
clientMock.offline_queue.clear(); clientMock.offlineQueue.clear();
clientMock.command_queue.clear(); clientMock.commandQueue.clear();
err_count = 0; errCount = 0;
res_count = 0; resCount = 0;
emitted = false; emitted = false;
}); });
it('no elements in either queue. Reply in the next tick with callback', function (done) { it('no elements in either queue. Reply in the next tick with callback', function (done) {
var called = false; var called = false;
utils.reply_in_order(clientMock, function () { utils.replyInOrder(clientMock, function () {
called = true; called = true;
done(); done();
}, null, null); }, null, null);
@@ -97,7 +78,7 @@ describe('utils.js', function () {
it('no elements in either queue. Reply in the next tick without callback', function (done) { it('no elements in either queue. Reply in the next tick without callback', function (done) {
assert(!emitted); assert(!emitted);
utils.reply_in_order(clientMock, null, new Error('tada')); utils.replyInOrder(clientMock, null, new Error('tada'));
assert(!emitted); assert(!emitted);
setTimeout(function () { setTimeout(function () {
assert(emitted); assert(emitted);
@@ -105,48 +86,48 @@ describe('utils.js', function () {
}, 1); }, 1);
}); });
it('elements in the offline queue. Reply after the offline queue is empty and respect the command_obj callback', function (done) { it('elements in the offline queue. Reply after the offline queue is empty and respect the commandObj callback', function (done) {
clientMock.offline_queue.push(create_command_obj(), create_command_obj()); clientMock.offlineQueue.push(createCommandObj(), createCommandObj());
utils.reply_in_order(clientMock, function () { utils.replyInOrder(clientMock, function () {
assert.strictEqual(clientMock.offline_queue.length, 0); assert.strictEqual(clientMock.offlineQueue.length, 0);
assert.strictEqual(res_count, 2); assert.strictEqual(resCount, 2);
done(); done();
}, null, null); }, null, null);
while (clientMock.offline_queue.length) clientMock.offline_queue.shift().callback(null, 'foo'); while (clientMock.offlineQueue.length) clientMock.offlineQueue.shift().callback(null, 'foo');
}); });
it('elements in the offline queue. Reply after the offline queue is empty and respect the command_obj error emit', function (done) { it('elements in the offline queue. Reply after the offline queue is empty and respect the commandObj error emit', function (done) {
clientMock.command_queue.push({}, create_command_obj(), {}); clientMock.commandQueue.push({}, createCommandObj(), {});
utils.reply_in_order(clientMock, function () { utils.replyInOrder(clientMock, function () {
assert.strictEqual(clientMock.command_queue.length, 0); assert.strictEqual(clientMock.commandQueue.length, 0);
assert(emitted); assert(emitted);
assert.strictEqual(err_count, 1); assert.strictEqual(errCount, 1);
assert.strictEqual(res_count, 0); assert.strictEqual(resCount, 0);
done(); done();
}, null, null); }, null, null);
while (clientMock.command_queue.length) { while (clientMock.commandQueue.length) {
var command_obj = clientMock.command_queue.shift(); var commandObj = clientMock.commandQueue.shift();
if (command_obj.callback) { if (commandObj.callback) {
command_obj.callback(new Error('tada')); commandObj.callback(new Error('tada'));
} }
} }
}); });
it('elements in the offline queue and the command_queue. Reply all other commands got handled respect the command_obj', function (done) { it('elements in the offline queue and the commandQueue. Reply all other commands got handled respect the commandObj', function (done) {
clientMock.command_queue.push(create_command_obj(), create_command_obj()); clientMock.commandQueue.push(createCommandObj(), createCommandObj());
clientMock.offline_queue.push(create_command_obj(), {}); clientMock.offlineQueue.push(createCommandObj(), {});
utils.reply_in_order(clientMock, function (err, res) { utils.replyInOrder(clientMock, function (err, res) {
assert.strictEqual(clientMock.command_queue.length, 0); assert.strictEqual(clientMock.commandQueue.length, 0);
assert.strictEqual(clientMock.offline_queue.length, 0); assert.strictEqual(clientMock.offlineQueue.length, 0);
assert(!emitted); assert(!emitted);
assert.strictEqual(res_count, 3); assert.strictEqual(resCount, 3);
done(); done();
}, null, null); }, null, null);
while (clientMock.offline_queue.length) { while (clientMock.offlineQueue.length) {
clientMock.command_queue.push(clientMock.offline_queue.shift()); clientMock.commandQueue.push(clientMock.offlineQueue.shift());
} }
while (clientMock.command_queue.length) { while (clientMock.commandQueue.length) {
clientMock.command_queue.shift().callback(null, 'hello world'); clientMock.commandQueue.shift().callback(null, 'hello world');
} }
}); });
}); });