Skip to content

Commit

Permalink
Added validation to $angularCacheFactoryProvider.setCacheDefaults. #55
Browse files Browse the repository at this point in the history
Swapped `localStorageImpl` and `sessionStorageImpl` options for just `storageImpl` option.
  • Loading branch information
jmdobry committed Sep 24, 2013
1 parent 75672b0 commit d1e26b4
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Swapped `aggressiveDelete` option for `deleteOnExpire` option. #30, #47
- Changed `$angularCacheFactory.info()` to return an object similar to `AngularCache.info()` #45
- Namespaced angular-cache module under `jmdobry` so it is now "jmdobry.angular-cache". #42
- Substituted `localStorageImpl` and `sessionStorageImpl` options for just `storageImpl` option.

###### Backwards compatible API changes
- Added ability to set global cache defaults in $angularCacheFactoryProvider. #55
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ See [AngularCache#info](http://jmdobry.github.io/angular-cache/docs/Cache.html#i
- Swapped `aggressiveDelete` option for `deleteOnExpire` option. #30, #47
- Changed `$angularCacheFactory.info()` to return an object similar to `AngularCache.info()` #45
- Namespaced angular-cache module under `jmdobry` so it is now "jmdobry.angular-cache". #42
- Substituted `localStorageImpl` and `sessionStorageImpl` options for just `storageImpl` option.

###### Backwards compatible API changes
- Added ability to set global cache defaults in $angularCacheFactoryProvider. #55
Expand Down
28 changes: 28 additions & 0 deletions TRANSITION.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,32 @@ $angularCacheFactory('myNewCache', {
maxAge: 90000, // Items added to this cache expire after 15 minutes
deleteOnExpire: 'none' // Items will expire but not be removed
});
```

- Substituted `localStorageImpl` and `sessionStorageImpl` options for just `storageImpl` option.

###### 1.x.x
```javascript
$angularCacheFactory('myNewCache', {
storageMode: 'localStorage',
localStorageImpl: myLocalStoragePolyfill // Use custom localStorage implementation
});
$angularCacheFactory('myNewCache2', {
storageMode: 'sessionStorage',
sessionStorageImpl: mySessionStoragePolyfill // Use custom sessionStorage implementation
});
```

###### 2.0.0
```javascript
$angularCacheFactory('myNewCache', {
storageMode: 'localStorage',
storageImpl: myLocalStoragePolyfill // Use custom localStorage implementation
});
$angularCacheFactory('myNewCache2', {
storageMode: 'sessionStorage',
storageImpl: mySessionStoragePolyfill // Use custom sessionStorage implementation
});
```
111 changes: 87 additions & 24 deletions src/angular-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,98 @@
onExpire: null,
cacheFlushInterval: null,
storageMode: 'none',
localStorageImpl: null,
sessionStorageImpl: null
storageImpl: null
};
};

/**
* @method setCacheDefaults
* @method _validateNumberOption
* @desc Validates the given number option.
* @param {Number} option The number option to check.
* @param {Function} cb Callback function
* @private
* @ignore
*/
function _validateNumberOption(option, cb) {
if (!angular.isNumber(option)) {
cb('must be a number!');
} else if (option < 0) {
cb('must be greater than zero!');
} else {
cb(null);
}
}

/**
* @method $AngularCacheFactoryProvider.setCacheDefaults
* @desc Set the default configuration for all caches created by $angularCacheFactory.
* @param {Object} options
* @privileged
*/
this.setCacheDefaults = function (options) {
options = options || {};

if (!angular.isObject(options)) {
throw new Error('setOptions(): options: must be an object!');
}

if ('capacity' in options) {
_validateNumberOption(options.capacity, function (err) {
if (err) {
throw new Error('setCacheDefaults(): capacity: ' + err);
}
});
}

if ('deleteOnExpire' in options) {
if (!angular.isString(options.deleteOnExpire)) {
throw new Error('setCacheDefaults(): deleteOnExpire: must be a string!');
} else if (options.deleteOnExpire !== 'none' && options.deleteOnExpire !== 'passive' && options.deleteOnExpire !== 'aggressive') {
throw new Error('setCacheDefaults(): deleteOnExpire: accepted values are "none", "passive" or "aggressive"!');
}
}

if ('maxAge' in options) {
_validateNumberOption(options.maxAge, function (err) {
if (err) {
throw new Error('setCacheDefaults(): maxAge: ' + err);
}
});
}

if ('cacheFlushInterval' in options) {
_validateNumberOption(options.cacheFlushInterval, function (err) {
if (err) {
throw new Error('setCacheDefaults(): cacheFlushInterval: ' + err);
}
});
}

if ('storageMode' in options) {
if (!angular.isString(options.storageMode)) {
throw new Error('setCacheDefaults(): storageMode: must be a string!');
} else if (options.storageMode !== 'none' && options.storageMode !== 'localStorage' && options.storageMode !== 'sessionStorage') {
throw new Error('setCacheDefaults(): storageMode: accepted values are "none", "localStorage" or "sessionStorage"');
}
if ('storageImpl' in options) {
if (!angular.isObject(options.storageImpl)) {
throw new Error('setCacheDefaults(): [local|session]storageImpl: must be an object!');
} else if (!('setItem' in options.storageImpl) || typeof options.storageImpl.setItem !== 'function') {
throw new Error('setCacheDefaults(): [local|session]storageImpl: must implement "setItem(key, value)"!');
} else if (!('getItem' in options.storageImpl) || typeof options.storageImpl.getItem !== 'function') {
throw new Error('setCacheDefaults(): [local|session]storageImpl: must implement "getItem(key)"!');
} else if (!('removeItem' in options.storageImpl) || typeof options.storageImpl.removeItem !== 'function') {
throw new Error('setCacheDefaults(): [local|session]storageImpl: must implement "removeItem(key)"!');
}
}
}

if ('onExpire' in options) {
if (typeof options.onExpire !== 'function') {
throw new Error('setCacheDefaults(): onExpire: Must be a function!');
}
}

cacheDefaults = angular.extend({}, DEFAULTS(), options);
};

Expand Down Expand Up @@ -97,7 +178,7 @@
* @class AngularCache
* @desc Instantiated via <code>$angularCacheFactory(cacheId[, options])</code>
* @param {String} cacheId The id of the new cache.
* @param {Object} [options] {{[capacity]: Number, [maxAge]: Number, [cacheFlushInterval]: Number, [aggressiveDelete]: Boolean, [onExpire]: Function, [storageMode]: String, [localStorageImpl]: Object}}
* @param {Object} [options] {{[capacity]: Number, [maxAge]: Number, [cacheFlushInterval]: Number, [deleteOnExpire]: String, [onExpire]: Function, [storageMode]: String, [storageImpl]: Object}}
*/
function AngularCache(cacheId, options) {
var size = 0,
Expand Down Expand Up @@ -135,24 +216,6 @@
}, delay);
}

/**
* @method _validateNumberOption
* @desc Validates the given number option.
* @param {Number} option The number option to check.
* @param {Function} cb Callback function
* @private
* @ignore
*/
function _validateNumberOption(option, cb) {
if (!angular.isNumber(option)) {
cb('must be a number!');
} else if (option < 0) {
cb('must be greater than zero!');
} else {
cb(null);
}
}

/**
* @method _setCapacity
* @desc Set the capacity for this cache.
Expand Down Expand Up @@ -364,7 +427,7 @@
}

if ('storageMode' in options) {
_setStorageMode(options.storageMode, options.localStorageImpl || options.sessionStorageImpl);
_setStorageMode(options.storageMode, options.storageImpl);
}

if ('onExpire' in options) {
Expand Down Expand Up @@ -735,7 +798,7 @@
/**
* @class AngularCacheFactory
* @param {String} cacheId The id of the new cache.
* @param {Object} [options] {{capacity: Number, maxAge: Number, deleteOnExpire: String, onExpire: Function, cacheFlushInterval: Number, storageMode: String, localStorageImpl: Object, sessionStorageImpl: Object}}
* @param {Object} [options] {{[capacity]: Number, [maxAge]: Number, [cacheFlushInterval]: Number, [deleteOnExpire]: String, [onExpire]: Function, [storageMode]: String, [storageImpl]: Object}}
* @returns {AngularCache}
*/
function angularCacheFactory(cacheId, options) {
Expand Down
4 changes: 2 additions & 2 deletions test/angularCacheFactorySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ describe('AngularCacheFactory', function () {
value: 'value2',
timestamp: new Date().getTime()
}));
var lsCache = $angularCacheFactory('lsCache', { localStorageImpl: myLocalStorage, storageMode: 'localStorage', maxAge: 10, deleteOnExpire: 'aggressive' });
var lsCache = $angularCacheFactory('lsCache', { storageImpl: myLocalStorage, storageMode: 'localStorage', maxAge: 10, deleteOnExpire: 'aggressive' });
expect(lsCache.get('item1')).toEqual('value1');
expect(lsCache.get('item2')).toEqual('value2');
waits(100);
Expand All @@ -227,7 +227,7 @@ describe('AngularCacheFactory', function () {
value: 'value2',
timestamp: new Date().getTime()
}));
var ssCache = $angularCacheFactory('ssCache', { sessionStorageImpl: mySessionStorage, storageMode: 'sessionStorage', maxAge: 10, deleteOnExpire: 'aggressive' });
var ssCache = $angularCacheFactory('ssCache', { storageImpl: mySessionStorage, storageMode: 'sessionStorage', maxAge: 10, deleteOnExpire: 'aggressive' });
expect(ssCache.get('item1')).toEqual('value1');
expect(ssCache.get('item2')).toEqual('value2');
waits(100);
Expand Down

0 comments on commit d1e26b4

Please sign in to comment.