[api test] Remove Redis store in preparation for nconf-redis
This commit is contained in:
parent
49a1a6dea3
commit
8620e6ba91
3 changed files with 1 additions and 671 deletions
|
@ -1,435 +0,0 @@
|
||||||
/*
|
|
||||||
* redis.js: Redis storage engine for nconf configuration(s)
|
|
||||||
*
|
|
||||||
* (C) 2011, Charlie Robbins
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
var async = require('async'),
|
|
||||||
redis = require('redis'),
|
|
||||||
nconf = require('../../nconf'),
|
|
||||||
Memory = require('./memory').Memory;
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### function Redis (options)
|
|
||||||
// #### @options {Object} Options for this instance
|
|
||||||
// Constructor function for the Redis nconf store which maintains
|
|
||||||
// a nested Redis key structure based on key delimiters `:`.
|
|
||||||
//
|
|
||||||
// e.g.
|
|
||||||
// my:nested:key, 'value'
|
|
||||||
// namespace:keys ==> ['my']
|
|
||||||
// namespace:nested:keys ==> ['key']
|
|
||||||
// namespace:nested:key ==> 'value'
|
|
||||||
//
|
|
||||||
var Redis = exports.Redis = function (options) {
|
|
||||||
options = options || {};
|
|
||||||
this.type = 'redis';
|
|
||||||
this.namespace = options.namespace || 'nconf';
|
|
||||||
this.host = options.host || 'localhost';
|
|
||||||
this.port = options.port || 6379;
|
|
||||||
this.ttl = options.ttl || 60 * 60 * 1000;
|
|
||||||
this.cache = new Memory();
|
|
||||||
this.redis = redis.createClient(options.port, options.host);
|
|
||||||
|
|
||||||
if (options.auth) {
|
|
||||||
this.redis.auth(options.auth);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Suppress errors from the Redis client
|
|
||||||
this.redis.on('error', function (err) {
|
|
||||||
console.dir(err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### function get (key, callback)
|
|
||||||
// #### @key {string} Key to retrieve for this instance.
|
|
||||||
// #### @callback {function} Continuation to respond to when complete.
|
|
||||||
// Retrieves the value for the specified key (if any).
|
|
||||||
//
|
|
||||||
Redis.prototype.get = function (key, callback) {
|
|
||||||
var self = this,
|
|
||||||
result = {},
|
|
||||||
now = Date.now(),
|
|
||||||
mtime = this.cache.mtimes[key],
|
|
||||||
fullKey = nconf.key(this.namespace, key);
|
|
||||||
|
|
||||||
// Set the callback if not provided for "fire and forget"
|
|
||||||
callback = callback || function () { };
|
|
||||||
|
|
||||||
//
|
|
||||||
// If the key exists in the cache and the ttl is less than
|
|
||||||
// the value set for this instance, return from the cache.
|
|
||||||
//
|
|
||||||
if (mtime && now - mtime < this.ttl) {
|
|
||||||
return callback(null, this.cache.get(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the set of all children keys for the `key` supplied. If the value
|
|
||||||
// to be returned is an Object, this list will not be empty.
|
|
||||||
//
|
|
||||||
this.redis.smembers(nconf.key(fullKey, 'keys'), function (err, keys) {
|
|
||||||
function addValue (source, next) {
|
|
||||||
self.get(nconf.key(key, source), function (err, value) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
result[source] = value;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keys && keys.length > 0) {
|
|
||||||
//
|
|
||||||
// If the value to be retrieved is an Object, recursively attempt
|
|
||||||
// to get the value from redis. Here we use a recursive call to `this.get`
|
|
||||||
// to support nested Object keys.
|
|
||||||
//
|
|
||||||
async.forEach(keys, addValue, function (err) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cache.set(key, result);
|
|
||||||
callback(null, result);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//
|
|
||||||
// If there are no keys, then the value to be retrieved is a literal
|
|
||||||
// and we can simply return the value from redis directly.
|
|
||||||
//
|
|
||||||
self.redis.get(fullKey, function (err, value) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = JSON.parse(value);
|
|
||||||
if (result) {
|
|
||||||
self.cache.set(key, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### function set (key, value, callback)
|
|
||||||
// #### @key {string} Key to set in this instance
|
|
||||||
// #### @value {literal|Object} Value for the specified key
|
|
||||||
// #### @callback {function} Continuation to respond to when complete.
|
|
||||||
// Sets the `value` for the specified `key` in this instance.
|
|
||||||
//
|
|
||||||
Redis.prototype.set = function (key, value, callback) {
|
|
||||||
var self = this,
|
|
||||||
path = nconf.path(key);
|
|
||||||
|
|
||||||
// Set the callback if not provided for "fire and forget"
|
|
||||||
callback = callback || function () { };
|
|
||||||
|
|
||||||
this._addKeys(key, function (err) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var fullKey = nconf.key(self.namespace, key);
|
|
||||||
|
|
||||||
if (!Array.isArray(value) && value !== null && typeof value === 'object') {
|
|
||||||
//
|
|
||||||
// If the value is an `Object` (and not an `Array`) then
|
|
||||||
// nest into the value and set the child keys appropriately.
|
|
||||||
// This is done for efficient lookup when setting Object keys.
|
|
||||||
// (i.e. If you set and Object then wish to later retrieve only a
|
|
||||||
// member of that Object, the entire Object need not be retrieved).
|
|
||||||
//
|
|
||||||
self.cache.set(key, value);
|
|
||||||
self._setObject(fullKey, value, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//
|
|
||||||
// If the value is a simple literal (or an `Array`) then JSON
|
|
||||||
// stringify it and put it into Redis.
|
|
||||||
//
|
|
||||||
self.cache.set(key, value);
|
|
||||||
value = JSON.stringify(value);
|
|
||||||
self.redis.set(fullKey, value, callback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### function merge (key, value, callback)
|
|
||||||
// #### @key {string} Key to merge the value into
|
|
||||||
// #### @value {literal|Object} Value to merge into the key
|
|
||||||
// #### 2callback {function} Continuation to respond to when complete.
|
|
||||||
// Merges the properties in `value` into the existing object value
|
|
||||||
// at `key`. If the existing value `key` is not an Object, it will be
|
|
||||||
// completely overwritten.
|
|
||||||
//
|
|
||||||
Redis.prototype.merge = function (key, value, callback) {
|
|
||||||
//
|
|
||||||
// If the key is not an `Object` or is an `Array`,
|
|
||||||
// then simply set it. Merging is for Objects.
|
|
||||||
//
|
|
||||||
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
||||||
return this.set(key, value, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
var self = this,
|
|
||||||
path = nconf.path(key),
|
|
||||||
fullKey = nconf.key(this.namespace, key);
|
|
||||||
|
|
||||||
// Set the callback if not provided for "fire and forget"
|
|
||||||
callback = callback || function () { };
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the set of all children keys for the `key` supplied. If the value
|
|
||||||
// to be returned is an Object, this list will not be empty.
|
|
||||||
//
|
|
||||||
this._addKeys(key, function (err) {
|
|
||||||
self.redis.smembers(nconf.key(fullKey, 'keys'), function (err, keys) {
|
|
||||||
function nextMerge (nested, next) {
|
|
||||||
var keyPath = nconf.key.apply(null, path.concat([nested]));
|
|
||||||
self.merge(keyPath, value[nested], next);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keys && keys.length > 0) {
|
|
||||||
//
|
|
||||||
// If there are existing keys then we must do a recursive merge
|
|
||||||
// of the two Objects.
|
|
||||||
//
|
|
||||||
return async.forEach(Object.keys(value), nextMerge, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Otherwise, we can simply invoke `set` to override the current
|
|
||||||
// literal or Array value with our new Object value
|
|
||||||
//
|
|
||||||
self.set(key, value, callback);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### function clear (key, callback)
|
|
||||||
// #### @key {string} Key to remove from this instance
|
|
||||||
// #### @callback {function} Continuation to respond to when complete.
|
|
||||||
// Removes the value for the specified `key` from this instance.
|
|
||||||
//
|
|
||||||
Redis.prototype.clear = function (key, callback) {
|
|
||||||
var self = this,
|
|
||||||
result = {},
|
|
||||||
path = [this.namespace].concat(nconf.path(key)),
|
|
||||||
last = path.pop(),
|
|
||||||
fullKey = nconf.key(this.namespace, key);
|
|
||||||
|
|
||||||
// Set the callback if not provided for "fire and forget"
|
|
||||||
callback = callback || function () { };
|
|
||||||
|
|
||||||
//
|
|
||||||
// Clear the key from the cache for this instance
|
|
||||||
//
|
|
||||||
this.cache.clear(key);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Remove the `key` from the parent set of keys.
|
|
||||||
//
|
|
||||||
this.redis.srem(nconf.key.apply(null, path.concat(['keys'])), last, function (err) {
|
|
||||||
//
|
|
||||||
// Remove the value from redis by iterating over the set of keys (if any)
|
|
||||||
// and deleting each value. If no keys, then just delete the simple literal.
|
|
||||||
//
|
|
||||||
self.redis.smembers(nconf.key(fullKey, 'keys'), function (err, keys) {
|
|
||||||
function removeValue (child, next) {
|
|
||||||
//
|
|
||||||
// Recursively call `self.clear` here to ensure we remove any
|
|
||||||
// nested Objects completely from this instance.
|
|
||||||
//
|
|
||||||
self.clear(nconf.key(key, child), next);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keys && keys.length > 0) {
|
|
||||||
//
|
|
||||||
// If there are child keys then iterate over them,
|
|
||||||
// removing each child along the way.
|
|
||||||
//
|
|
||||||
async.forEach(keys, removeValue, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//
|
|
||||||
// Otherwise if this is just a simple literal, then
|
|
||||||
// simply remove it from Redis directly.
|
|
||||||
//
|
|
||||||
self.redis.del(fullKey, callback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### function save (value, callback)
|
|
||||||
// #### @value {Object} Config object to set for this instance
|
|
||||||
// #### @callback {function} Continuation to respond to when complete.
|
|
||||||
// Removes any existing configuration settings that may exist in this
|
|
||||||
// instance and then adds all key-value pairs in `value`.
|
|
||||||
//
|
|
||||||
Redis.prototype.save = function (value, callback) {
|
|
||||||
if (Array.isArray(value) || typeof value !== 'object') {
|
|
||||||
return callback(new Error('`value` to be saved must be an object.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
var self = this,
|
|
||||||
keys = Object.keys(value);
|
|
||||||
|
|
||||||
// Set the callback if not provided for "fire and forget"
|
|
||||||
callback = callback || function () { };
|
|
||||||
|
|
||||||
//
|
|
||||||
// Clear all existing keys associated with this instance.
|
|
||||||
//
|
|
||||||
this.reset(function (err) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Iterate over the keys in the new value, setting each of them.
|
|
||||||
//
|
|
||||||
async.forEach(keys, function (key, next) {
|
|
||||||
self.set(key, value[key], next);
|
|
||||||
}, callback);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### function load (callback)
|
|
||||||
// #### @callback {function} Continuation to respond to when complete.
|
|
||||||
// Responds with an Object representing all keys associated in this instance.
|
|
||||||
//
|
|
||||||
Redis.prototype.load = function (callback) {
|
|
||||||
var self = this,
|
|
||||||
result = {};
|
|
||||||
|
|
||||||
// Set the callback if not provided for "fire and forget"
|
|
||||||
callback = callback || function () { };
|
|
||||||
|
|
||||||
this.redis.smembers(nconf.key(this.namespace, 'keys'), function (err, keys) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addValue (key, next) {
|
|
||||||
self.get(key, function (err, value) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
result[key] = value;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
keys = keys || [];
|
|
||||||
async.forEach(keys, addValue, function (err) {
|
|
||||||
return err ? callback(err) : callback(null, result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### function reset (callback)
|
|
||||||
// #### @callback {function} Continuation to respond to when complete.
|
|
||||||
// Clears all keys associated with this instance.
|
|
||||||
//
|
|
||||||
Redis.prototype.reset = function (callback) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// Set the callback if not provided for "fire and forget"
|
|
||||||
callback = callback || function () { };
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the list of of top-level keys, then clear each of them
|
|
||||||
//
|
|
||||||
this.redis.smembers(nconf.key(this.namespace, 'keys'), function (err, existing) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
existing = existing || [];
|
|
||||||
async.forEach(existing, function (key, next) {
|
|
||||||
self.clear(key, next);
|
|
||||||
}, callback);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### @private function _addKeys (key, callback)
|
|
||||||
// #### @key {string} Key to add parent keys for
|
|
||||||
// #### @callback {function} Continuation to respond to when complete.
|
|
||||||
// Adds the full `key` path to Redis via `sadd`.
|
|
||||||
//
|
|
||||||
Redis.prototype._addKeys = function (key, callback) {
|
|
||||||
var self = this,
|
|
||||||
path = nconf.path(key);
|
|
||||||
|
|
||||||
function addKey (partial, next) {
|
|
||||||
var index = path.indexOf(partial),
|
|
||||||
base = [self.namespace].concat(path.slice(0, index)),
|
|
||||||
parent = nconf.key.apply(null, base.concat(['keys']));
|
|
||||||
|
|
||||||
self.redis.sadd(parent, partial, next);
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Iterate over the entire key path and add each key to the
|
|
||||||
// parent key-set if it doesn't exist already.
|
|
||||||
//
|
|
||||||
async.forEach(path, addKey, callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// ### @private function _setObject (key, value, callback)
|
|
||||||
// #### @key {string} Key to set in this instance
|
|
||||||
// #### @value {Object} Value for the specified key
|
|
||||||
// #### @callback {function} Continuation to respond to when complete.
|
|
||||||
// Internal helper function for setting all keys of a nested object.
|
|
||||||
//
|
|
||||||
Redis.prototype._setObject = function (key, value, callback) {
|
|
||||||
var self = this,
|
|
||||||
keys = Object.keys(value);
|
|
||||||
|
|
||||||
function addValue (child, next) {
|
|
||||||
//
|
|
||||||
// Add the child key to the parent key-set, then set the value.
|
|
||||||
// Recursively call `_setObject` in the event of nested Object(s).
|
|
||||||
//
|
|
||||||
self.redis.sadd(nconf.key(key, 'keys'), child, function (err) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var fullKey = nconf.key(key, child),
|
|
||||||
childValue = value[child];
|
|
||||||
|
|
||||||
if (!Array.isArray(childValue) && typeof childValue === 'object') {
|
|
||||||
self._setObject(fullKey, childValue, next);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
childValue = JSON.stringify(childValue);
|
|
||||||
self.redis.set(fullKey, childValue, next);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Iterate over the keys of the Object and set the appropriate values.
|
|
||||||
//
|
|
||||||
async.forEach(keys, addValue, function (err) {
|
|
||||||
return err ? callback(err) : callback();
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -42,7 +42,7 @@ vows.describe('nconf/stores/file').addBatch({
|
||||||
store.load(this.callback.bind(null, null));
|
store.load(this.callback.bind(null, null));
|
||||||
},
|
},
|
||||||
"should respond with an error": function (ign, err) {
|
"should respond with an error": function (ign, err) {
|
||||||
console.dir(err);
|
assert.isTrue(!!err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
/*
|
|
||||||
* redis-store-test.js: Tests for the redis nconf storage engine.
|
|
||||||
*
|
|
||||||
* (C) 2011, Charlie Robbins
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
var vows = require('vows'),
|
|
||||||
assert = require('assert'),
|
|
||||||
nconf = require('../lib/nconf'),
|
|
||||||
data = require('./fixtures/data').data,
|
|
||||||
merge = require('./fixtures/data').merge;
|
|
||||||
|
|
||||||
vows.describe('nconf/stores/redis').addBatch({
|
|
||||||
"When using the nconf redis store": {
|
|
||||||
topic: new nconf.stores.Redis(),
|
|
||||||
"the set() method": {
|
|
||||||
"with a literal": {
|
|
||||||
topic: function (store) {
|
|
||||||
store.set('foo:literal', 'bazz', this.callback)
|
|
||||||
},
|
|
||||||
"should respond without an error": function (err, ok) {
|
|
||||||
assert.isNull(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"with an Array": {
|
|
||||||
topic: function (store) {
|
|
||||||
store.set('foo:array', data.arr, this.callback)
|
|
||||||
},
|
|
||||||
"should respond without an": function (err, ok) {
|
|
||||||
assert.isNull(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"with an Object": {
|
|
||||||
topic: function (store) {
|
|
||||||
store.set('foo:object', data.obj, this.callback)
|
|
||||||
},
|
|
||||||
"should respond without an error": function (err, ok) {
|
|
||||||
assert.isNull(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"with null": {
|
|
||||||
topic: function (store) {
|
|
||||||
store.set('falsy:object', null, this.callback);
|
|
||||||
},
|
|
||||||
"should respond without an error": function(err, ok) {
|
|
||||||
assert.isNull(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).addBatch({
|
|
||||||
"When using the nconf redis store": {
|
|
||||||
topic: new nconf.stores.Redis(),
|
|
||||||
"the get() method": {
|
|
||||||
"with a literal value": {
|
|
||||||
topic: function (store) {
|
|
||||||
store.get('foo:literal', this.callback);
|
|
||||||
},
|
|
||||||
"should respond with the correct value": function (err, value) {
|
|
||||||
assert.equal(value, data.literal);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"with an Array value": {
|
|
||||||
topic: function (store) {
|
|
||||||
store.get('foo:array', this.callback);
|
|
||||||
},
|
|
||||||
"should respond with the correct value": function (err, value) {
|
|
||||||
assert.deepEqual(value, data.arr);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"with an Object value": {
|
|
||||||
topic: function (store) {
|
|
||||||
store.get('foo:object', this.callback);
|
|
||||||
},
|
|
||||||
"should respond with the correct value": function (err, value) {
|
|
||||||
assert.deepEqual(value, data.obj);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"with a nested Object value": {
|
|
||||||
topic: function (store) {
|
|
||||||
store.get('foo:object:auth', this.callback);
|
|
||||||
},
|
|
||||||
"should respond with the correct value": function (err, value) {
|
|
||||||
assert.deepEqual(value, data.obj.auth);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"with null": {
|
|
||||||
topic: function(store) {
|
|
||||||
store.get('falsy:object', this.callback);
|
|
||||||
},
|
|
||||||
"should respond with the correct value": function(err, value) {
|
|
||||||
assert.equal(value, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).addBatch({
|
|
||||||
"When using the nconf redis store": {
|
|
||||||
topic: new nconf.stores.Redis(),
|
|
||||||
"the clear() method": {
|
|
||||||
topic: function (store) {
|
|
||||||
var that = this;
|
|
||||||
store.clear('foo', function (err) {
|
|
||||||
if (err) {
|
|
||||||
return that.callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
store.get('foo', that.callback);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"should actually remove the value from Redis": function (err, value) {
|
|
||||||
assert.isNull(err);
|
|
||||||
assert.isNull(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).addBatch({
|
|
||||||
"When using the nconf redis store": {
|
|
||||||
topic: new nconf.stores.Redis(),
|
|
||||||
"the save() method": {
|
|
||||||
topic: function (store) {
|
|
||||||
var that = this;
|
|
||||||
store.save(data, function (err) {
|
|
||||||
if (err) {
|
|
||||||
return that.callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
store.get('obj', that.callback);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"should set all values correctly": function (err, value) {
|
|
||||||
assert.isNull(err);
|
|
||||||
assert.deepEqual(value, data.obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).addBatch({
|
|
||||||
"When using the nconf redis store": {
|
|
||||||
topic: new nconf.stores.Redis(),
|
|
||||||
"the load() method": {
|
|
||||||
topic: function (store) {
|
|
||||||
store.load(this.callback);
|
|
||||||
},
|
|
||||||
"should respond with the correct object": function (err, value) {
|
|
||||||
assert.isNull(err);
|
|
||||||
assert.deepEqual(value, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).addBatch({
|
|
||||||
"when using the nconf redis store": {
|
|
||||||
topic: new nconf.stores.Redis(),
|
|
||||||
"the merge() method": {
|
|
||||||
"when overriding an existing literal value": {
|
|
||||||
topic: function (store) {
|
|
||||||
var that = this;
|
|
||||||
store.set('merge:literal', 'string-value', function () {
|
|
||||||
store.merge('merge:literal', merge, function () {
|
|
||||||
store.get('merge:literal', that.callback);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"should merge correctly": function (err, data) {
|
|
||||||
assert.deepEqual(data, merge);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"when overriding an existing Array value": {
|
|
||||||
topic: function (store) {
|
|
||||||
var that = this;
|
|
||||||
store.set('merge:array', [1, 2, 3, 4], function () {
|
|
||||||
store.merge('merge:array', merge, function () {
|
|
||||||
store.get('merge:array', that.callback);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"should merge correctly": function (err, data) {
|
|
||||||
assert.deepEqual(data, merge);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"when merging into an existing Object value": {
|
|
||||||
topic: function (store) {
|
|
||||||
var that = this, current;
|
|
||||||
current = {
|
|
||||||
prop1: 2,
|
|
||||||
prop2: 'prop2',
|
|
||||||
prop3: {
|
|
||||||
bazz: 'bazz'
|
|
||||||
},
|
|
||||||
prop4: ['foo', 'bar']
|
|
||||||
};
|
|
||||||
|
|
||||||
store.set('merge:object', current, function () {
|
|
||||||
store.merge('merge:object', merge, function () {
|
|
||||||
store.get('merge:object', that.callback);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"should merge correctly": function (err, data) {
|
|
||||||
assert.equal(data['prop1'], 1);
|
|
||||||
assert.equal(data['prop2'].length, 3);
|
|
||||||
assert.deepEqual(data['prop3'], {
|
|
||||||
foo: 'bar',
|
|
||||||
bar: 'foo',
|
|
||||||
bazz: 'bazz'
|
|
||||||
});
|
|
||||||
assert.equal(data['prop4'].length, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).addBatch({
|
|
||||||
"When using the nconf redis store": {
|
|
||||||
topic: new nconf.stores.Redis(),
|
|
||||||
"the reset() method": {
|
|
||||||
topic: function (store) {
|
|
||||||
var that = this;
|
|
||||||
this.store = store;
|
|
||||||
|
|
||||||
store.reset(function (err) {
|
|
||||||
if (err) {
|
|
||||||
return that.callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
store.get('obj', that.callback);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
"should remove all keys from redis": function (err, value) {
|
|
||||||
assert.isNull(err);
|
|
||||||
assert.isNull(value);
|
|
||||||
assert.length(Object.keys(this.store.cache.store), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).export(module);
|
|
Loading…
Reference in a new issue