You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

295 lines
10 KiB

var assert = require('assert');
var sinon = require('sinon');
var redis = require('redis');
var Lru = require("lru-cache")
var support = require('./support');
var check_err = support.check_err;
var caching = require('../index').caching;
var memory_store = require('../lib/stores/memory');
function get_widget(name, cb) {
cb(null, {name: name});
}
describe("caching", function() {
var cache;
var key;
var ttl;
var name;
var value;
describe("get() and set()", function() {
context("using redis store", function() {
beforeEach(function() {
cache = caching({store: 'redis'});
key = support.random.string(20);
value = support.random.string();
});
it("lets us set and get data in cache", function(done) {
cache.set(key, value, function(err, result) {
check_err(err);
cache.get(key, function(err, result) {
assert.equal(result, value);
done();
});
});
});
});
context("using memory store", function() {
beforeEach(function() {
cache = caching({store: 'memory'});
key = support.random.string(20);
value = support.random.string();
});
it("lets us set and get data in cache", function(done) {
cache.set(key, value, function(err, result) {
check_err(err);
cache.get(key, function(err, result) {
assert.equal(result, value);
done();
});
});
});
});
});
describe("del()", function() {
['redis', 'memory'].forEach(function(store) {
context("using " + store + " store", function() {
beforeEach(function(done) {
cache = caching({store: store});
key = support.random.string(20);
value = support.random.string();
cache.set(key, value, function(err, result) {
check_err(err);
done();
});
});
it("deletes data from cache", function(done) {
cache.get(key, function(err, result) {
assert.equal(result, value);
cache.del(key, function(err, result) {
check_err(err);
cache.get(key, function(err, result) {
assert.ok(!result);
done();
});
});
});
});
});
});
});
describe("wrap()", function() {
context("using redis store", function() {
var redis_client;
before(function() {
redis_client = redis.createClient();
sinon.stub(redis, 'createClient').returns(redis_client);
});
beforeEach(function() {
cache = caching({store: 'redis'});
key = support.random.string(20);
name = support.random.string();
});
after(function() {
redis.createClient.restore();
});
it("calls back with the result of the wrapped function", function(done) {
cache.wrap(key, function(cb) {
get_widget(name, cb);
}, function(err, widget) {
check_err(err);
assert.deepEqual(widget, {name: name});
done();
});
});
it("caches the result of the function in redis", function(done) {
cache.wrap(key, function(cb) {
get_widget(name, cb);
}, function(err, widget) {
check_err(err);
redis_client.get(key, function(err, result) {
check_err(err);
assert.deepEqual(JSON.parse(result), {name: name});
done();
});
});
});
it("retrieves data from redis when available", function(done) {
cache.wrap(key, function(cb) {
get_widget(name, cb);
}, function(err, widget) {
check_err(err);
redis_client.get(key, function(err, result) {
check_err(err);
sinon.spy(redis_client, 'get');
cache.wrap(key, function(cb) {
get_widget(name, cb);
}, function(err, widget) {
check_err(err);
assert.deepEqual(widget, {name: name});
assert.ok(redis_client.get.calledWith(key));
redis_client.get.restore();
done();
});
});
});
});
context("when using ttl", function() {
beforeEach(function() {
ttl = 50;
cache = caching({store: 'redis', ttl: ttl});
});
it("expires cached result after ttl seconds", function(done) {
cache.wrap(key, function(cb) {
get_widget(name, cb);
}, function(err, widget) {
check_err(err);
redis_client.ttl(key, function(err, result) {
check_err(err);
support.assert_within(result, ttl, 2);
done();
});
});
});
});
});
describe("using memory (lru-cache) store", function() {
var memory_store_stub;
beforeEach(function() {
ttl = 0.1;
memory_store_stub = memory_store.create({ttl: ttl});
sinon.stub(memory_store, 'create').returns(memory_store_stub);
cache = caching({store: 'memory', ttl: ttl});
key = support.random.string(20);
name = support.random.string();
});
afterEach(function() {
memory_store.create.restore();
});
it("calls back with the result of a function", function(done) {
cache.wrap(key, function(cb) {
get_widget(name, cb);
}, function(err, widget) {
check_err(err);
assert.deepEqual(widget, {name: name});
done();
});
});
it("retrieves data from memory when available", function(done) {
cache.wrap(key, function(cb) {
get_widget(name, cb);
}, function(err, widget) {
check_err(err);
memory_store_stub.get(key, function(err, result) {
check_err(err);
sinon.spy(memory_store_stub, 'get');
var func_called = false;
cache.wrap(key, function(cb) {
get_widget(name, function(err, result) {
func_called = true;
cb(err, result);
});
}, function(err, widget) {
check_err(err);
assert.deepEqual(widget, {name: name});
assert.ok(memory_store_stub.get.calledWith(key));
assert.ok(!func_called);
memory_store_stub.get.restore();
done();
});
});
});
});
it("expires cached result after ttl seconds", function(done) {
cache.wrap(key, function(cb) {
get_widget(name, cb);
}, function(err, widget) {
check_err(err);
memory_store_stub.get(key, function(err, result) {
check_err(err);
assert.deepEqual(widget, {name: name});
var func_called = false;
setTimeout(function () {
cache.wrap(key, function(cb) {
get_widget(name, function(err, result) {
func_called = true;
cb(err, result);
});
}, function(err, widget) {
check_err(err);
assert.ok(func_called);
assert.deepEqual(widget, {name: name});
done();
});
}, (ttl * 1000 + 10));
});
});
});
});
});
describe("instantiating with custom store", function() {
it("allows us to pass in our own store object", function(done) {
var store = memory_store.create({ttl: ttl});
cache = caching({store: store});
cache.set(key, value, function(err, result) {
check_err(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 store_path = '../lib/stores/memory';
cache = caching({store: store_path});
cache.set(key, value, function(err, result) {
check_err(err);
cache.get(key, function(err, result) {
assert.equal(result, value);
done();
});
});
});
});
});