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

chore: add print helper again and refactor some code

Expose the RedisClient directly instead of only being a property
This commit is contained in:
Ruben Bridgewater
2017-05-29 18:23:24 +02:00
parent 4e593587cb
commit 0276e15f04
14 changed files with 169 additions and 104 deletions

View File

@@ -19,14 +19,18 @@ and maybe more.
Bugfixes
- Fixed auth in batch not saving the password
- Fixed catch tls handshake failures with newer Node.js versions
- Fixed stream option being copied
- Fixed pub sub activated, listening to a `(p)messageBuffer`, no Buffer returns
and monitoring resulting in a crash.
Features
- Native promise support
- Auto pipelining
- The client is now exported directly and be instantiated directly
Breaking Changes
- Dropped support for `UPPER_CASE` commands
- Dropped support for `snake_case`
- Dropped support for domains
- Dropped support for Redis 2.4
@@ -36,9 +40,7 @@ Breaking Changes
- Removed `parser` option
- Removed `retryMaxDelay` (max_delay) option
- Removed `maxAttempts` (max_attempts) option
- Removed `socketNoDelay` (socket_no_delay) option
- Removed `authPass` (auth_pass) option. Please use `password` instead
- Removed `Redis.print` helper function
- Removed `socketNoDelay` (socket\_no_delay) option
- Removed backpressure indicator from function return value
- Removed the `stream` parameter from the RedisClient constructor.
- Please set the stream in the options instead
@@ -60,11 +62,12 @@ Breaking Changes
- `restore-asking` is now `restore_asking_`
- `host:` is now `host`
- Changed the `serverInfo` into a nested object and to parse numbers
- Changed the `serverInfo.versions` to `serverInfo.version`
- Changed the `serverInfo.versions` to `serverInfo.server.version`
- Changed the `message` and `pmessage` listener to always return a string
- If you want to receive a buffer, please listen to the `messageBuffer` or `pmessageBuffer`
- Using `.end` without the flush parameter is now going to throw an TypeError
- Only emit ready when all commands were truly send to Redis
- `UPPER_CASE` commands are not enumerated anymore
## v.2.7.2 - 14 Mar, 2017

View File

