Skip to content

Commit

Permalink
Merge pull request #57 from jmdobry/feature-heap-delete
Browse files Browse the repository at this point in the history
Feature heap delete
  • Loading branch information
jmdobry committed Oct 6, 2013
2 parents d1e26b4 + f4f327d commit daab6f1
Show file tree
Hide file tree
Showing 31 changed files with 2,699 additions and 1,442 deletions.
4 changes: 1 addition & 3 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ module.exports = function (grunt) {
preprocessors: {
'src/angular-cache.js': ['coverage']
},
reporters: {
reporters: ['progress', 'coverage']
}
reporters: ['progress', 'coverage']
}
},
jsdoc : {
Expand Down
2 changes: 1 addition & 1 deletion demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ app.service('DemoService', function ($log, $angularCacheFactory) {
storageMode: 'localStorage',
deleteOnExpire: 'none'
}),
$angularCacheFactory('maxAgeCache', {
$angularCacheFactory('passiveDeleteCache', {
maxAge: 12000,
deleteOnExpire: 'passive',
onExpire: function (key, value, done) {
Expand Down
1 change: 1 addition & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = function (config) {
'test/vendor/angular-1.1.5.min.js',
'test/vendor/angular-mocks-1.1.5.js',
'src/angular-cache.js',
'test/karma.start.js',
'test/*.js'
],
logLevel: config.LOG_DEBUG,
Expand Down
671 changes: 442 additions & 229 deletions src/angular-cache.js

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions test/angularCache.destroy-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
describe('AngularCache.destroy()', function () {
it('should destroy the cache and remove all traces of its existence.', function () {
var cache = $angularCacheFactory('cache');
cache.destroy();
expect(cache.info()).toEqual({ size: 0 });
expect($angularCacheFactory.get('cache')).toEqual(undefined);
});
it('should remove items from localStorage when storageMode is used.', function () {
var localStorageCache = $angularCacheFactory('localStorageCache', { storageMode: 'localStorage' }),
sessionStorageCache = $angularCacheFactory('sessionStorageCache', { storageMode: 'sessionStorage' });

localStorageCache.put('item1', 'value1');
sessionStorageCache.put('item1', 'value1');
localStorageCache.put('item2', 'value2');
sessionStorageCache.put('item2', 'value2');

if (localStorage) {
expect(angular.fromJson(localStorage.getItem('angular-cache.caches.localStorageCache.data.item1')).value).toEqual('value1');
expect(angular.fromJson(localStorage.getItem('angular-cache.caches.localStorageCache.data.item2')).value).toEqual('value2');
expect(localStorage.getItem('angular-cache.caches.localStorageCache.keys')).toEqual('["item1","item2"]');
}
if (sessionStorage) {
expect(angular.fromJson(sessionStorage.getItem('angular-cache.caches.sessionStorageCache.data.item1')).value).toEqual('value1');
expect(angular.fromJson(sessionStorage.getItem('angular-cache.caches.sessionStorageCache.data.item2')).value).toEqual('value2');
expect(sessionStorage.getItem('angular-cache.caches.sessionStorageCache.keys')).toEqual('["item1","item2"]');
}

localStorageCache.destroy();
sessionStorageCache.destroy();

if (localStorage) {
expect(angular.fromJson(localStorage.getItem('angular-cache.caches.localStorageCache.data.item1'))).toEqual(null);
expect(angular.fromJson(localStorage.getItem('angular-cache.caches.localStorageCache.data.item2'))).toEqual(null);
expect(localStorage.getItem('angular-cache.caches.localStorageCache.keys')).toEqual(null);
}
if (sessionStorage) {
expect(angular.fromJson(sessionStorage.getItem('angular-cache.caches.sessionStorageCache.data.item1'))).toEqual(null);
expect(angular.fromJson(sessionStorage.getItem('angular-cache.caches.sessionStorageCache.data.item2'))).toEqual(null);
expect(sessionStorage.getItem('angular-cache.caches.sessionStorageCache.keys')).toEqual(null);
}
});
});
116 changes: 116 additions & 0 deletions test/angularCache.get-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
describe('AngularCache.get(key)', function () {
it('should throw an error if "key" is not a string.', function () {
var cache = $angularCacheFactory('cache');
for (var i = 0; i < TYPES_EXCEPT_STRING.length; i++) {
try {
cache.get(TYPES_EXCEPT_STRING[i]);
fail(TYPES_EXCEPT_STRING[i]);
} catch (err) {
expect(err.message).toEqual('AngularCache.get(key, options): key: must be a string!');
continue;
}
fail(TYPES_EXCEPT_STRING[i]);
}
});
it('should throw an error if "options" is not an object.', function () {
var cache = $angularCacheFactory('cache');
for (var i = 0; i < TYPES_EXCEPT_OBJECT.length; i++) {
try {
cache.get('item', TYPES_EXCEPT_OBJECT[i]);
if (TYPES_EXCEPT_OBJECT[i] !== null && TYPES_EXCEPT_OBJECT[i] !== undefined && TYPES_EXCEPT_OBJECT[i] !== false) {
fail(TYPES_EXCEPT_OBJECT[i]);
}
} catch (err) {
expect(err.message).toEqual('AngularCache.get(key, options): options: must be an object!');
continue;
}
if (TYPES_EXCEPT_OBJECT[i] !== null && TYPES_EXCEPT_OBJECT[i] !== undefined && TYPES_EXCEPT_OBJECT[i] !== false) {
fail(TYPES_EXCEPT_OBJECT[i]);
}
}
});
it('should throw an error if "onExpire" is not a function.', function () {
var cache = $angularCacheFactory('cache');
for (var i = 0; i < TYPES_EXCEPT_FUNCTION.length; i++) {
try {
cache.get('item', { onExpire: TYPES_EXCEPT_FUNCTION[i] });
if (TYPES_EXCEPT_FUNCTION[i] !== null && TYPES_EXCEPT_FUNCTION[i] !== undefined && TYPES_EXCEPT_FUNCTION[i] !== false) {
fail(TYPES_EXCEPT_FUNCTION[i]);
}
} catch (err) {
expect(err.message).toEqual('AngularCache.get(key, options): onExpire: must be a function!');
continue;
}
if (TYPES_EXCEPT_FUNCTION[i] !== null && TYPES_EXCEPT_FUNCTION[i] !== undefined && TYPES_EXCEPT_FUNCTION[i] !== false) {
fail(TYPES_EXCEPT_FUNCTION[i]);
}
}
});
it('should return the correct value for the specified key.', function () {
var cache = $angularCacheFactory('cache');
var value1 = 'value1',
value2 = 2,
value3 = {
value3: 'stuff'
};
cache.put('item1', value1);
cache.put('item2', value2);
cache.put('item3', value3);
expect(cache.get('item1')).toEqual(value1);
expect(cache.get('item2')).toEqual(value2);
expect(cache.get('item3')).toEqual(value3);
});
it('should return undefined if the key isn\'t in the cache.', function () {
var cache = $angularCacheFactory('cache');
expect(cache.get('item')).toEqual(undefined);
});
it('should execute globally configured "onExpire" callback if the item is expired in passive mode and global "onExpire" callback is configured.', function () {
var cache = $angularCacheFactory('cache', {
maxAge: 10,
recycleFreq: 20,
deleteOnExpire: 'passive',
onExpire: function (key, value, done) {
done(key, value, 'executed global callback');
}
});
cache.put('item', 'value');
waits(100);
runs(function () {
cache.get('item', { onExpire: function (key, value, test) {
expect(key).toEqual('item');
expect(value).toEqual('value');
expect(test).toEqual('executed global callback');
}});
});
});
it('should execute globally configured "onExpire" callback when an item is aggressively deleted and global "onExpire" callback is configured.', function () {
var onExpire = jasmine.createSpy();
var cache = $angularCacheFactory('cache', {
maxAge: 10,
recycleFreq: 20,
deleteOnExpire: 'aggressive',
onExpire: onExpire
});
cache.put('item', 'value');
waits(100);
runs(function () {
expect(onExpire).toHaveBeenCalled();
expect(onExpire).toHaveBeenCalledWith('item', 'value');
});
});
it('should execute local "onExpire" callback if the item is expired in passive mode and global "onExpire" callback is NOT configured.', function () {
var cache = $angularCacheFactory('cache', {
maxAge: 10,
deleteOnExpire: 'passive',
recycleFreq: 20
});
cache.put('item', 'value');
waits(100);
runs(function () {
cache.get('item', { onExpire: function (key, value) {
expect(key).toEqual('item');
expect(value).toEqual('value');
}});
});
});
});
81 changes: 81 additions & 0 deletions test/angularCache.info-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
describe('AngularCache.info()', function () {
it('should return the correct values.', function () {
var onExpire = function () {
};
var cache = $angularCacheFactory('cache'),
cache2 = $angularCacheFactory('cache2', { maxAge: 1000 }),
cache3 = $angularCacheFactory('cache3', { cacheFlushInterval: 1000 }),
cache4 = $angularCacheFactory('cache4', { capacity: 1000 }),
cache5 = $angularCacheFactory('cache5', { storageMode: 'localStorage' }),
cache6 = $angularCacheFactory('cache6', { storageMode: 'sessionStorage' });
cache7 = $angularCacheFactory('cache7', { maxAge: 100, onExpire: onExpire });
var cacheInfo = cache.info();
expect(cacheInfo.id).toEqual('cache');
expect(cacheInfo.capacity).toEqual(Number.MAX_VALUE);
expect(cacheInfo.size).toEqual(0);
expect(cacheInfo.recycleFreq).toEqual(1000);
expect(cacheInfo.maxAge).toEqual(null);
expect(cacheInfo.cacheFlushInterval).toEqual(null);
expect(typeof cacheInfo.recycleFreqId).toEqual('number');
expect(cacheInfo.deleteOnExpire).toEqual('none');
expect(cacheInfo.storageMode).toEqual('none');
expect(cacheInfo.onExpire).toEqual(null);
cache.put('item', 'value');
cache.put('item2', 'value2', { maxAge: 200, deleteOnExpire: 'aggressive' });

// AngularCache#info(key)
expect(cache.info('non-existent item')).not.toBeDefined();
expect(typeof cache.info('item').created).toEqual('number');
expect(typeof cache.info('item').expires).toEqual('undefined');
expect(typeof cache.info('item').accessed).toEqual('number');
expect(cache.info('item').maxAge).toEqual(null);
expect(cache.info('item').deleteOnExpire).toEqual('none');
expect(typeof cache.info('item2').created).toEqual('number');
expect(typeof cache.info('item2').expires).toEqual('number');
expect(typeof cache.info('item2').accessed).toEqual('number');
expect(cache.info('item2').maxAge).toEqual(200);
expect(cache.info('item2').deleteOnExpire).toEqual('aggressive');

expect(cache.info().size).toEqual(2);

var cacheInfo2 = cache2.info();
expect(cacheInfo2.id).toEqual('cache2');
expect(cacheInfo2.capacity).toEqual(Number.MAX_VALUE);
expect(cacheInfo2.size).toEqual(0);
expect(cacheInfo2.recycleFreq).toEqual(1000);
expect(cacheInfo2.maxAge).toEqual(1000);
expect(cacheInfo2.cacheFlushInterval).toEqual(null);
expect(typeof cacheInfo2.recycleFreqId).toEqual('number');
expect(cacheInfo2.deleteOnExpire).toEqual('none');
expect(cacheInfo2.storageMode).toEqual('none');
expect(cacheInfo2.onExpire).toEqual(null);

expect(cache3.info().id).toEqual('cache3');
expect(cache3.info().capacity).toEqual(Number.MAX_VALUE);
expect(cache3.info().cacheFlushInterval).toEqual(1000);
expect(cache3.info().size).toEqual(0);

var cacheInfo4 = cache4.info();
expect(cacheInfo4.id).toEqual('cache4');
expect(cacheInfo4.capacity).toEqual(1000);
expect(cacheInfo4.size).toEqual(0);
expect(cacheInfo4.recycleFreq).toEqual(1000);
expect(cacheInfo4.maxAge).toEqual(null);
expect(cacheInfo4.cacheFlushInterval).toEqual(null);
expect(typeof cacheInfo4.recycleFreqId).toEqual('number');
expect(cacheInfo4.deleteOnExpire).toEqual('none');
expect(cacheInfo4.storageMode).toEqual('none');
expect(cacheInfo4.onExpire).toEqual(null);
if (localStorage) {
expect(cache5.info().storageMode).toEqual('localStorage');
} else {
expect(cache5.info().storageMode).toEqual(null);
}
if (sessionStorage) {
expect(cache6.info().storageMode).toEqual('sessionStorage');
} else {
expect(cache6.info().storageMode).toEqual(null);
}
expect(cache7.info().onExpire).toEqual(onExpire);
});
});
31 changes: 31 additions & 0 deletions test/angularCache.keySet-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
describe('AngularCache.keySet()', function () {
it('should return the set of keys of all items in the cache.', function () {
var itemKeys = ['item1', 'item2', 'item3'];

var cache = $angularCacheFactory('cache');

cache.put(itemKeys[0], itemKeys[0]);
cache.put(itemKeys[1], itemKeys[1]);
cache.put(itemKeys[2], itemKeys[2]);

var keySet = cache.keySet();

expect(keySet.hasOwnProperty(itemKeys[0])).toEqual(true);
expect(keySet.hasOwnProperty(itemKeys[1])).toEqual(true);
expect(keySet.hasOwnProperty(itemKeys[2])).toEqual(true);

expect(keySet[itemKeys[0]]).toEqual(itemKeys[0]);
expect(keySet[itemKeys[1]]).toEqual(itemKeys[1]);
expect(keySet[itemKeys[2]]).toEqual(itemKeys[2]);

cache.remove(itemKeys[0]);
cache.remove(itemKeys[1]);
cache.remove(itemKeys[2]);

keySet = cache.keySet();

expect(keySet.hasOwnProperty(itemKeys[0])).toEqual(false);
expect(keySet.hasOwnProperty(itemKeys[1])).toEqual(false);
expect(keySet.hasOwnProperty(itemKeys[2])).toEqual(false);
});
});
25 changes: 25 additions & 0 deletions test/angularCache.keys-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
describe('AngularCache.keys()', function () {
it('should return the array of keys of all items in the cache.', function () {
var itemKeys = ['item1', 'item2', 'item3'];

var cache = $angularCacheFactory('cache');

cache.put(itemKeys[0], itemKeys[0]);
cache.put(itemKeys[1], itemKeys[1]);
cache.put(itemKeys[2], itemKeys[2]);

var keys = cache.keys();

expect(keys[0]).toEqual(itemKeys[0]);
expect(keys[1]).toEqual(itemKeys[1]);
expect(keys[2]).toEqual(itemKeys[2]);

cache.remove(itemKeys[0]);
cache.remove(itemKeys[1]);
cache.remove(itemKeys[2]);

keys = cache.keys();

expect(keys.length).toEqual(0);
});
});
Loading

0 comments on commit daab6f1

Please sign in to comment.