Here's the simple expiring cache:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
steal(function() { | |
function ExpiringCache(options) { | |
if (!(this instanceof ExpiringCache)) { | |
return new ExpiringCache(options); | |
} | |
this._items = {}; | |
this._size = 0; | |
this._defaultExpiry = options ? options.defaultExpiry : 60 * 1000; | |
} | |
ExpiringCache.prototype.get = function(key) { | |
var item = this._items[key]; | |
if (item) { | |
if (new Date() - item.ctime >= item.expiry) { | |
delete this._items[key]; | |
this._size--; | |
return null; | |
} | |
} | |
return item ? item.val : null; | |
}; | |
ExpiringCache.prototype.put = function(key, val, expiry) { | |
var item = this.get(key); | |
this._items[key] = { | |
ctime: new Date().getTime(), | |
expiry: expiry || this._defaultExpiry, | |
val: val | |
} | |
if (!item) { | |
this._size++; | |
} | |
return item; | |
}; | |
ExpiringCache.prototype.remove = function(key) { | |
var item = this.get(key); | |
if (item) { | |
delete this._items[key]; | |
this._size--; | |
} | |
return item; | |
}; | |
ExpiringCache.prototype.size = function() { | |
return this._size; | |
} | |
window.ExpiringCache = ExpiringCache; | |
}) |
And here's the deferred loading cache:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*global ExpiringCache:false */ | |
steal('jquery', 'expiring_cache.js', function() { | |
function LoadingCache() { | |
this.cache = new ExpiringCache(); | |
} | |
LoadingCache.prototype.load = function(path) { | |
var item = this.cache.get(path); | |
if (!item) { | |
item = $.Deferred(); | |
this.cache.put(path, item); | |
} | |
if (item.state() !== 'resolved') { | |
$.get(path, function(data) { | |
item.resolve(data); | |
}); | |
} | |
return item; | |
}; | |
window.LoadingCache = LoadingCache; | |
}); |
Jasmine spec for the loading cache:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*global LoadingCache:false */ | |
steal('app/util/loading_cache.js', function() { | |
describe("loading cache", function() { | |
var cache; | |
beforeEach(function() { | |
spyOn(jQuery, 'get'); | |
cache = new LoadingCache(); | |
}) | |
it('returns deferred for non-existent entry', function() { | |
var item = cache.load('foo'); | |
expect('resolve' in item).toBeTruthy(); | |
expect(item.state()).not.toEqual('resolved'); | |
}) | |
it('invokes $.get with given path for unloaded entry', function() { | |
cache.load('foo'); | |
expect(jQuery.get).toHaveBeenCalled(); | |
expect(jQuery.get.calls[0].args[0]).toEqual('foo'); | |
}) | |
it('resolves the item deferred with the result of the $.get', function() { | |
var item = cache.load('foo'), | |
fn = jQuery.get.calls[0].args[1]; | |
fn('bar'); | |
expect(item.state()).toEqual('resolved'); | |
item.done(function(val) { | |
expect(val).toEqual('bar'); | |
}) | |
}) | |
it('doesnt call $.get again for resolved entry', function() { | |
cache.load('foo'); | |
var fn = jQuery.get.calls[0].args[1]; | |
fn('bar'); | |
cache.load('foo'); | |
expect(jQuery.get.calls.length).toBe(1); | |
}) | |
}) | |
}) |
In my next post, I'll show how to use a jasmine spec runner for steal to run jasmine steal specs in grunt.
No comments:
Post a Comment