@@ -20,6 +20,7 @@ const offlineCommand = require('./lib/offlineCommand')
const utils = require('./lib/utils')
const normalizeAndWriteCommand = require('./lib/writeCommands')
const noop = function () {}
var connectionId = 0
// Attention: The second parameter might be removed at will and is not officially supported.
// Do not rely on this
@@ -34,8 +35,8 @@ class RedisClient extends EventEmitter {
super()
// Copy the options so they are not mutated
options = utils.clone(options)
// TODO: Add a more restrictive options validation
const cnxOptions = {}
/* istanbul ignore next: travis does not work with stunnel atm. Therefore the tls tests are skipped on travis */
for (const tlsOption in options.tls) {
if (options.tls.hasOwnProperty(tlsOption)) {
cnxOptions[tlsOption] = options.tls[tlsOption]
@@ -140,6 +141,8 @@ class RedisClient extends EventEmitter {
// Do not call internalSendCommand directly, if you are not absolutely certain it handles everything properly
// e.g. monitor / info does not work with internalSendCommand only
// TODO: Move this function out of the client as a private function
// TODO: Check how others can intercept (monkey patch) essential parts (e.g. opbeat)
// after making this private.
internalSendCommand (commandObj) {
if (this.ready === false || this._stream.writable === false) {
// Handle offline commands right away
@@ -154,7 +157,6 @@ class RedisClient extends EventEmitter {
}
// Handle `CLIENT REPLY ON|OFF|SKIP`
// This has to be checked after callOnWrite
/* istanbul ignore else: TODO: Remove this as soon as we test Redis 3.2 on travis */
if (this._reply === 'ON') {
this.commandQueue.push(commandObj)
} else {
@@ -229,6 +231,10 @@ class RedisClient extends EventEmitter {
}
// TODO: promisify this
// This can not be done without removing support to return the client sync.
// This would be another BC and it should be fine to return the client sync.
// Therefore a option could be to accept a resolved promise instead of a callback
// to return a promise.
duplicate (options, callback) {
if (typeof options === 'function') {
callback = options
@@ -261,33 +267,31 @@ class RedisClient extends EventEmitter {
// Note: this overrides a native function!
multi (args) {
return new Multi(this, 'multi', args)
return new Multi(this, args, 'multi')
}
// Note: This is not a native function but is still handled as a individual command as it behaves just the same as multi
batch (args) {
return new Multi(this, 'batch', args)
return new Multi(this, args, 'batch')
}
}
RedisClient.connectionId = 0
RedisClient.debugMode = /\bredis\b/i.test(process.env.NODE_DEBUG)
RedisClient.RedisClient = RedisClient
RedisClient.Multi = Multi
RedisClient.AbortError = Errors.AbortError
RedisClient.ParserError = Errors.ParserError
RedisClient.RedisError = Errors.RedisError
RedisClient.ReplyError = Errors.ReplyError
RedisClient.InterruptError = Errors.InterruptError
RedisClient.print = utils.print
RedisClient.createClient = function () {
return new RedisClient(unifyOptions.apply(null, arguments))
}
Commands.list.forEach((name) => addCommand(RedisClient.prototype, Multi.prototype, name))
module.exports = {
debugMode: /\bredis\b/i.test(process.env.NODE_DEBUG),
RedisClient,
Multi,
AbortError: Errors.AbortError,
ParserError: Errors.ParserError,
RedisError: Errors.RedisError,
ReplyError: Errors.ReplyError,
InterruptError: Errors.InterruptError,
createClient () {
return new RedisClient(unifyOptions.apply(null, arguments))
}
}
module.exports = RedisClient
// Add all redis commands / nodeRedis api to the client
// TODO: Change the way this is included...

View File

@@ -23,6 +23,12 @@ function addCommand (clientProto, multiProto, command) {
})
}
}
Object.defineProperty(clientProto, commandName.toUpperCase(), {
enumerable: false,
configurable: false,
writable: false,
value: clientProto[commandName]
})
// Do not override existing functions
if (!multiProto[command] && command !== 'multi') {
@@ -41,6 +47,12 @@ function addCommand (clientProto, multiProto, command) {
})
}
}
Object.defineProperty(multiProto, commandName.toUpperCase(), {
enumerable: false,
configurable: false,
writable: false,
value: clientProto[commandName]
})
}
module.exports = addCommand

View File

@@ -10,9 +10,9 @@ const replyHandler = require('./replyHandler')
const onResult = replyHandler.onResult
const onError = replyHandler.onError
var reconnect = function (client, why, err) {
reconnect = require('./reconnect')
reconnect(client, why, err)
var lazyReconnect = function (client, why, err) {
lazyReconnect = require('./reconnect')
lazyReconnect(client, why, err)
}
function onStreamError (client, err) {
@@ -31,7 +31,7 @@ function onStreamError (client, err) {
}
// 'error' events get turned into exceptions if they aren't listened for. If the user handled this error
// then we should try to reconnect.
reconnect(client, 'error', err)
lazyReconnect(client, 'error', err)
}
/**
@@ -91,9 +91,19 @@ function connect (client) {
client._stream.destroy()
}
/* istanbul ignore if: travis does not work with stunnel atm. Therefore the tls tests are skipped on travis */
if (client._options.tls) {
client._stream = tls.connect(client._connectionOptions)
// Whenever a handshake times out.
// Older Node.js versions use "clientError", newer versions use tlsClientError.
stream.once('clientError', (err) => {
debug('clientError occurred')
onStreamError(client, err)
})
stream.once('tlsClientError', (err) => {
debug('clientError occurred')
onStreamError(client, err)
})
} else {
client._stream = net.createConnection(client._connectionOptions)
}
@@ -105,11 +115,10 @@ function connect (client) {
// TODO: Investigate why this is not properly triggered
stream.setTimeout(client._options.connectTimeout, () => {
// Note: This is only tested if a internet connection is established
reconnect(client, 'timeout')
lazyReconnect(client, 'timeout')
})
}
/* istanbul ignore next: travis does not work with stunnel atm. Therefore the tls tests are skipped on travis */
const connectEvent = client._options.tls ? 'secureConnect' : 'connect'
stream.once(connectEvent, () => {
stream.removeAllListeners('timeout')
@@ -126,18 +135,12 @@ function connect (client) {
onStreamError(client, err)
})
/* istanbul ignore next: difficult to test and not important as long as we keep this listener */
stream.on('clientError', (err) => {
debug('clientError occurred')
onStreamError(client, err)
})
stream.once('close', (hadError) => {
reconnect(client, 'close')
lazyReconnect(client, 'close')
})
stream.once('end', () => {
reconnect(client, 'end')
lazyReconnect(client, 'end')
})
stream.setNoDelay()

View File

@@ -3,7 +3,9 @@
const utils = require('./utils')
const URL = require('url')
module.exports = function createClient (portArg, hostArg, options) {
// TODO: Improve the unify performance by checking for the arguments length
// before trying to access that argument.
function unifyOptions (portArg, hostArg, options) {
if (typeof portArg === 'number' || (typeof portArg === 'string' && /^\d+$/.test(portArg))) {
var host
if (typeof hostArg === 'string') {
@@ -75,3 +77,5 @@ module.exports = function createClient (portArg, hostArg, options) {
return options
}
module.exports = unifyOptions

View File

@@ -186,7 +186,7 @@ function authCallback (client, pass) {
if (err) {
if (noPasswordIsSet.test(err.message)) {
utils.warn(client, 'Warning: Redis server does not require a password, but a password was supplied.')
return 'OK' // TODO: Fix this
return 'OK'
}
return err
}
@@ -224,7 +224,6 @@ RedisClient.prototype.client = function client () {
}
var callOnWrite
// CLIENT REPLY ON|OFF|SKIP
/* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */
if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') {
const replyOnOff = arr[1].toString().toUpperCase()
if (replyOnOff === 'ON' || replyOnOff === 'OFF' || replyOnOff === 'SKIP') {
@@ -244,7 +243,6 @@ Multi.prototype.client = function client () {
}
var callOnWrite
// CLIENT REPLY ON|OFF|SKIP
/* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */
if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') {
const replyOnOff = arr[1].toString().toUpperCase()
if (replyOnOff === 'ON' || replyOnOff === 'OFF' || replyOnOff === 'SKIP') {

View File

@@ -145,14 +145,14 @@ class Multi {
/**
* Creates an instance of Multi.
* @param {RedisClient} client
* @param {string} type
* @param {any[]} [args]
* @param {string} [type]
*
* @memberof Multi
*/
constructor (client, type, args) {
constructor (client, args, type) {
this._client = client
this._type = type
this._type = typeof type === 'string' ? type : 'multi'
this._queue = new Queue()
// Either undefined or an array. Fail hard if it's not an array
if (args) {

View File

@@ -105,7 +105,6 @@ function readyCheck (client) {
// Always fire client info command as first command even if other commands are already queued up
client.ready = true
client.info().then((res) => {
/* istanbul ignore if: some servers might not respond with any info data. client is just a safety check that is difficult to test */
if (!res) {
debug('The info command returned without any data.')
readyHandler(client)

View File

@@ -40,7 +40,7 @@ function onResult (client, reply) {
// If in monitor mode, all normal commands are still working and we only want to emit the streamlined commands
// As this is not the average use case and monitor is expensive anyway, let's change the code here, to improve
// the average performance of all other commands in case of no monitor mode
if (client._monitoring) {
if (client._monitoring === true) {
var replyStr
if (client.buffers && Buffer.isBuffer(reply)) {
replyStr = reply.toString()
@@ -63,6 +63,7 @@ function onResult (client, reply) {
} else if (client._pubSubMode !== 1) {
client._pubSubMode--
normalReply(client, reply)
// TODO: Have another look at this if this could be further improved
} else if (!(reply instanceof Array) || reply.length <= 2) {
// Only PING and QUIT are allowed in this context besides the pub sub commands
// Ping replies with ['pong', null|value] and quit with 'OK'

View File

@@ -46,25 +46,29 @@ function replyToStrings (reply) {
* @description 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)
* and array will be passed by reference (e.g. Buffers, Maps, Functions).
*
* @param {any} obj
* @returns any
*/
function clone (obj) {
var copy
if (Array.isArray(obj)) {
copy = new Array(obj.length)
const copy = new Array(obj.length)
for (var i = 0; i < obj.length; i++) {
copy[i] = clone(obj[i])
}
return copy
}
if (Object.prototype.toString.call(obj) === '[object Object]') {
copy = {}
const elements = Object.keys(obj)
for (var elem = elements.pop(); elem !== undefined; elem = elements.pop()) {
copy[elem] = clone(obj[elem])
const copy = {}
const keys = Object.keys(obj)
while (keys.length) {
const key = keys.pop()
if (key === 'stream') {
copy[key] = obj[key]
} else {
copy[key] = clone(obj[key])
}
}
return copy
}
@@ -96,12 +100,10 @@ function convenienceClone (obj) {
* @param {Denque} queue
*/
function replyInOrder (client, callback, err, res, queue) {
var commandObj
if (queue) {
commandObj = queue.peekBack()
} else {
commandObj = client.offlineQueue.peekBack() || client.commandQueue.peekBack()
}
const commandObj = queue
? queue.peekBack()
: (client.offlineQueue.peekBack() || client.commandQueue.peekBack())
if (!commandObj) {
process.nextTick(callback, err, res)
} else {
@@ -149,6 +151,21 @@ function handleReply (client, reply, command) {
return reply
}
/**
* @description Callback result print helper
*
* @param {Error|null} err
* @param {any} reply
*/
function print (err, reply) {
if (err) {
// A error always begins with Error:
console.error(err.toString())
} else {
console.log('Reply: ' + reply)
}
}
/**
* @description Set default reconnect variables
*
@@ -171,5 +188,6 @@ module.exports = {
replyInOrder,
warn,
handleReply,
setReconnectDefaults
setReconnectDefaults,
print
}

View File

@@ -14,9 +14,7 @@ if (process.platform !== 'win32') {
})
})
helper.allTests({
allConnections: true
}, (ip, args) => {
helper.allTests((ip, args) => {
describe(`using ${ip}`, () => {
const auth = 'porkchopsandwiches'
let client = null

View File

@@ -4,7 +4,7 @@ const assert = require('assert')
const config = require('./lib/config')
const connect = require('../lib/connect')
const helper = require('./helper')
const redis = config.redis
const Redis = config.redis
const intercept = require('intercept-stdout')
const net = require('net')
let client
@@ -22,7 +22,7 @@ describe('connection tests', () => {
// Besides that some functions also have to be monkey patched to be safe from errors in this case.
// Therefore this is not officially supported!
const socket = new net.Socket()
client = new redis.RedisClient({
client = new Redis({
prefix: 'test',
stream: socket
})
@@ -38,7 +38,7 @@ describe('connection tests', () => {
describe('quit on lost connections', () => {
it('calling quit while the connection is down should not end in reconnecting version a', (done) => {
let called = 0
client = redis.createClient({
client = Redis.createClient({
connectTimeout: 5,
port: 9999,
retryStrategy (options) {
@@ -59,7 +59,7 @@ describe('connection tests', () => {
it('calling quit while the connection is down should not end in reconnecting version b', () => {
let called = false
client = redis.createClient(9999)
client = Redis.createClient(9999)
client.set('foo', 'bar').catch((err) => {
assert.strictEqual(err.message, 'Stream connection ended and command aborted.')
called = true
@@ -72,7 +72,7 @@ describe('connection tests', () => {
it('calling quit while the connection is down without offline queue should end the connection right away', () => {
let called = false
client = redis.createClient(9999, {
client = Redis.createClient(9999, {
enableOfflineQueue: false
})
client.set('foo', 'bar').catch((err) => {
@@ -87,7 +87,7 @@ describe('connection tests', () => {
it('calling quit while connected without offline queue should end the connection when all commands have finished', (done) => {
let called = false
client = redis.createClient({
client = Redis.createClient({
enableOfflineQueue: false
})
client.on('ready', () => {
@@ -104,7 +104,7 @@ describe('connection tests', () => {
})
it('do not quit before connected or a connection issue is detected', () => {
client = redis.createClient()
client = Redis.createClient()
return Promise.all([
client.set('foo', 'bar').then(helper.isString('OK')),
client.quit()
@@ -112,7 +112,7 @@ describe('connection tests', () => {
})
it('quit "succeeds" even if the client connection is closed while doing so', () => {
client = redis.createClient()
client = Redis.createClient()
return client.set('foo', 'bar').then((res) => {
assert.strictEqual(res, 'OK')
const promise = client.quit().then((res) => {
@@ -124,7 +124,7 @@ describe('connection tests', () => {
})
it('quit right away if connection drops while quit command is on the fly', (done) => {
client = redis.createClient()
client = Redis.createClient()
client.once('ready', () => {
client.set('foo', 'bar').catch(helper.isError())
client.quit().then(() => done())
@@ -138,7 +138,7 @@ describe('connection tests', () => {
describe('on lost connection', () => {
it('end connection while retry is still ongoing', (done) => {
const connectTimeout = 1000 // in ms
client = redis.createClient({
client = Redis.createClient({
connectTimeout
})
@@ -160,7 +160,7 @@ describe('connection tests', () => {
family: ip,
retryStrategy () {}
}
client = redis.createClient(options)
client = Redis.createClient(options)
assert.strictEqual(client._connectionOptions.family, ip === 'IPv6' ? 6 : 4)
assert.strictEqual(Object.keys(options).length, 4)
const end = helper.callFuncAfter(done, 2)
@@ -172,7 +172,7 @@ describe('connection tests', () => {
})
it('retryStrategy used to reconnect with individual error', (done) => {
client = redis.createClient({
client = Redis.createClient({
retryStrategy (options) {
if (options.totalRetryTime > 150) {
client.set('foo', 'bar').then(assert, (err) => {
@@ -191,7 +191,7 @@ describe('connection tests', () => {
})
it('retryStrategy used to reconnect', (done) => {
client = redis.createClient({
client = Redis.createClient({
retryStrategy (options) {
if (options.totalRetryTime > 150) {
client.set('foo', 'bar').catch((err) => {
@@ -213,17 +213,17 @@ describe('connection tests', () => {
const unhookIntercept = intercept(() => {
return ''
})
redis.debugMode = true
client = redis.createClient({
Redis.debugMode = true
client = Redis.createClient({
retryStrategy (options) {
client.set('foo', 'bar').catch((err) => {
assert.strictEqual(err.code, 'NR_CLOSED')
assert.strictEqual(err.message, 'Stream connection ended and command aborted.')
unhookIntercept()
redis.debugMode = false
Redis.debugMode = false
done()
})
assert(redis.debugMode)
assert(Redis.debugMode)
return null
}
})
@@ -237,7 +237,7 @@ describe('connection tests', () => {
// TODO: Fix this test
it.skip('emit an error after the socket timeout exceeded the connectTimeout time', (done) => {
const connectTimeout = 500 // in ms
client = redis.createClient({
client = Redis.createClient({
// Auto detect ipv4 and use non routeable ip to trigger the timeout
host: '10.255.255.1',
connectTimeout,
@@ -271,7 +271,7 @@ describe('connection tests', () => {
})
it('use the system socket timeout if the connectTimeout has not been provided', (done) => {
client = redis.createClient({
client = Redis.createClient({
host: '2001:db8::ff00:42:8329' // auto detect ip v6
})
assert.strictEqual(client.address, '2001:db8::ff00:42:8329:6379')
@@ -284,7 +284,7 @@ describe('connection tests', () => {
})
it('clears the socket timeout after a connection has been established', (done) => {
client = redis.createClient({
client = Redis.createClient({
connectTimeout: 1000
})
process.nextTick(assert.strictEqual, client._stream._idleTimeout, 1000)
@@ -296,7 +296,7 @@ describe('connection tests', () => {
})
it('connect with host and port provided in the options object', (done) => {
client = redis.createClient({
client = Redis.createClient({
host: 'localhost',
port: '6379',
connectTimeout: 1000
@@ -309,7 +309,7 @@ describe('connection tests', () => {
if (process.platform === 'win32') {
this.skip()
}
client = redis.createClient({
client = Redis.createClient({
path: '/tmp/redis.sock',
connectTimeout: 1000
})
@@ -317,7 +317,7 @@ describe('connection tests', () => {
})
it('connects correctly with args', (done) => {
client = redis.createClient.apply(null, args)
client = Redis.createClient.apply(null, args)
client.on('error', done)
client.once('ready', () => {
@@ -327,7 +327,7 @@ describe('connection tests', () => {
})
it('connects correctly with default values', (done) => {
client = redis.createClient()
client = Redis.createClient()
client.on('error', done)
client.once('ready', () => {
@@ -337,7 +337,7 @@ describe('connection tests', () => {
})
it('connects with a port only', (done) => {
client = redis.createClient(6379)
client = Redis.createClient(6379)
assert.strictEqual(client._connectionOptions.family, 4)
client.on('error', done)
@@ -348,7 +348,7 @@ describe('connection tests', () => {
})
it('connects correctly to localhost', (done) => {
client = redis.createClient(null, null)
client = Redis.createClient(null, null)
client.on('error', done)
client.once('ready', () => {
@@ -358,7 +358,7 @@ describe('connection tests', () => {
})
it('connects correctly to the provided host with the port set to null', (done) => {
client = redis.createClient(null, 'localhost')
client = Redis.createClient(null, 'localhost')
client.on('error', done)
assert.strictEqual(client.address, 'localhost:6379')
@@ -371,7 +371,7 @@ describe('connection tests', () => {
})
it('connects correctly to localhost and no ready check', (done) => {
client = redis.createClient(undefined, undefined, {
client = Redis.createClient(undefined, undefined, {
noReadyCheck: true
})
client.on('error', done)
@@ -385,7 +385,7 @@ describe('connection tests', () => {
})
it('connects correctly to the provided host with the port set to undefined', (done) => {
client = redis.createClient(undefined, 'localhost', {
client = Redis.createClient(undefined, 'localhost', {
noReadyCheck: true
})
client.on('error', done)
@@ -400,7 +400,7 @@ describe('connection tests', () => {
})
it('connects correctly even if the info command is not present on the redis server', (done) => {
client = redis.createClient.apply(null, args)
client = Redis.createClient.apply(null, args)
const end = helper.callFuncAfter(done, 2)
client.info = function () {
// Mock the result
@@ -415,13 +415,13 @@ describe('connection tests', () => {
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', (done) => {
client = redis.createClient('redis:///3?db=3')
client = Redis.createClient('redis:///3?db=3')
assert.strictEqual(client.selectedDb, '3')
client.on('ready', done)
})
it('allows connecting with the redis url and the default port and auth provided even though it is not required', (done) => {
client = redis.createClient(`redis://:porkchopsandwiches@${config.HOST[ip]}/`)
client = Redis.createClient(`redis://:porkchopsandwiches@${config.HOST[ip]}/`)
const end = helper.callFuncAfter(done, 2)
client.on('warning', (msg) => {
assert.strictEqual(msg, 'Warning: Redis server does not require a password, but a password was supplied.')
@@ -431,7 +431,7 @@ describe('connection tests', () => {
})
it('allows connecting with the redis url as first parameter and the options as second parameter', (done) => {
client = redis.createClient('//127.0.0.1', {
client = Redis.createClient('//127.0.0.1', {
connectTimeout: 1000
})
assert.strictEqual(client._options.connectTimeout, 1000)
@@ -439,7 +439,7 @@ describe('connection tests', () => {
})
it('allows connecting with the redis url in the options object and works with protocols other than the redis protocol (e.g. http)', (done) => {
client = redis.createClient({
client = Redis.createClient({
url: `http://foo:porkchopsandwiches@${config.HOST[ip]}/3`
})
assert.strictEqual(client._options.password, 'porkchopsandwiches')
@@ -453,13 +453,13 @@ describe('connection tests', () => {
const options = {
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)
client.on('ready', done)
})
it('allows connecting with the redis url and no auth and options as third parameter', (done) => {
client = redis.createClient(`redis://${config.HOST[ip]}:${config.PORT}`, null, {
client = Redis.createClient(`redis://${config.HOST[ip]}:${config.PORT}`, null, {
detectBuffers: false
})
client.on('ready', done)
@@ -467,7 +467,7 @@ describe('connection tests', () => {
}
it('redis still loading <= 500', (done) => {
client = redis.createClient.apply(null, args)
client = Redis.createClient.apply(null, args)
const tmp = client.info.bind(client)
const end = helper.callFuncAfter(done, 3)
let delayed = false
@@ -496,7 +496,7 @@ describe('connection tests', () => {
})
it('redis still loading > 1000ms', (done) => {
client = redis.createClient.apply(null, args)
client = Redis.createClient.apply(null, args)
const tmp = client.info.bind(client)
const end = helper.callFuncAfter(done, 3)
let delayed = false

View File

@@ -170,7 +170,7 @@ module.exports = {
let key
for (key in options) {
if (options.hasOwnProperty(key)) {
strOptions += `${key }: ${options[key]}; `
strOptions += `${key}: ${options[key]}; `
}
}
describe(`using options: ${strOptions}`, () => {

View File

@@ -2,9 +2,34 @@
const assert = require('assert')
const Queue = require('denque')
const intercept = require('intercept-stdout')
const utils = require('../lib/utils')
describe('utils.js', () => {
describe('print helper', function () {
it('callback with reply', function () {
var text = ''
const unhookIntercept = intercept(function (data) {
text += data
return ''
})
utils.print(null, 'abc')
unhookIntercept()
assert.strictEqual(text, 'Reply: abc\n')
})
it('callback with error', function () {
var text = ''
const unhookIntercept = intercept(function (data) {
text += data
return ''
})
utils.print(new Error('Wonderful exception'))
unhookIntercept()
assert.strictEqual(text, 'Error: Wonderful exception\n')
})
})
describe('clone', () => {
it('ignore the object prototype and clone a nested array / object', () => {
const obj = {