Browse Source

Merge branch 'feature/1.0-prep' into develop

feature/fix-isCacheableValue-usage
Bryan Donovan 10 years ago
parent
commit
34e753dec2
  1. 12
      History.md
  2. 10
      README.md
  3. 4
      examples/example.js
  4. 5
      examples/redis_example/redis_store.js
  5. 4
      lib/caching.js
  6. 4
      lib/index.js
  7. 55
      lib/multi_caching.js
  8. 3
      lib/stores/memory.js
  9. 81
      test/caching.unit.js
  10. 110
      test/multi_caching.unit.js
  11. 209
      test/stores/options.unit.js
  12. 3
      test/support.js

12
History.md

@ -1,6 +1,14 @@
- {next release} 2015-05-17
- By default, cache falsey values like `false`, `0`, and `null`, but not `undefined` (#25).
- 1.0.0 2015-05-XX
- Added JSDOC generation (`make docs`)
- (Breaking change) By default, cache falsey values like `false`, `0`, and `null`, but not `undefined` (#25).
- Allow users to pass in callback function `isCacheableValue` to specify what to cache.
- (Breaking change) Removed deprecated lower-case `multi_caching` export (use `multiCaching` instead).
- (Breaking change) Removed `multiCaching#get_and_pass_up` (use `getAndPassUp` instead).
- (Breaking change) Cache store methods must accept an `options` param (which can be ignored). Eg.,
`function set(key, val, options, cb) { }`
- (Breaking change) caching/multicaching methods no longer accept a `ttl` param. You must instead pass
in an options object which will be passed to the cache store's `set` method.
- (Breaking change) caching.js no longer accepts a path to cache store. Pass in an object or 'memory' instead.
- 0.19.0 2015-03-29
- Pass dispose, length & stale options to lru-cache (#22). - @gmaclennan

10
README.md

@ -57,7 +57,7 @@ function getCachedUser(id, cb) {
function getCachedUser(id, cb) {
memoryCache.wrap(id, function (cacheCallback) {
getUser(id, cacheCallback);
}, ttl, cb);
}, {ttl: ttl}, cb);
}
```
@ -147,7 +147,7 @@ app.get('/foo/bar', function(req, res) {
var ttl = 10;
memoryCache.wrap(cacheKey, function(cacheCallback) {
DB.find(req.query, cacheCallback);
}, ttl, function(err, result) {
}, {ttl: ttl}, function(err, result) {
respond(res, err, result);
});
});
@ -177,7 +177,7 @@ key2 = 'user_' + userId;
ttl = 5;
// Sets in all caches.
multiCache.set('foo2', 'bar2', ttl, function(err) {
multiCache.set('foo2', 'bar2', {ttl: ttl}, function(err) {
if (err) { throw err; }
// Fetches from highest priority cache that has the key.
@ -190,10 +190,10 @@ multiCache.set('foo2', 'bar2', ttl, function(err) {
});
});
// Note: ttl is optional in wrap()
// Note: options with ttl are optional in wrap()
multiCache.wrap(key2, function (cb) {
getUser(userId2, cb);
}, ttl, function (err, user) {
}, {ttl: ttl}, function (err, user) {
console.log(user);
// Second time fetches user from memoryCache, since it's highest priority.

4
examples/example.js

@ -8,7 +8,7 @@ var ttl; //Can't use a different ttl per set() call with memory cache
//
// Basic usage
//
memoryCache.set('foo', 'bar', ttl, function(err) {
memoryCache.set('foo', 'bar', function(err) {
if (err) { throw err; }
memoryCache.get('foo', function(err, result) {
@ -112,7 +112,7 @@ multiCache.wrap(key2, function(cb) {
});
// Sets in all caches.
multiCache.set('foo2', 'bar2', ttl2, function(err) {
multiCache.set('foo2', 'bar2', {ttl: ttl2}, function(err) {
if (err) { throw err; }
// Fetches from highest priority cache that has the key.

5
examples/redis_example/redis_store.js

@ -81,7 +81,10 @@ function redisStore(args) {
});
};
self.del = function(key, cb) {
self.del = function(key, options, cb) {
if (typeof options === 'function') {
cb = options;
}
connect(function(err, conn) {
if (err) { return cb(err); }
conn.del(key, handleResponse(conn, cb));

4
lib/caching.js

@ -22,8 +22,6 @@ var caching = function(args) {
} else {
self.store = args.store;
}
} else if (typeof args.store === 'string' && args.store.match(/\//)) {
self.store = require(args.store).create(args);
} else {
var storeName = args.store || 'memory';
self.store = require('./stores/' + storeName).create(args);
@ -66,7 +64,7 @@ var caching = function(args) {
self.wrap = function(key, work, options, cb) {
if (typeof options === 'function') {
cb = options;
options = undefined;
options = {};
}
var hasKey = callbackFiller.has(key);

4
lib/index.js

@ -1,10 +1,6 @@
/** @namespace cacheManager */
var cacheManager = {
caching: require('./caching'),
// Deprecate
//jscs:disable requireCamelCaseOrUpperCaseIdentifiers
multi_caching: require('./multi_caching'), //backward compat
//jscs:enable requireCamelCaseOrUpperCaseIdentifiers
multiCaching: require('./multi_caching')
};

55
lib/multi_caching.js

@ -6,8 +6,6 @@ var CallbackFiller = require('./callback_filler');
/**
* Module that lets you specify a hierarchy of caches.
*
* @memberof cacheManager
*
* @param {array} caches - Array of caching objects.
* @param {object} [options]
* @param {function} [options.isCacheableValue] - A callback function which is called
@ -36,7 +34,7 @@ var multiCaching = function(caches, options) {
function getFromHighestPriorityCache(key, options, cb) {
if (typeof options === 'function') {
cb = options;
options = undefined;
options = {};
}
var i = 0;
@ -54,21 +52,14 @@ var multiCaching = function(caches, options) {
next();
};
if (typeof options === 'object') {
cache.store.get(key, options, callback);
} else {
cache.store.get(key, callback);
}
}, cb);
}
function setInMultipleCaches(caches, opts, cb) {
opts.options = opts.options || {};
async.each(caches, function(cache, next) {
if (typeof opts.options === 'object') {
cache.store.set(opts.key, opts.value, opts.options, next);
} else {
cache.store.set(opts.key, opts.value, opts.ttl, next);
}
}, cb);
}
@ -97,13 +88,6 @@ var multiCaching = function(caches, options) {
});
};
/**
* This is for backward-compatibility
*/
//jscs:disable requireCamelCaseOrUpperCaseIdentifiers
self.get_and_pass_up = self.getAndPassUp;
//jscs:enable requireCamelCaseOrUpperCaseIdentifiers
/**
* Wraps a function in one or more caches.
* Has same API as regular caching module.
@ -122,21 +106,15 @@ var multiCaching = function(caches, options) {
self.wrap = function(key, work, options, cb) {
if (typeof options === 'function') {
cb = options;
options = undefined;
options = {};
}
function getOptsForSet(result) {
var opts = {
function getOptsForSet(value) {
return {
key: key,
value: result,
value: value,
options: options
};
if (typeof options !== 'object') {
opts.ttl = options;
}
return opts;
}
var hasKey = callbackFiller.has(key);
@ -187,17 +165,20 @@ var multiCaching = function(caches, options) {
* @param {string} key
* @param {*} value
* @param {object} [options] to pass to underlying set function.
* @param {function} cb
* @param {function} [cb]
*/
self.set = function(key, value, options, cb) {
if (typeof options === 'function') {
cb = options;
options = {};
}
var opts = {
key: key,
value: value,
options: options
};
if (typeof options !== 'object') {
opts.ttl = options;
}
setInMultipleCaches(caches, opts, cb);
};
@ -214,8 +195,9 @@ var multiCaching = function(caches, options) {
self.get = function(key, options, cb) {
if (typeof options === 'function') {
cb = options;
options = false;
options = {};
}
getFromHighestPriorityCache(key, options, cb);
};
@ -232,14 +214,11 @@ var multiCaching = function(caches, options) {
self.del = function(key, options, cb) {
if (typeof options === 'function') {
cb = options;
options = false;
options = {};
}
async.each(caches, function(cache, next) {
if (typeof options === 'object') {
cache.store.del(key, options, next);
} else {
cache.store.del(key, next);
}
}, cb);
};

3
lib/stores/memory.js

@ -16,6 +16,9 @@ var memoryStore = function(args) {
var lruCache = new Lru(lruOpts);
self.set = function(key, value, options, cb) {
if (typeof options === 'function') {
cb = options;
}
lruCache.set(key, value);
if (cb) {
process.nextTick(cb);

81
test/caching.unit.js

@ -19,7 +19,7 @@ var methods = {
describe("caching", function() {
var cache;
var key;
var ttl = 1;
var defaultTtl = 1;
var name;
var value;
@ -33,7 +33,7 @@ describe("caching", function() {
});
it("lets us set and get data in cache", function(done) {
cache.set(key, value, ttl, function(err) {
cache.set(key, value, {ttl: defaultTtl}, function(err) {
checkErr(err);
cache.get(key, function(err, result) {
@ -45,7 +45,7 @@ describe("caching", function() {
});
it("lets us set and get data without a callback", function(done) {
cache.set(key, value, ttl);
cache.set(key, value, {ttl: defaultTtl});
setTimeout(function() {
var result = cache.get(key);
@ -54,7 +54,7 @@ describe("caching", function() {
}, 20);
});
it("lets us set and get data without a ttl or callback", function(done) {
it("lets us set and get data without options object or callback", function(done) {
cache.set(key, value);
setTimeout(function() {
@ -74,7 +74,7 @@ describe("caching", function() {
cache = caching({store: store});
key = support.random.string(20);
value = support.random.string();
cache.set(key, value, ttl, function(err) {
cache.set(key, value, {ttl: defaultTtl}, function(err) {
checkErr(err);
done();
});
@ -121,13 +121,13 @@ describe("caching", function() {
cache = caching({store: 'memory'});
key = support.random.string(20);
value = support.random.string();
cache.set(key, value, ttl, function(err) {
cache.set(key, value, function(err) {
checkErr(err);
key2 = support.random.string(20);
value2 = support.random.string();
cache.set(key2, value2, ttl, done);
cache.set(key2, value2, done);
});
});
@ -241,7 +241,7 @@ describe("caching", function() {
key = support.random.string(20);
savedKeys.push(key);
value = support.random.string();
cache.set(key, value, ttl, cb);
cache.set(key, value, cb);
}, done);
});
@ -262,14 +262,15 @@ describe("caching", function() {
describe("wrap()", function() {
describe("using memory (lru-cache) store", function() {
var memoryStoreStub;
var opts;
beforeEach(function() {
ttl = 0.1;
memoryStoreStub = memoryStore.create({ttl: ttl});
opts = {ttl: 0.1};
memoryStoreStub = memoryStore.create(opts);
sinon.stub(memoryStore, 'create').returns(memoryStoreStub);
cache = caching({store: 'memory', ttl: ttl, ignoreCacheErrors: false});
cache = caching({store: 'memory', ttl: opts.ttl, ignoreCacheErrors: false});
key = support.random.string(20);
name = support.random.string();
});
@ -290,10 +291,10 @@ describe("caching", function() {
it("when a ttl is passed in", function(done) {
cache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, ttl, function(err, widget) {
}, opts, function(err, widget) {
checkErr(err);
assert.deepEqual(widget, {name: name});
sinon.assert.calledWith(memoryStoreStub.set, key, {name: name}, ttl);
sinon.assert.calledWith(memoryStoreStub.set, key, {name: name}, opts);
done();
});
});
@ -304,7 +305,7 @@ describe("caching", function() {
}, function(err, widget) {
checkErr(err);
assert.deepEqual(widget, {name: name});
sinon.assert.calledWith(memoryStoreStub.set, key, {name: name}, undefined);
sinon.assert.calledWith(memoryStoreStub.set, key, {name: name}, {});
done();
});
});
@ -314,7 +315,7 @@ describe("caching", function() {
function getCachedWidget(name, cb) {
cache.wrap(key, function(cacheCb) {
methods.getWidget(name, cacheCb);
}, ttl, cb);
}, opts, cb);
}
beforeEach(function(done) {
@ -345,7 +346,7 @@ describe("caching", function() {
funcCalled = true;
cb(err, result);
});
}, ttl, function(err, widget) {
}, function(err, widget) {
checkErr(err);
assert.deepEqual(widget, {name: name});
assert.ok(memoryStoreStub.get.calledWith(key));
@ -368,7 +369,7 @@ describe("caching", function() {
function getCachedFalseyValue(cb) {
cache.wrap(key, function(cacheCb) {
getFalseyValue(cacheCb);
}, ttl, cb);
}, cb);
}
beforeEach(function(done) {
@ -424,7 +425,7 @@ describe("caching", function() {
getValue(name, function(err, result) {
cacheCb(err, result);
});
}, ttl, cb);
}, {ttl: defaultTtl}, cb);
}
beforeEach(function() {
@ -490,9 +491,11 @@ describe("caching", function() {
});
it("expires cached result after ttl seconds", function(done) {
var ttl = 0.1;
cache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, ttl, function(err, widget) {
}, {ttl: ttl}, function(err, widget) {
checkErr(err);
assert.deepEqual(widget, {name: name});
@ -529,7 +532,7 @@ describe("caching", function() {
it("bubbles up that error", function(done) {
cache.wrap(key, function() {
throw fakeError;
}, ttl, function(err) {
}, function(err) {
assert.equal(err, fakeError);
done();
});
@ -547,7 +550,7 @@ describe("caching", function() {
cache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, ttl, function(err) {
}, function(err) {
assert.equal(err, fakeError);
memoryStoreStub.get.restore();
done();
@ -557,7 +560,7 @@ describe("caching", function() {
context("and ignoreCacheErrors is set to true", function() {
it("does not bubble up that error", function(done) {
cache = caching({store: 'memory', ttl: ttl, ignoreCacheErrors: true});
cache = caching({store: 'memory', ttl: defaultTtl, ignoreCacheErrors: true});
var fakeError = new Error(support.random.string());
@ -567,7 +570,7 @@ describe("caching", function() {
cache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, ttl, function(err) {
}, function(err) {
assert.equal(err, null);
memoryStoreStub.get.restore();
done();
@ -587,7 +590,7 @@ describe("caching", function() {
cache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, ttl, function(err) {
}, function(err) {
assert.equal(err, fakeError);
memoryStoreStub.set.restore();
done();
@ -597,16 +600,14 @@ describe("caching", function() {
context("and ignoreCacheErrors is set to true", function() {
it("does not bubbles up that error", function(done) {
cache = caching({store: 'memory', ttl: ttl, ignoreCacheErrors: true});
cache = caching({store: 'memory', ttl: defaultTtl, ignoreCacheErrors: true});
var fakeError = new Error(support.random.string());
sinon.stub(memoryStoreStub, 'set', function(key, val, ttl, cb) {
cb(fakeError);
});
sinon.stub(memoryStoreStub, 'set').yields(fakeError);
cache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, ttl, function(err) {
}, function(err) {
assert.equal(err, null);
memoryStoreStub.set.restore();
done();
@ -624,7 +625,7 @@ describe("caching", function() {
cache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, ttl, function(err, widget) {
}, function(err, widget) {
methods.getWidget.restore();
assert.equal(err, fakeError);
assert.ok(!widget);
@ -661,7 +662,7 @@ describe("caching", function() {
async.each(values, function(val, next) {
cache.wrap('key', function(cb) {
construct(val, cb);
}, ttl, function(err, result) {
}, function(err, result) {
assert.equal(result, 'value');
next(err);
});
@ -683,21 +684,9 @@ describe("caching", function() {
describe("instantiating with custom store", function() {
it("allows us to pass in our own store object", function(done) {
var store = memoryStore.create({ttl: ttl});
var store = memoryStore.create({ttl: defaultTtl});
cache = caching({store: store});
cache.set(key, value, ttl, function(err) {
checkErr(err);
cache.get(key, function(err, result) {
assert.equal(result, value);
done();
});
});
});
it("allows us to pass in a path to our own store", function(done) {
var storePath = '../lib/stores/memory';
cache = caching({store: storePath});
cache.set(key, value, ttl, function(err) {
cache.set(key, value, function(err) {
checkErr(err);
cache.get(key, function(err, result) {
assert.equal(result, value);
@ -709,7 +698,7 @@ describe("caching", function() {
it("allows us to pass in a module (uninstantiated)", function(done) {
var store = memoryStore;
cache = caching({store: store});
cache.set(key, value, ttl, function(err) {
cache.set(key, value, {ttl: defaultTtl}, function(err) {
checkErr(err);
cache.get(key, function(err, result) {
assert.equal(result, value);

110
test/multi_caching.unit.js

@ -23,10 +23,11 @@ describe("multiCaching", function() {
var key;
var memoryTtl;
var name;
var ttl = 5;
var defaultTtl;
beforeEach(function() {
memoryTtl = 0.1;
defaultTtl = 5;
memoryCache = caching({store: 'memory', ttl: memoryTtl});
memoryCache2 = caching({store: 'memory', ttl: memoryTtl});
@ -47,7 +48,7 @@ describe("multiCaching", function() {
describe("set()", function() {
it("lets us set data in all caches", function(done) {
multiCache.set(key, value, ttl, function(err) {
multiCache.set(key, value, {ttl: defaultTtl}, function(err) {
checkErr(err);
memoryCache.get(key, function(err, result) {
@ -69,7 +70,7 @@ describe("multiCaching", function() {
});
it("lets us set data without a callback", function(done) {
multiCache.set(key, value, ttl);
multiCache.set(key, value, {ttl: defaultTtl});
setTimeout(function() {
multiCache.get(key, function(err, result) {
checkErr(err);
@ -94,7 +95,34 @@ describe("multiCaching", function() {
}, 20);
});
it("lets us set data without a ttl or callback", function(done) {
it("lets us set data without an options param", function(done) {
multiCache.set(key, value, function(err) {
checkErr(err);
multiCache.get(key, function(err, result) {
checkErr(err);
assert.equal(result, value);
memoryCache.get(key, function(err, result) {
checkErr(err);
assert.equal(result, value);
memoryCache2.get(key, function(err, result) {
checkErr(err);
assert.equal(result, value);
memoryCache3.get(key, function(err, result) {
checkErr(err);
assert.equal(result, value);
done();
});
});
});
});
});
});
it("lets us set data without options or callback", function(done) {
multiCache.set(key, value);
setTimeout(function() {
multiCache.get(key, function(err, result) {
@ -123,7 +151,7 @@ describe("multiCaching", function() {
describe("get()", function() {
it("gets data from first cache that has it", function(done) {
memoryCache3.set(key, value, ttl, function(err) {
memoryCache3.set(key, value, function(err) {
checkErr(err);
multiCache.get(key, function(err, result) {
@ -133,11 +161,31 @@ describe("multiCaching", function() {
});
});
});
it("passes any options to underlying caches", function(done) {
multiCache.set(key, value, function(err) {
checkErr(err);
sinon.spy(memoryCache.store, 'get');
var opts = {foo: 'bar'};
multiCache.get(key, opts, function(err, result) {
checkErr(err);
assert.equal(result, value);
assert.ok(memoryCache.store.get.calledWith(key, opts));
memoryCache.store.get.restore();
done();
});
});
});
});
describe("del()", function() {
it("lets us delete data in all caches", function(done) {
multiCache.set(key, value, ttl, function(err) {
multiCache.set(key, value, function(err) {
checkErr(err);
multiCache.del(key, function(err) {
@ -162,7 +210,7 @@ describe("multiCaching", function() {
});
it("lets us delete data without a callback", function(done) {
multiCache.set(key, value, ttl, function(err) {
multiCache.set(key, value, function(err) {
checkErr(err);
multiCache.del(key);
@ -201,7 +249,7 @@ describe("multiCaching", function() {
});
it("gets data from first cache that has it", function(done) {
memoryCache3.set(key, value, ttl, function(err) {
memoryCache3.set(key, value, function(err) {
checkErr(err);
multiCache.getAndPassUp(key, function(err, result) {
@ -257,7 +305,7 @@ describe("multiCaching", function() {
});
it("checks to see if higher levels have item", function(done) {
memoryCache3.set(key, value, ttl, function(err) {
memoryCache3.set(key, value, function(err) {
checkErr(err);
multiCache.getAndPassUp(key, function(err, result) {
@ -280,9 +328,9 @@ describe("multiCaching", function() {
var memoryStoreStub;
beforeEach(function() {
memoryStoreStub = memoryStore.create({ttl: ttl});
memoryStoreStub = memoryStore.create({ttl: defaultTtl});
sinon.stub(memoryStore, 'create').returns(memoryStoreStub);
memoryCache = caching({store: 'memory', ttl: ttl});
memoryCache = caching({store: 'memory', ttl: defaultTtl});
multiCache = multiCaching([memoryCache]);
fakeError = new Error(support.random.string());
sinon.stub(memoryStoreStub, 'get').yields(fakeError);
@ -318,13 +366,17 @@ describe("multiCaching", function() {
memoryCache3.store.set.restore();
});
/**
* Note: it's up to the underlying cache implementation to handle the ttl number.
* We're just testing that the ttl gets passed to the underlying store.
*/
it('when a ttl number is passed in', function(done) {
multiCache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, ttl, function(err, widget) {
}, defaultTtl, function(err, widget) {
checkErr(err);
assert.deepEqual(widget, {name: name});
sinon.assert.calledWith(memoryCache3.store.set, key, {name: name}, ttl);
sinon.assert.calledWith(memoryCache3.store.set, key, {name: name}, defaultTtl);
done();
});
});
@ -332,15 +384,15 @@ describe("multiCaching", function() {
it('when a ttl option is passed in', function(done) {
multiCache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, {ttl: ttl}, function(err, widget) {
}, {ttl: defaultTtl}, function(err, widget) {
checkErr(err);
assert.deepEqual(widget, {name: name});
sinon.assert.calledWith(memoryCache3.store.set, key, {name: name}, {ttl: ttl});
sinon.assert.calledWith(memoryCache3.store.set, key, {name: name}, {ttl: defaultTtl});
done();
});
});
it('when a ttl is not passed in', function(done) {
it('when no options are passed in', function(done) {
multiCache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, function(err, widget) {
@ -355,9 +407,7 @@ describe("multiCaching", function() {
context("when wrapped function calls back with an error", function() {
it("calls back with that error", function(done) {
var fakeError = new Error(support.random.string());
sinon.stub(methods, 'getWidget', function(name, cb) {
cb(fakeError, {name: name});
});
sinon.stub(methods, 'getWidget').yields(fakeError, {name: name});
multiCache.wrap(key, function(cb) {
methods.getWidget(name, cb);
@ -383,7 +433,7 @@ describe("multiCaching", function() {
function getCachedFalseyValue(cb) {
multiCache.wrap(key, function(cacheCb) {
getFalseyValue(cacheCb);
}, ttl, cb);
}, cb);
}
beforeEach(function(done) {
@ -444,7 +494,7 @@ describe("multiCaching", function() {
getValue(name, function(err, result) {
cacheCb(err, result);
});
}, ttl, cb);
}, cb);
}
beforeEach(function() {
@ -523,7 +573,7 @@ describe("multiCaching", function() {
context("when value exists in first store but not second", function() {
it("returns value from first store, does not set it in second", function(done) {
memoryCache.set(key, {name: name}, ttl, function(err) {
memoryCache.set(key, {name: name}, function(err) {
checkErr(err);
multiCache.wrap(key, function(cb) {
@ -544,7 +594,7 @@ describe("multiCaching", function() {
context("when value exists in second store but not first", function() {
it("returns value from second store, sets it in first store", function(done) {
memoryCache3.set(key, {name: name}, ttl, function(err) {
memoryCache3.set(key, {name: name}, function(err) {
checkErr(err);
multiCache.wrap(key, function(cb) {
@ -606,7 +656,7 @@ describe("multiCaching", function() {
context("when value exists in first store only", function() {
it("returns value from first store, does not set it in second or third", function(done) {
memoryCache.set(key, {name: name}, ttl, function(err) {
memoryCache.set(key, {name: name}, function(err) {
checkErr(err);
multiCache.wrap(key, function(cb) {
@ -632,7 +682,7 @@ describe("multiCaching", function() {
context("when value exists in second store only", function() {
it("returns value from second store, sets it in first store, does not set third store", function(done) {
memoryCache3.set(key, {name: name}, ttl, function(err) {
memoryCache3.set(key, {name: name}, function(err) {
checkErr(err);
multiCache.wrap(key, function(cb) {
@ -658,7 +708,7 @@ describe("multiCaching", function() {
context("when value exists in third store only", function() {
it("returns value from third store, sets it in first and second stores", function(done) {
memoryCache2.set(key, {name: name}, ttl, function(err) {
memoryCache2.set(key, {name: name}, function(err) {
checkErr(err);
multiCache.wrap(key, function(cb) {
@ -745,9 +795,7 @@ describe("multiCaching", function() {
it("bubbles up that error", function(done) {
var fakeError = new Error(support.random.string());
sinon.stub(memoryStoreStub, 'get', function(key, cb) {
cb(fakeError);
});
sinon.stub(memoryStoreStub, 'get').yields(fakeError);
multiCache.wrap(key, function(cb) {
methods.getWidget(name, cb);
@ -763,9 +811,7 @@ describe("multiCaching", function() {
it("bubbles up that error", function(done) {
var fakeError = new Error(support.random.string());
sinon.stub(memoryStoreStub, 'set', function(key, val, ttl, cb) {
cb(fakeError);
});
sinon.stub(memoryStoreStub, 'set').yields(fakeError);
multiCache.wrap(key, function(cb) {
methods.getWidget(name, cb);

209
test/stores/options.unit.js

@ -1,209 +0,0 @@
var caching = require("../../index");
var assert = require("assert");
var support = require("../support");
var checkErr = support.checkErr;
var memoryFlag = "";
var key;
var value;
var testStore = function(args) {
args = args || {};
var self = {};
self.name = "options";
self.store = {};
self.get = function(key, options, cb) {
var optionsMapped = false;
if (typeof options === "function") {
cb = options;
options = false;
optionsMapped = true;
}
if (options && options.value) {
return cb(null, options.value + "ValueOption");
} else if (options && options.fn) {
options.fn("GetFunctionOption");
return cb(null, "GetFunctionOption");
} else if (options && options.runNormal) {
return cb(null, self.store[key]);
} else if (optionsMapped) {
return cb();
}
return cb("Error No Options");
};
self.set = function(key, value, options, cb) {
var optionsMapped = false;
if (typeof options === "function") {
cb = options;
options = false;
optionsMapped = true;
} else if (typeof options !== "object") {
options = {ttl: options, runNormal: true};
}
if (options && options.value) {
memoryFlag = options.value + "ValueOption";
return cb();
} else if (options && options.fn) {
options.fn("SetFunctionOption");
return cb();
} else if (options && options.runNormal) {
self.store[key] = value;
return cb(null, self.store[key]);
} else if (optionsMapped) {
return cb();
}
return cb("Error No Options");
};
self.del = function(key, options, cb) {
var optionsMapped = false;
if (typeof options === "function") {
cb = options;
options = false;
optionsMapped = true;
}
if (options && options.value) {
memoryFlag = options.value + "ValueOption";
return cb();
} else if (options && options.fn) {
options.fn("DeleteFunctionOption");
return cb();
} else if (options && options.runNormal) {
delete self.store[key];
return cb(null, "");
} else if (optionsMapped) {
return cb();
}
return cb("Error No Options");
};
return {
create: function() {
return self;
}
};
};
describe("Methods with options", function() {
var testInstance = caching.caching({store: testStore()});
var testCache;
before(function() {
key = support.random.string(20);
value = support.random.string(20);
testCache = caching.multiCaching([testInstance]);
});
describe("get with options", function() {
it("lets us pass options by value", function(done) {
var options = {value: value};
testCache.get(key, options, function(err, response) {
assert.equal(response, value + "ValueOption");
done();
});
});
it("lets us pass options by function", function(done) {
var options = {
fn: function(response) {
assert.equal(response, "GetFunctionOption");
done();
}
};
testCache.get(key, options, function(err, response) {
assert.equal(response, "GetFunctionOption");
});
});
});
describe("set with options", function() {
var ttl = 60;
it("lets us pass options by value", function(done) {
var options = {ttl: ttl, value: value};
testCache.set(key, value, options, function() {
assert.equal(memoryFlag, value + "ValueOption");
done();
});
});
it("lets us pass options by function", function(done) {
var options = {
ttl: ttl,
fn: function(response) {
assert.equal(response, "SetFunctionOption");
done();
}
};
testCache.set(key, value, options, function() {}, options);
});
});
describe("delete with options", function() {
it("lets us pass options by value", function(done) {
var options = {value: value};
testCache.del(key, options, function() {
assert.equal(memoryFlag,value + "ValueOption");
done();
});
});
it("lets us pass options by function", function(done) {
var options = {
fn: function(response) {
assert.equal(response, "DeleteFunctionOption");
done();
}
};
testCache.del(key, options, function() {}, options);
});
});
});
describe("Multiple stores with options", function() {
var testInstance = caching.caching({store: testStore()});
var memInstance = caching.caching({store: "memory"});
var testCache;
var options = {runNormal: true};
var ttl = 1;
before(function() {
key = support.random.string(20);
value = support.random.string(20);
testCache = caching.multiCaching([testInstance, memInstance]);
});
it("lets us pass options which only one store uses", function() {
testCache.set(key, value, options, function(err) {
checkErr(err);
testCache.get(key, options, function(err, response) {
checkErr(err);
assert.equal(response, value);
testCache.del(key, options, function(err) {
checkErr(err);
testCache.get(key, options, function(err, response) {
checkErr(err);
assert.equal(response, undefined);
});
});
});
});
});
it("lets us not pass options which only one store uses", function() {
testCache.set(key, value, ttl, function(err) {
checkErr(err);
testCache.get(key, function(err, response) {
checkErr(err);
assert.equal(response, value);
testCache.del(key, function(err) {
checkErr(err);
testCache.get(key, function(err, response) {
checkErr(err);
assert.equal(response, undefined);
});
});
});
});
});
});

3
test/support.js

@ -90,9 +90,8 @@ var support = {
testSetGetDel: function(cache, cb) {
var key = 'TEST' + support.random.string();
var val = support.random.string();
var ttl;
cache.set(key, val, ttl, function(err) {
cache.set(key, val, function(err) {
if (err) { return cb(err); }
cache.get(key, function(err, result) {

Loading…
Cancel
Save