From b9ce0b013502ca47fb7d6f11fa45627c3e0bdfc7 Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Tue, 24 Feb 2015 08:15:59 +0100
Subject: [PATCH 01/12] add field repository to package.json to fix npm warning

---
 package.json | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/package.json b/package.json
index 3332dd0..761b471 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,10 @@
     "name": "Martin Gontovnikas",
     "email": "martin@gon.to"
   },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/auth0/angular-storage.git"
+  },
   "dependencies": {},
   "devDependencies": {
     "chai": "^1.9.1",
-- 
GitLab


From 12fa48d25be417439a49fee3c36e6c5dbefd74ac Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Tue, 24 Feb 2015 08:18:46 +0100
Subject: [PATCH 02/12] changer version of angular-cookies in bower.json to fix
 resolution error when running bower install

---
 bower.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bower.json b/bower.json
index 1e35cd6..3ce1220 100755
--- a/bower.json
+++ b/bower.json
@@ -22,8 +22,8 @@
   "devDependencies": {
     "angular-mocks": ">= 1.2",
     "angular-scenario": ">= 1.2",
-    "angular-cookies": ">= 1.4"
-  },    
+    "angular-cookies": ">= 1.2"
+  },
   "resolutions": {
     "angular": "1.3.3"
   }
-- 
GitLab


From fa03932003c83f1568840262bbcb5eb199fcaa04 Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Tue, 24 Feb 2015 08:32:06 +0100
Subject: [PATCH 03/12] add lint task to gulp to check for jshint
 errors/warnings

---
 gulpfile.js  | 15 +++++++++++++--
 package.json |  2 ++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/gulpfile.js b/gulpfile.js
index 4f26b33..f24cf0e 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -11,7 +11,18 @@ var gulp = require('gulp'),
       'src/angularStorage/filters/**/*.js',
       'src/angularStorage/services/**/*.js',
       'src/angularStorage/angularStorage.suffix'
-    ];
+    ],
+    lintFiles = [
+      'src/angularStorage/**/*.js',
+    ]
+
+var jshint = require('gulp-jshint');
+
+gulp.task('lint', function() {
+  return gulp.src(lintFiles)
+    .pipe(jshint())
+    .pipe(jshint.reporter('jshint-stylish'));
+});
 
 gulp.task('build', function() {
   gulp.src(sourceFiles)
@@ -61,5 +72,5 @@ gulp.task('test-dist-minified', function (done) {
   }, done);
 });
 
-gulp.task('default', ['test', 'build']);
+gulp.task('default', ['lint', 'test', 'build']);
 gulp.task('dist', ['test-dist-concatenated', 'test-dist-minified']);
diff --git a/package.json b/package.json
index 761b471..3f04580 100644
--- a/package.json
+++ b/package.json
@@ -15,9 +15,11 @@
     "chai-jquery": "^1.2.3",
     "gulp": "^3.8.7",
     "gulp-concat": "^2.3.4",
+    "gulp-jshint": "^1.9.2",
     "gulp-ng-annotate": "^0.3.3",
     "gulp-rename": "^1.2.0",
     "gulp-uglify": "^0.3.1",
+    "jshint-stylish": "^1.0.0",
     "karma": "^0.12.22",
     "karma-chai": "^0.1.0",
     "karma-chai-jquery": "^1.0.0",
-- 
GitLab


From 24a9c57372e718bf11ed7aafb96e80524ca0f098 Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Tue, 24 Feb 2015 08:33:26 +0100
Subject: [PATCH 04/12] fix jshint warnings

---
 src/angularStorage/services/internalStore.js | 8 ++------
 src/angularStorage/services/store.js.js      | 4 +---
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/src/angularStorage/services/internalStore.js b/src/angularStorage/services/internalStore.js
index dff608c..af6cbcb 100644
--- a/src/angularStorage/services/internalStore.js
+++ b/src/angularStorage/services/internalStore.js
@@ -15,8 +15,6 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
       }
     };
 
-
-
     InternalStore.prototype.set = function(name, elem) {
       this.inMemoryCache[name] = elem;
       storage.set(this.getNamespacedKey(name), JSON.stringify(elem));
@@ -30,7 +28,7 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
       var saved = storage.get(this.getNamespacedKey(name));
       try {
 
-        if (typeof saved ==="undefined" || saved === "undefined") {
+        if (typeof saved === 'undefined' || saved === 'undefined') {
           obj = undefined;
         } else {
           obj = JSON.parse(saved);
@@ -38,7 +36,7 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
 
         this.inMemoryCache[name] = obj;
       } catch(e) {
-        $log.error("Error parsing saved value", e);
+        $log.error('Error parsing saved value', e);
         this.remove(name);
       }
       return obj;
@@ -50,7 +48,5 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
     };
 
     return InternalStore;
-
-
   });
 
diff --git a/src/angularStorage/services/store.js.js b/src/angularStorage/services/store.js.js
index 6f6cfd4..1b08474 100644
--- a/src/angularStorage/services/store.js.js
+++ b/src/angularStorage/services/store.js.js
@@ -4,10 +4,8 @@ angular.module('angular-storage.store', ['angular-storage.internalStore'])
     var store = new InternalStore();
     store.getNamespacedStore = function(namespace, key) {
       return new InternalStore(namespace, key);
-    }
+    };
 
     return store;
-
-
   });
 
-- 
GitLab


From cd902095408d04a93c0da0120b0076095d0df508 Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Tue, 24 Feb 2015 08:35:57 +0100
Subject: [PATCH 05/12] also check gulpfile.js for jshint errors

---
 gulpfile.js | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gulpfile.js b/gulpfile.js
index f24cf0e..6c1036a 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -3,6 +3,7 @@ var gulp = require('gulp'),
     concat = require('gulp-concat'),
     uglify = require('gulp-uglify'),
     rename = require('gulp-rename'),
+    jshint = require('gulp-jshint'),
     ngAnnotate = require('gulp-ng-annotate'),
     sourceFiles = [
       'src/angularStorage/angularStorage.prefix',
@@ -14,9 +15,8 @@ var gulp = require('gulp'),
     ],
     lintFiles = [
       'src/angularStorage/**/*.js',
-    ]
-
-var jshint = require('gulp-jshint');
+      'gulpfile.js'
+    ];
 
 gulp.task('lint', function() {
   return gulp.src(lintFiles)
@@ -31,7 +31,7 @@ gulp.task('build', function() {
     .pipe(gulp.dest('./dist/'))
     .pipe(uglify())
     .pipe(rename('angular-storage.min.js'))
-    .pipe(gulp.dest('./dist'))
+    .pipe(gulp.dest('./dist'));
 });
 
 /**
-- 
GitLab


From 6d31f8e5d9dfb19b62d9200f2574df89fa6c2ca9 Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Tue, 24 Feb 2015 08:45:28 +0100
Subject: [PATCH 06/12] add gulp task test-all to run the unit tests in all
 available browsers on the current system

---
 gulpfile.js           | 10 ++++++
 karma-src-all.conf.js | 83 +++++++++++++++++++++++++++++++++++++++++++
 package.json          |  3 +-
 3 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 karma-src-all.conf.js

diff --git a/gulpfile.js b/gulpfile.js
index 6c1036a..94e8cd0 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -44,6 +44,16 @@ gulp.task('test', function (done) {
   }, done);
 });
 
+/**
+ * Run test once in all available browsers and exit
+ */
+gulp.task('test-all', function (done) {
+  karma.start({
+    configFile: __dirname + '/karma-src-all.conf.js',
+    singleRun: true
+  }, done);
+});
+
 gulp.task('test-debug', function (done) {
   karma.start({
     configFile: __dirname + '/karma-src.conf.js',
diff --git a/karma-src-all.conf.js b/karma-src-all.conf.js
new file mode 100644
index 0000000..a4f2e11
--- /dev/null
+++ b/karma-src-all.conf.js
@@ -0,0 +1,83 @@
+// Karma configuration
+// Generated on Thu Aug 21 2014 10:24:39 GMT+0200 (CEST)
+
+module.exports = function(config) {
+  config.set({
+
+    // base path that will be used to resolve all patterns (eg. files, exclude)
+    basePath: '',
+
+
+    // frameworks to use
+    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+    frameworks: ['mocha', 'chai-jquery', 'jquery-1.8.3', 'sinon-chai', 'detectBrowsers'],
+
+    plugins: [
+      'karma-mocha',
+      'karma-chai',
+      'karma-sinon-chai',
+      'karma-chrome-launcher',
+      'karma-phantomjs-launcher',
+      'karma-firefox-launcher',
+      'karma-ie-launcher',
+      'karma-safari-launcher',
+      'karma-detect-browsers',
+      'karma-jquery',
+      'karma-chai-jquery',
+      'karma-mocha-reporter'
+    ],
+
+    // list of files / patterns to load in the browser
+    files: [
+      'bower/angular/angular.js',
+      'bower/angular-mocks/angular-mocks.js',
+      'bower/angular-cookies/angular-cookies.js',
+      'src/**/*.js',
+      'test/unit/**/*.js'
+    ],
+
+
+    // list of files to exclude
+    exclude: [
+    ],
+
+
+    // preprocess matching files before serving them to the browser
+    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
+    preprocessors: {
+    },
+
+
+    // test results reporter to use
+    // possible values: 'dots', 'progress'
+    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
+    reporters: ['mocha'],
+
+
+    // web server port
+    port: 9876,
+
+
+    // enable / disable colors in the output (reporters and logs)
+    colors: true,
+
+
+    // level of logging
+    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+    logLevel: config.LOG_INFO,
+
+
+    // enable / disable watching file and executing tests whenever any file changes
+    autoWatch: true,
+
+
+    // start these browsers
+    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
+    browsers: ['PhantomJS'],
+
+
+    // Continuous Integration mode
+    // if true, Karma captures browsers, runs the tests and exits
+    singleRun: false
+  });
+};
diff --git a/package.json b/package.json
index 3f04580..caa5668 100644
--- a/package.json
+++ b/package.json
@@ -24,10 +24,11 @@
     "karma-chai": "^0.1.0",
     "karma-chai-jquery": "^1.0.0",
     "karma-chrome-launcher": "^0.1.4",
+    "karma-detect-browsers": "^1.1.0",
     "karma-jasmine": "^0.1.5",
     "karma-jquery": "^0.1.0",
     "karma-mocha": "^0.1.8",
-    "karma-mocha-reporter": "^0.3.1",
+    "karma-mocha-reporter": "^1.0.0",
     "karma-phantomjs-launcher": "^0.1.4",
     "karma-sinon-chai": "^0.2.0",
     "mocha": "^1.21.4",
-- 
GitLab


From b8975ea7aa662ee23dd39cd3d91e58639db23014 Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Tue, 24 Feb 2015 10:58:45 +0100
Subject: [PATCH 07/12] add method setStorage() to the store service

- possible values are 'localStorage', 'sessionStorage' and 'cookieStorage'
- default store is 'localStorage'
- fallback store is 'cookieStorage' when localStorage or sessionStorage are not available in the browser
---
 dist/angular-storage.js                       |  98 +++++++++++--
 dist/angular-storage.min.js                   |   2 +-
 gulpfile.js                                   |   1 +
 src/angularStorage/services/cookieStorage.js  |  16 +++
 src/angularStorage/services/internalStore.js  |  19 ++-
 src/angularStorage/services/localStorage.js   |  22 +++
 src/angularStorage/services/sessionStorage.js |  22 +++
 src/angularStorage/services/store.js.js       |   8 ++
 .../unit/angularStorage/services/storeSpec.js | 135 +++++++++++++++---
 9 files changed, 287 insertions(+), 36 deletions(-)
 create mode 100644 src/angularStorage/services/cookieStorage.js
 create mode 100644 src/angularStorage/services/localStorage.js
 create mode 100644 src/angularStorage/services/sessionStorage.js

diff --git a/dist/angular-storage.js b/dist/angular-storage.js
index 716d495..3e2b4c3 100755
--- a/dist/angular-storage.js
+++ b/dist/angular-storage.js
@@ -10,13 +10,31 @@ angular.module('angular-storage',
       'angular-storage.store'
     ]);
 
-angular.module('angular-storage.internalStore', ['angular-storage.storage'])
-  .factory('InternalStore', ["storage", "$log", function(storage, $log) {
+angular.module('angular-storage.cookieStorage', [])
+  .service('cookieStorage', ["$injector", function ($injector) {
+    var $cookieStore = $injector.get('$cookieStore');
+
+    this.set = function (what, value) {
+      return $cookieStore.put(what, value);
+    };
+
+    this.get = function (what) {
+      return $cookieStore.get(what);
+    };
+
+    this.remove = function (what) {
+      return $cookieStore.remove(what);
+    };
+  }]);
+
+angular.module('angular-storage.internalStore', ['angular-storage.localStorage', 'angular-storage.sessionStorage'])
+  .factory('InternalStore', ["$log", "$injector", function($log, $injector) {
 
     function InternalStore(namespace, delimiter) {
       this.namespace = namespace || null;
       this.delimiter = delimiter || '.';
       this.inMemoryCache = {};
+      this.storage = $injector.get('localStorage');
     }
 
     InternalStore.prototype.getNamespacedKey = function(key) {
@@ -27,11 +45,9 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
       }
     };
 
-
-
     InternalStore.prototype.set = function(name, elem) {
       this.inMemoryCache[name] = elem;
-      storage.set(this.getNamespacedKey(name), JSON.stringify(elem));
+      this.storage.set(this.getNamespacedKey(name), JSON.stringify(elem));
     };
 
     InternalStore.prototype.get = function(name) {
@@ -39,10 +55,10 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
       if (name in this.inMemoryCache) {
         return this.inMemoryCache[name];
       }
-      var saved = storage.get(this.getNamespacedKey(name));
+      var saved = this.storage.get(this.getNamespacedKey(name));
       try {
 
-        if (typeof saved ==="undefined" || saved === "undefined") {
+        if (typeof saved === 'undefined' || saved === 'undefined') {
           obj = undefined;
         } else {
           obj = JSON.parse(saved);
@@ -50,7 +66,7 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
 
         this.inMemoryCache[name] = obj;
       } catch(e) {
-        $log.error("Error parsing saved value", e);
+        $log.error('Error parsing saved value', e);
         this.remove(name);
       }
       return obj;
@@ -58,14 +74,66 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
 
     InternalStore.prototype.remove = function(name) {
       this.inMemoryCache[name] = null;
-      storage.remove(this.getNamespacedKey(name));
+      this.storage.remove(this.getNamespacedKey(name));
+    };
+
+    InternalStore.prototype.setStorage = function(storage) {
+      if (!storage || !angular.isString(storage)) {
+        return;
+      }
+
+      this.storage = $injector.get(storage);
     };
 
     return InternalStore;
+  }]);
+
 
+angular.module('angular-storage.localStorage', ['angular-storage.cookieStorage'])
+  .service('localStorage', ["$window", "$injector", function ($window, $injector) {
+    if ($window.localStorage) {
+      this.set = function (what, value) {
+        return $window.localStorage.setItem(what, value);
+      };
 
+      this.get = function (what) {
+        return $window.localStorage.getItem(what);
+      };
+
+      this.remove = function (what) {
+        return $window.localStorage.removeItem(what);
+      };
+    } else {
+      var cookieStorage = $injector.get('cookieStorage');
+
+      this.set = cookieStorage.set;
+      this.get = cookieStorage.get;
+      this.remove = cookieStorage.remove;
+    }
   }]);
 
+angular.module('angular-storage.sessionStorage', ['angular-storage.cookieStorage'])
+  .service('sessionStorage', ["$window", "$injector", function ($window, $injector) {
+    if ($window.sessionStorage) {
+      this.set = function (what, value) {
+        return $window.sessionStorage.setItem(what, value);
+      };
+
+      this.get = function (what) {
+        return $window.sessionStorage.getItem(what);
+      };
+
+      this.remove = function (what) {
+        return $window.sessionStorage.removeItem(what);
+      };
+    } else {
+      var cookieStorage = $injector.get('cookieStorage');
+
+      this.set = cookieStorage.set;
+      this.get = cookieStorage.get;
+      this.remove = cookieStorage.remove;
+    }
+  }]);
 
 angular.module('angular-storage.storage', [])
   .service('storage', ["$window", "$injector", function($window, $injector) {
@@ -98,13 +166,19 @@ angular.module('angular-storage.store', ['angular-storage.internalStore'])
   .factory('store', ["InternalStore", function(InternalStore) {
 
     var store = new InternalStore();
+
+    /**
+     * Returns a namespaced store
+     *
+     * @param {String} namespace The namespace
+     * @param {String} key The key
+     * @returns {InternalStore}
+     */
     store.getNamespacedStore = function(namespace, key) {
       return new InternalStore(namespace, key);
-    }
+    };
 
     return store;
-
-
   }]);
 
 
diff --git a/dist/angular-storage.min.js b/dist/angular-storage.min.js
index b1ff6eb..bc8e146 100755
--- a/dist/angular-storage.min.js
+++ b/dist/angular-storage.min.js
@@ -1 +1 @@
-!function(){angular.module("angular-storage",["angular-storage.store"]),angular.module("angular-storage.internalStore",["angular-storage.storage"]).factory("InternalStore",["storage","$log",function(e,t){function r(e,t){this.namespace=e||null,this.delimiter=t||".",this.inMemoryCache={}}return r.prototype.getNamespacedKey=function(e){return this.namespace?[this.namespace,e].join(this.delimiter):e},r.prototype.set=function(t,r){this.inMemoryCache[t]=r,e.set(this.getNamespacedKey(t),JSON.stringify(r))},r.prototype.get=function(r){var n=null;if(r in this.inMemoryCache)return this.inMemoryCache[r];var o=e.get(this.getNamespacedKey(r));try{n="undefined"==typeof o||"undefined"===o?void 0:JSON.parse(o),this.inMemoryCache[r]=n}catch(a){t.error("Error parsing saved value",a),this.remove(r)}return n},r.prototype.remove=function(t){this.inMemoryCache[t]=null,e.remove(this.getNamespacedKey(t))},r}]),angular.module("angular-storage.storage",[]).service("storage",["$window","$injector",function(e,t){if(e.localStorage)this.set=function(t,r){return e.localStorage.setItem(t,r)},this.get=function(t){return e.localStorage.getItem(t)},this.remove=function(t){return e.localStorage.removeItem(t)};else{var r=t.get("$cookieStore");this.set=function(e,t){return r.put(e,t)},this.get=function(e){return r.get(e)},this.remove=function(e){return r.remove(e)}}}]),angular.module("angular-storage.store",["angular-storage.internalStore"]).factory("store",["InternalStore",function(e){var t=new e;return t.getNamespacedStore=function(t,r){return new e(t,r)},t}])}();
\ No newline at end of file
+!function(){angular.module("angular-storage",["angular-storage.store"]),angular.module("angular-storage.cookieStorage",[]).service("cookieStorage",["$injector",function(e){var t=e.get("$cookieStore");this.set=function(e,r){return t.put(e,r)},this.get=function(e){return t.get(e)},this.remove=function(e){return t.remove(e)}}]),angular.module("angular-storage.internalStore",["angular-storage.localStorage","angular-storage.sessionStorage"]).factory("InternalStore",["$log","$injector",function(e,t){function r(e,r){this.namespace=e||null,this.delimiter=r||".",this.inMemoryCache={},this.storage=t.get("localStorage")}return r.prototype.getNamespacedKey=function(e){return this.namespace?[this.namespace,e].join(this.delimiter):e},r.prototype.set=function(e,t){this.inMemoryCache[e]=t,this.storage.set(this.getNamespacedKey(e),JSON.stringify(t))},r.prototype.get=function(t){var r=null;if(t in this.inMemoryCache)return this.inMemoryCache[t];var o=this.storage.get(this.getNamespacedKey(t));try{r="undefined"==typeof o||"undefined"===o?void 0:JSON.parse(o),this.inMemoryCache[t]=r}catch(n){e.error("Error parsing saved value",n),this.remove(t)}return r},r.prototype.remove=function(e){this.inMemoryCache[e]=null,this.storage.remove(this.getNamespacedKey(e))},r.prototype.setStorage=function(e){e&&angular.isString(e)&&(this.storage=t.get(e))},r}]),angular.module("angular-storage.localStorage",["angular-storage.cookieStorage"]).service("localStorage",["$window","$injector",function(e,t){if(e.localStorage)this.set=function(t,r){return e.localStorage.setItem(t,r)},this.get=function(t){return e.localStorage.getItem(t)},this.remove=function(t){return e.localStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.sessionStorage",["angular-storage.cookieStorage"]).service("sessionStorage",["$window","$injector",function(e,t){if(e.sessionStorage)this.set=function(t,r){return e.sessionStorage.setItem(t,r)},this.get=function(t){return e.sessionStorage.getItem(t)},this.remove=function(t){return e.sessionStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.storage",[]).service("storage",["$window","$injector",function(e,t){if(e.localStorage)this.set=function(t,r){return e.localStorage.setItem(t,r)},this.get=function(t){return e.localStorage.getItem(t)},this.remove=function(t){return e.localStorage.removeItem(t)};else{var r=t.get("$cookieStore");this.set=function(e,t){return r.put(e,t)},this.get=function(e){return r.get(e)},this.remove=function(e){return r.remove(e)}}}]),angular.module("angular-storage.store",["angular-storage.internalStore"]).factory("store",["InternalStore",function(e){var t=new e;return t.getNamespacedStore=function(t,r){return new e(t,r)},t}])}();
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 94e8cd0..3b8e89b 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -15,6 +15,7 @@ var gulp = require('gulp'),
     ],
     lintFiles = [
       'src/angularStorage/**/*.js',
+      'test/**/*.js',
       'gulpfile.js'
     ];
 
diff --git a/src/angularStorage/services/cookieStorage.js b/src/angularStorage/services/cookieStorage.js
new file mode 100644
index 0000000..19b6109
--- /dev/null
+++ b/src/angularStorage/services/cookieStorage.js
@@ -0,0 +1,16 @@
+angular.module('angular-storage.cookieStorage', [])
+  .service('cookieStorage', function ($injector) {
+    var $cookieStore = $injector.get('$cookieStore');
+
+    this.set = function (what, value) {
+      return $cookieStore.put(what, value);
+    };
+
+    this.get = function (what) {
+      return $cookieStore.get(what);
+    };
+
+    this.remove = function (what) {
+      return $cookieStore.remove(what);
+    };
+  });
diff --git a/src/angularStorage/services/internalStore.js b/src/angularStorage/services/internalStore.js
index af6cbcb..49bb816 100644
--- a/src/angularStorage/services/internalStore.js
+++ b/src/angularStorage/services/internalStore.js
@@ -1,10 +1,11 @@
-angular.module('angular-storage.internalStore', ['angular-storage.storage'])
-  .factory('InternalStore', function(storage, $log) {
+angular.module('angular-storage.internalStore', ['angular-storage.localStorage', 'angular-storage.sessionStorage'])
+  .factory('InternalStore', function($log, $injector) {
 
     function InternalStore(namespace, delimiter) {
       this.namespace = namespace || null;
       this.delimiter = delimiter || '.';
       this.inMemoryCache = {};
+      this.storage = $injector.get('localStorage');
     }
 
     InternalStore.prototype.getNamespacedKey = function(key) {
@@ -17,7 +18,7 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
 
     InternalStore.prototype.set = function(name, elem) {
       this.inMemoryCache[name] = elem;
-      storage.set(this.getNamespacedKey(name), JSON.stringify(elem));
+      this.storage.set(this.getNamespacedKey(name), JSON.stringify(elem));
     };
 
     InternalStore.prototype.get = function(name) {
@@ -25,7 +26,7 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
       if (name in this.inMemoryCache) {
         return this.inMemoryCache[name];
       }
-      var saved = storage.get(this.getNamespacedKey(name));
+      var saved = this.storage.get(this.getNamespacedKey(name));
       try {
 
         if (typeof saved === 'undefined' || saved === 'undefined') {
@@ -44,7 +45,15 @@ angular.module('angular-storage.internalStore', ['angular-storage.storage'])
 
     InternalStore.prototype.remove = function(name) {
       this.inMemoryCache[name] = null;
-      storage.remove(this.getNamespacedKey(name));
+      this.storage.remove(this.getNamespacedKey(name));
+    };
+
+    InternalStore.prototype.setStorage = function(storage) {
+      if (!storage || !angular.isString(storage)) {
+        return;
+      }
+
+      this.storage = $injector.get(storage);
     };
 
     return InternalStore;
diff --git a/src/angularStorage/services/localStorage.js b/src/angularStorage/services/localStorage.js
new file mode 100644
index 0000000..e409713
--- /dev/null
+++ b/src/angularStorage/services/localStorage.js
@@ -0,0 +1,22 @@
+angular.module('angular-storage.localStorage', ['angular-storage.cookieStorage'])
+  .service('localStorage', function ($window, $injector) {
+    if ($window.localStorage) {
+      this.set = function (what, value) {
+        return $window.localStorage.setItem(what, value);
+      };
+
+      this.get = function (what) {
+        return $window.localStorage.getItem(what);
+      };
+
+      this.remove = function (what) {
+        return $window.localStorage.removeItem(what);
+      };
+    } else {
+      var cookieStorage = $injector.get('cookieStorage');
+
+      this.set = cookieStorage.set;
+      this.get = cookieStorage.get;
+      this.remove = cookieStorage.remove;
+    }
+  });
diff --git a/src/angularStorage/services/sessionStorage.js b/src/angularStorage/services/sessionStorage.js
new file mode 100644
index 0000000..8a676ec
--- /dev/null
+++ b/src/angularStorage/services/sessionStorage.js
@@ -0,0 +1,22 @@
+angular.module('angular-storage.sessionStorage', ['angular-storage.cookieStorage'])
+  .service('sessionStorage', function ($window, $injector) {
+    if ($window.sessionStorage) {
+      this.set = function (what, value) {
+        return $window.sessionStorage.setItem(what, value);
+      };
+
+      this.get = function (what) {
+        return $window.sessionStorage.getItem(what);
+      };
+
+      this.remove = function (what) {
+        return $window.sessionStorage.removeItem(what);
+      };
+    } else {
+      var cookieStorage = $injector.get('cookieStorage');
+
+      this.set = cookieStorage.set;
+      this.get = cookieStorage.get;
+      this.remove = cookieStorage.remove;
+    }
+  });
diff --git a/src/angularStorage/services/store.js.js b/src/angularStorage/services/store.js.js
index 1b08474..a40026d 100644
--- a/src/angularStorage/services/store.js.js
+++ b/src/angularStorage/services/store.js.js
@@ -2,6 +2,14 @@ angular.module('angular-storage.store', ['angular-storage.internalStore'])
   .factory('store', function(InternalStore) {
 
     var store = new InternalStore();
+
+    /**
+     * Returns a namespaced store
+     *
+     * @param {String} namespace The namespace
+     * @param {String} key The key
+     * @returns {InternalStore}
+     */
     store.getNamespacedStore = function(namespace, key) {
       return new InternalStore(namespace, key);
     };
diff --git a/test/unit/angularStorage/services/storeSpec.js b/test/unit/angularStorage/services/storeSpec.js
index 35dfcf9..47c1025 100644
--- a/test/unit/angularStorage/services/storeSpec.js
+++ b/test/unit/angularStorage/services/storeSpec.js
@@ -68,30 +68,93 @@ describe('angularStorage store', function() {
     expect(store.get('gonto')).not.to.equal(value);
   }));
 
+  describe('.setStorage()', function () {
+
+    var $cookieStore;
+
+    beforeEach(module('ngCookies'));
+
+    beforeEach(inject(function( _$cookieStore_) {
+      $cookieStore = _$cookieStore_;
+    }));
+
+    it('should should save items correctly when the storage is changed to sessionStorage', inject(function(store, $window) {
+      var value = 11;
+      store.setStorage('sessionStorage');
+      store.set('gonto', value);
+
+      expect(store.get('gonto')).to.equal(value);
+      expect($window.sessionStorage.getItem('gonto')).to.exist;
+      expect($window.sessionStorage.getItem('gonto')).to.equal(value.toString());
+    }));
+
+    it('should should save items correctly when the storage is changed to localStorage', inject(function(store, $window) {
+      var value = 22;
+      store.setStorage('localStorage');
+      store.set('gonto', value);
+
+      expect(store.get('gonto')).to.equal(value);
+      expect($window.localStorage.getItem('gonto')).to.exist;
+      expect($window.localStorage.getItem('gonto')).to.equal(value.toString());
+    }));
+
+    it('should should save items correctly when the storage is changed to cookieStorage', inject(function(store) {
+      var value = 22;
+      store.setStorage('cookieStorage');
+      store.set('gonto', value);
+
+      expect(store.get('gonto')).to.equal(value);
+      expect($cookieStore.get('gonto')).to.equal(JSON.stringify(value));
+    }));
+
+    it('should not change store when param storage is not a string', inject(function(store, $window) {
+      var value = 2222;
+      store.setStorage({a:3});
+      store.set('xxx', value);
+
+      expect(store.get('xxx')).to.equal(value);
+      expect($window.localStorage.getItem('xxx')).to.exist;
+      expect($window.localStorage.getItem('xxx')).to.equal(value.toString());
+    }));
+
+    it('should not change store when param storage is an empty string', inject(function(store, $window) {
+      var value = 2222;
+      store.setStorage('');
+      store.set('xxx', value);
+
+      expect(store.get('xxx')).to.equal(value);
+      expect($window.localStorage.getItem('xxx')).to.exist;
+      expect($window.localStorage.getItem('xxx')).to.equal(value.toString());
+    }));
+
+    it('should throw an error when the store is not found', inject(function(store) {
+      expect(function() { store.setStorage('abc'); } ).to.throw(Error, /Unknown provider: abcProvider <- abc/);
+    }));
+  });
 });
+
 describe('angularStorage store: cookie fallback', function() {
 
     /* these tests ensure that the cookie fallback works correctly.
     *
     * note - to confirm that cookiestore was used we attempt to retrieve the value from the cookie
              since this bypasses our service, the result will not have been json parsed
-             therefore we use JSON.stringify on the expected value, so comparing like for like 
+             therefore we use JSON.stringify on the expected value, so comparing like for like
     *
     */
-    
+
     var windowMock, $cookieStore;
-    
+
     /* provide a mock for $window where localStorage is not defined */
-    beforeEach(module("ngCookies", "angular-storage.store", function ($provide) {
+    beforeEach(module('ngCookies', 'angular-storage.store', function ($provide) {
         windowMock = { localStorage: undefined };
-        $provide.value("$window", windowMock);
-
+        $provide.value('$window', windowMock);
     }));
-      
-    beforeEach(inject(function( _$cookieStore_) {  
+
+    beforeEach(inject(function( _$cookieStore_) {
         $cookieStore = _$cookieStore_;
     }));
-    
+
   it('should save items correctly in localStorage', inject(function(store) {
     var value = 1;
     store.set('gonto', value);
@@ -110,7 +173,7 @@ describe('angularStorage store: cookie fallback', function() {
     store.set('gonto', undefined);
     store.inMemoryCache = {};
     expect(store.get('gonto')).to.equal(undefined);
-    expect($cookieStore.get('gonto')).to.equal(JSON.stringify(undefined));      
+    expect($cookieStore.get('gonto')).to.equal(JSON.stringify(undefined));
   }));
 
   it('should delete items correctly from localStorage', inject(function(store) {
@@ -119,7 +182,7 @@ describe('angularStorage store: cookie fallback', function() {
     expect(store.get('gonto')).to.equal(value);
     store.remove('gonto');
     expect(store.get('gonto')).to.not.exist;
-    expect($cookieStore.get('gonto')).to.not.exist;         
+    expect($cookieStore.get('gonto')).to.not.exist;
   }));
 
   it('should save objects correctly', inject(function(store) {
@@ -137,7 +200,7 @@ describe('angularStorage store: cookie fallback', function() {
     store.set('gonto', value);
     expect(store.get('gonto')).to.eql(value);
     expect($cookieStore.get('gonto')).to.equal(JSON.stringify(value));
-  }));    
+  }));
 
   it('should save objects correctly without cache', inject(function(store) {
     var value = {
@@ -149,7 +212,7 @@ describe('angularStorage store: cookie fallback', function() {
     expect(store.get('gonto')).not.to.equal(value);
   }));
 
-  it('should save  objects correctly without cache', inject(function(store) {
+  it('should save objects correctly without cache', inject(function(store) {
     var value = {
       gonto: 'hola'
     };
@@ -158,16 +221,14 @@ describe('angularStorage store: cookie fallback', function() {
     expect(store.get('gonto')).to.eql(value);
     expect(store.get('gonto')).not.to.equal(value);
     expect($cookieStore.get('gonto')).to.eql(JSON.stringify(value));
-      
+
   }));
-    
-    
+
 });
 
 describe('angularStorage new namespaced store', function() {
-
   beforeEach(function() {
-    module('angular-storage.store');
+    module('ngCookies', 'angular-storage.store');
   });
 
   var newStore = null;
@@ -228,5 +289,43 @@ describe('angularStorage new namespaced store', function() {
     expect(newStore.get('gonto')).not.to.equal(value);
   });
 
+  describe('.setStorage()', function () {
+    var $cookieStore;
+
+    beforeEach(inject(function( _$cookieStore_) {
+      $cookieStore = _$cookieStore_;
+    }));
+
+    it('should should save items correctly when the storage is changed to sessionStorage', inject(function( $window) {
+      var value = 111;
+      newStore.setStorage('sessionStorage');
+      newStore.set('wayne', value);
+
+      expect(newStore.get('wayne')).to.equal(value);
+      expect($window.sessionStorage.getItem('auth0.wayne')).to.exist;
+      expect($window.sessionStorage.getItem('auth0.wayne')).to.equal(value.toString());
+      expect($window.sessionStorage.getItem('wayne')).to.not.exist;
+    }));
+
+    it('should should save items correctly when the storage is changed to localStorage', inject(function($window) {
+      var value = 222;
+      newStore.setStorage('localStorage');
+      newStore.set('wayne', value);
+
+      expect(newStore.get('wayne')).to.equal(value);
+      expect($window.localStorage.getItem('auth0.wayne')).to.exist;
+      expect($window.localStorage.getItem('auth0.wayne')).to.equal(value.toString());
+      expect($window.localStorage.getItem('wayne')).to.not.exist;
+    }));
+
+    it('should should save items correctly when the storage is changed to cookieStorage', inject(function() {
+      var value = 333;
+      newStore.setStorage('cookieStorage');
+      newStore.set('wayne', value);
+
+      expect(newStore.get('wayne')).to.equal(value);
+      expect($cookieStore.get('auth0.wayne')).to.equal(JSON.stringify(value));
+    }));
+  });
 });
 
-- 
GitLab


From 56112b2f0bcac769cdb4c91d541ebe7b3a85e274 Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Tue, 24 Feb 2015 11:06:35 +0100
Subject: [PATCH 08/12] fix dist tests

---
 dist/angular-storage.js         | 27 ---------------------------
 dist/angular-storage.min.js     |  2 +-
 karma-dist-concatenated.conf.js |  1 +
 karma-dist-minified.conf.js     |  1 +
 4 files changed, 3 insertions(+), 28 deletions(-)

diff --git a/dist/angular-storage.js b/dist/angular-storage.js
index 3e2b4c3..0205606 100755
--- a/dist/angular-storage.js
+++ b/dist/angular-storage.js
@@ -135,33 +135,6 @@ angular.module('angular-storage.sessionStorage', ['angular-storage.cookieStorage
     }
   }]);
 
-angular.module('angular-storage.storage', [])
-  .service('storage', ["$window", "$injector", function($window, $injector) {
-    if ($window.localStorage) {
-      this.set = function(what, value) {
-        return $window.localStorage.setItem(what, value);
-      };
-      this.get = function(what) {
-        return $window.localStorage.getItem(what);
-      };
-      this.remove = function(what) {
-        return $window.localStorage.removeItem(what);
-      };
-    } else {
-      var $cookieStore = $injector.get('$cookieStore');
-      this.set = function(what, value) {
-        return $cookieStore.put(what, value);
-      };
-      this.get = function(what) {
-        return $cookieStore.get(what);
-      };
-      this.remove = function(what) {
-        return $cookieStore.remove(what);
-      };
-    }
-  }]);
-
-
 angular.module('angular-storage.store', ['angular-storage.internalStore'])
   .factory('store', ["InternalStore", function(InternalStore) {
 
diff --git a/dist/angular-storage.min.js b/dist/angular-storage.min.js
index bc8e146..bbb584e 100755
--- a/dist/angular-storage.min.js
+++ b/dist/angular-storage.min.js
@@ -1 +1 @@
-!function(){angular.module("angular-storage",["angular-storage.store"]),angular.module("angular-storage.cookieStorage",[]).service("cookieStorage",["$injector",function(e){var t=e.get("$cookieStore");this.set=function(e,r){return t.put(e,r)},this.get=function(e){return t.get(e)},this.remove=function(e){return t.remove(e)}}]),angular.module("angular-storage.internalStore",["angular-storage.localStorage","angular-storage.sessionStorage"]).factory("InternalStore",["$log","$injector",function(e,t){function r(e,r){this.namespace=e||null,this.delimiter=r||".",this.inMemoryCache={},this.storage=t.get("localStorage")}return r.prototype.getNamespacedKey=function(e){return this.namespace?[this.namespace,e].join(this.delimiter):e},r.prototype.set=function(e,t){this.inMemoryCache[e]=t,this.storage.set(this.getNamespacedKey(e),JSON.stringify(t))},r.prototype.get=function(t){var r=null;if(t in this.inMemoryCache)return this.inMemoryCache[t];var o=this.storage.get(this.getNamespacedKey(t));try{r="undefined"==typeof o||"undefined"===o?void 0:JSON.parse(o),this.inMemoryCache[t]=r}catch(n){e.error("Error parsing saved value",n),this.remove(t)}return r},r.prototype.remove=function(e){this.inMemoryCache[e]=null,this.storage.remove(this.getNamespacedKey(e))},r.prototype.setStorage=function(e){e&&angular.isString(e)&&(this.storage=t.get(e))},r}]),angular.module("angular-storage.localStorage",["angular-storage.cookieStorage"]).service("localStorage",["$window","$injector",function(e,t){if(e.localStorage)this.set=function(t,r){return e.localStorage.setItem(t,r)},this.get=function(t){return e.localStorage.getItem(t)},this.remove=function(t){return e.localStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.sessionStorage",["angular-storage.cookieStorage"]).service("sessionStorage",["$window","$injector",function(e,t){if(e.sessionStorage)this.set=function(t,r){return e.sessionStorage.setItem(t,r)},this.get=function(t){return e.sessionStorage.getItem(t)},this.remove=function(t){return e.sessionStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.storage",[]).service("storage",["$window","$injector",function(e,t){if(e.localStorage)this.set=function(t,r){return e.localStorage.setItem(t,r)},this.get=function(t){return e.localStorage.getItem(t)},this.remove=function(t){return e.localStorage.removeItem(t)};else{var r=t.get("$cookieStore");this.set=function(e,t){return r.put(e,t)},this.get=function(e){return r.get(e)},this.remove=function(e){return r.remove(e)}}}]),angular.module("angular-storage.store",["angular-storage.internalStore"]).factory("store",["InternalStore",function(e){var t=new e;return t.getNamespacedStore=function(t,r){return new e(t,r)},t}])}();
\ No newline at end of file
+!function(){angular.module("angular-storage",["angular-storage.store"]),angular.module("angular-storage.cookieStorage",[]).service("cookieStorage",["$injector",function(e){var t=e.get("$cookieStore");this.set=function(e,r){return t.put(e,r)},this.get=function(e){return t.get(e)},this.remove=function(e){return t.remove(e)}}]),angular.module("angular-storage.internalStore",["angular-storage.localStorage","angular-storage.sessionStorage"]).factory("InternalStore",["$log","$injector",function(e,t){function r(e,r){this.namespace=e||null,this.delimiter=r||".",this.inMemoryCache={},this.storage=t.get("localStorage")}return r.prototype.getNamespacedKey=function(e){return this.namespace?[this.namespace,e].join(this.delimiter):e},r.prototype.set=function(e,t){this.inMemoryCache[e]=t,this.storage.set(this.getNamespacedKey(e),JSON.stringify(t))},r.prototype.get=function(t){var r=null;if(t in this.inMemoryCache)return this.inMemoryCache[t];var o=this.storage.get(this.getNamespacedKey(t));try{r="undefined"==typeof o||"undefined"===o?void 0:JSON.parse(o),this.inMemoryCache[t]=r}catch(a){e.error("Error parsing saved value",a),this.remove(t)}return r},r.prototype.remove=function(e){this.inMemoryCache[e]=null,this.storage.remove(this.getNamespacedKey(e))},r.prototype.setStorage=function(e){e&&angular.isString(e)&&(this.storage=t.get(e))},r}]),angular.module("angular-storage.localStorage",["angular-storage.cookieStorage"]).service("localStorage",["$window","$injector",function(e,t){if(e.localStorage)this.set=function(t,r){return e.localStorage.setItem(t,r)},this.get=function(t){return e.localStorage.getItem(t)},this.remove=function(t){return e.localStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.sessionStorage",["angular-storage.cookieStorage"]).service("sessionStorage",["$window","$injector",function(e,t){if(e.sessionStorage)this.set=function(t,r){return e.sessionStorage.setItem(t,r)},this.get=function(t){return e.sessionStorage.getItem(t)},this.remove=function(t){return e.sessionStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.store",["angular-storage.internalStore"]).factory("store",["InternalStore",function(e){var t=new e;return t.getNamespacedStore=function(t,r){return new e(t,r)},t}])}();
\ No newline at end of file
diff --git a/karma-dist-concatenated.conf.js b/karma-dist-concatenated.conf.js
index 398d9bf..f3d379a 100644
--- a/karma-dist-concatenated.conf.js
+++ b/karma-dist-concatenated.conf.js
@@ -27,6 +27,7 @@ module.exports = function(config) {
     files: [
       'bower/angular/angular.js',
       'bower/angular-mocks/angular-mocks.js',
+      'bower/angular-cookies/angular-cookies.js',
       'dist/angular-storage.js',
       'test/unit/**/*.js'
     ],
diff --git a/karma-dist-minified.conf.js b/karma-dist-minified.conf.js
index 94a16ec..5b2d303 100644
--- a/karma-dist-minified.conf.js
+++ b/karma-dist-minified.conf.js
@@ -27,6 +27,7 @@ module.exports = function(config) {
     files: [
       'bower/angular/angular.js',
       'bower/angular-mocks/angular-mocks.js',
+      'bower/angular-cookies/angular-cookies.js',
       'dist/angular-storage.min.js',
       'test/unit/**/*.js'
     ],
-- 
GitLab


From 6e386029668efa48c1c3fb4ad0c4e94892580de2 Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Tue, 24 Feb 2015 11:06:54 +0100
Subject: [PATCH 09/12] remove storage.js file, not needed any more

---
 src/angularStorage/services/storage.js | 26 --------------------------
 1 file changed, 26 deletions(-)
 delete mode 100644 src/angularStorage/services/storage.js

diff --git a/src/angularStorage/services/storage.js b/src/angularStorage/services/storage.js
deleted file mode 100644
index 272e001..0000000
--- a/src/angularStorage/services/storage.js
+++ /dev/null
@@ -1,26 +0,0 @@
-angular.module('angular-storage.storage', [])
-  .service('storage', function($window, $injector) {
-    if ($window.localStorage) {
-      this.set = function(what, value) {
-        return $window.localStorage.setItem(what, value);
-      };
-      this.get = function(what) {
-        return $window.localStorage.getItem(what);
-      };
-      this.remove = function(what) {
-        return $window.localStorage.removeItem(what);
-      };
-    } else {
-      var $cookieStore = $injector.get('$cookieStore');
-      this.set = function(what, value) {
-        return $cookieStore.put(what, value);
-      };
-      this.get = function(what) {
-        return $cookieStore.get(what);
-      };
-      this.remove = function(what) {
-        return $cookieStore.remove(what);
-      };
-    }
-  });
-
-- 
GitLab


From 7f163e935db38ca4347fdcbb73631516928cc0ca Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Wed, 25 Feb 2015 10:08:47 +0100
Subject: [PATCH 10/12] change store service to a provider

add method setStore() to set the storage with the storeProvider

```js
angular.module('app', ['angular-storage'])
    .config(function (storeProvider) {
        storeProvider.setStore('sessionStorage');
    })
    .controller('ctrl', function(store) {
        store.set('name', 'wayne');
    });
```
---
 dist/angular-storage.js                       |  49 +++--
 dist/angular-storage.min.js                   |   2 +-
 src/angularStorage/services/internalStore.js  |  12 +-
 src/angularStorage/services/store.js.js       |  35 ++-
 .../unit/angularStorage/services/storeSpec.js | 206 ++++++++++++------
 5 files changed, 197 insertions(+), 107 deletions(-)

diff --git a/dist/angular-storage.js b/dist/angular-storage.js
index 0205606..d366bc9 100755
--- a/dist/angular-storage.js
+++ b/dist/angular-storage.js
@@ -30,11 +30,11 @@ angular.module('angular-storage.cookieStorage', [])
 angular.module('angular-storage.internalStore', ['angular-storage.localStorage', 'angular-storage.sessionStorage'])
   .factory('InternalStore', ["$log", "$injector", function($log, $injector) {
 
-    function InternalStore(namespace, delimiter) {
+    function InternalStore(namespace, storage, delimiter) {
       this.namespace = namespace || null;
       this.delimiter = delimiter || '.';
       this.inMemoryCache = {};
-      this.storage = $injector.get('localStorage');
+      this.storage = $injector.get(storage || 'localStorage');
     }
 
     InternalStore.prototype.getNamespacedKey = function(key) {
@@ -77,14 +77,6 @@ angular.module('angular-storage.internalStore', ['angular-storage.localStorage',
       this.storage.remove(this.getNamespacedKey(name));
     };
 
-    InternalStore.prototype.setStorage = function(storage) {
-      if (!storage || !angular.isString(storage)) {
-        return;
-      }
-
-      this.storage = $injector.get(storage);
-    };
-
     return InternalStore;
   }]);
 
@@ -136,23 +128,40 @@ angular.module('angular-storage.sessionStorage', ['angular-storage.cookieStorage
   }]);
 
 angular.module('angular-storage.store', ['angular-storage.internalStore'])
-  .factory('store', ["InternalStore", function(InternalStore) {
+  .provider('store', function() {
 
-    var store = new InternalStore();
+    // the default storage
+    var _storage = 'localStorage';
 
     /**
-     * Returns a namespaced store
+     * Sets the storage.
      *
-     * @param {String} namespace The namespace
-     * @param {String} key The key
-     * @returns {InternalStore}
+     * @param {String} storage The storage name
      */
-    store.getNamespacedStore = function(namespace, key) {
-      return new InternalStore(namespace, key);
+    this.setStore = function(storage) {
+      if (storage && angular.isString(storage)) {
+        _storage = storage;
+      }
     };
 
-    return store;
-  }]);
+    this.$get = ["InternalStore", function(InternalStore) {
+      var store = new InternalStore(null, _storage);
+
+      /**
+       * Returns a namespaced store
+       *
+       * @param {String} namespace The namespace
+       * @param {String} storage The name of the storage service
+       * @param {String} key The key
+       * @returns {InternalStore}
+       */
+      store.getNamespacedStore = function(namespace, storage, key) {
+        return new InternalStore(namespace, storage, key);
+      };
+
+      return store;
+    }];
+  });
 
 
 }());
\ No newline at end of file
diff --git a/dist/angular-storage.min.js b/dist/angular-storage.min.js
index bbb584e..ffc6822 100755
--- a/dist/angular-storage.min.js
+++ b/dist/angular-storage.min.js
@@ -1 +1 @@
-!function(){angular.module("angular-storage",["angular-storage.store"]),angular.module("angular-storage.cookieStorage",[]).service("cookieStorage",["$injector",function(e){var t=e.get("$cookieStore");this.set=function(e,r){return t.put(e,r)},this.get=function(e){return t.get(e)},this.remove=function(e){return t.remove(e)}}]),angular.module("angular-storage.internalStore",["angular-storage.localStorage","angular-storage.sessionStorage"]).factory("InternalStore",["$log","$injector",function(e,t){function r(e,r){this.namespace=e||null,this.delimiter=r||".",this.inMemoryCache={},this.storage=t.get("localStorage")}return r.prototype.getNamespacedKey=function(e){return this.namespace?[this.namespace,e].join(this.delimiter):e},r.prototype.set=function(e,t){this.inMemoryCache[e]=t,this.storage.set(this.getNamespacedKey(e),JSON.stringify(t))},r.prototype.get=function(t){var r=null;if(t in this.inMemoryCache)return this.inMemoryCache[t];var o=this.storage.get(this.getNamespacedKey(t));try{r="undefined"==typeof o||"undefined"===o?void 0:JSON.parse(o),this.inMemoryCache[t]=r}catch(a){e.error("Error parsing saved value",a),this.remove(t)}return r},r.prototype.remove=function(e){this.inMemoryCache[e]=null,this.storage.remove(this.getNamespacedKey(e))},r.prototype.setStorage=function(e){e&&angular.isString(e)&&(this.storage=t.get(e))},r}]),angular.module("angular-storage.localStorage",["angular-storage.cookieStorage"]).service("localStorage",["$window","$injector",function(e,t){if(e.localStorage)this.set=function(t,r){return e.localStorage.setItem(t,r)},this.get=function(t){return e.localStorage.getItem(t)},this.remove=function(t){return e.localStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.sessionStorage",["angular-storage.cookieStorage"]).service("sessionStorage",["$window","$injector",function(e,t){if(e.sessionStorage)this.set=function(t,r){return e.sessionStorage.setItem(t,r)},this.get=function(t){return e.sessionStorage.getItem(t)},this.remove=function(t){return e.sessionStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.store",["angular-storage.internalStore"]).factory("store",["InternalStore",function(e){var t=new e;return t.getNamespacedStore=function(t,r){return new e(t,r)},t}])}();
\ No newline at end of file
+!function(){angular.module("angular-storage",["angular-storage.store"]),angular.module("angular-storage.cookieStorage",[]).service("cookieStorage",["$injector",function(e){var t=e.get("$cookieStore");this.set=function(e,r){return t.put(e,r)},this.get=function(e){return t.get(e)},this.remove=function(e){return t.remove(e)}}]),angular.module("angular-storage.internalStore",["angular-storage.localStorage","angular-storage.sessionStorage"]).factory("InternalStore",["$log","$injector",function(e,t){function r(e,r,o){this.namespace=e||null,this.delimiter=o||".",this.inMemoryCache={},this.storage=t.get(r||"localStorage")}return r.prototype.getNamespacedKey=function(e){return this.namespace?[this.namespace,e].join(this.delimiter):e},r.prototype.set=function(e,t){this.inMemoryCache[e]=t,this.storage.set(this.getNamespacedKey(e),JSON.stringify(t))},r.prototype.get=function(t){var r=null;if(t in this.inMemoryCache)return this.inMemoryCache[t];var o=this.storage.get(this.getNamespacedKey(t));try{r="undefined"==typeof o||"undefined"===o?void 0:JSON.parse(o),this.inMemoryCache[t]=r}catch(n){e.error("Error parsing saved value",n),this.remove(t)}return r},r.prototype.remove=function(e){this.inMemoryCache[e]=null,this.storage.remove(this.getNamespacedKey(e))},r}]),angular.module("angular-storage.localStorage",["angular-storage.cookieStorage"]).service("localStorage",["$window","$injector",function(e,t){if(e.localStorage)this.set=function(t,r){return e.localStorage.setItem(t,r)},this.get=function(t){return e.localStorage.getItem(t)},this.remove=function(t){return e.localStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.sessionStorage",["angular-storage.cookieStorage"]).service("sessionStorage",["$window","$injector",function(e,t){if(e.sessionStorage)this.set=function(t,r){return e.sessionStorage.setItem(t,r)},this.get=function(t){return e.sessionStorage.getItem(t)},this.remove=function(t){return e.sessionStorage.removeItem(t)};else{var r=t.get("cookieStorage");this.set=r.set,this.get=r.get,this.remove=r.remove}}]),angular.module("angular-storage.store",["angular-storage.internalStore"]).provider("store",function(){var e="localStorage";this.setStore=function(t){t&&angular.isString(t)&&(e=t)},this.$get=["InternalStore",function(t){var r=new t(null,e);return r.getNamespacedStore=function(e,r,o){return new t(e,r,o)},r}]})}();
\ No newline at end of file
diff --git a/src/angularStorage/services/internalStore.js b/src/angularStorage/services/internalStore.js
index 49bb816..df3157f 100644
--- a/src/angularStorage/services/internalStore.js
+++ b/src/angularStorage/services/internalStore.js
@@ -1,11 +1,11 @@
 angular.module('angular-storage.internalStore', ['angular-storage.localStorage', 'angular-storage.sessionStorage'])
   .factory('InternalStore', function($log, $injector) {
 
-    function InternalStore(namespace, delimiter) {
+    function InternalStore(namespace, storage, delimiter) {
       this.namespace = namespace || null;
       this.delimiter = delimiter || '.';
       this.inMemoryCache = {};
-      this.storage = $injector.get('localStorage');
+      this.storage = $injector.get(storage || 'localStorage');
     }
 
     InternalStore.prototype.getNamespacedKey = function(key) {
@@ -48,14 +48,6 @@ angular.module('angular-storage.internalStore', ['angular-storage.localStorage',
       this.storage.remove(this.getNamespacedKey(name));
     };
 
-    InternalStore.prototype.setStorage = function(storage) {
-      if (!storage || !angular.isString(storage)) {
-        return;
-      }
-
-      this.storage = $injector.get(storage);
-    };
-
     return InternalStore;
   });
 
diff --git a/src/angularStorage/services/store.js.js b/src/angularStorage/services/store.js.js
index a40026d..d84ad2d 100644
--- a/src/angularStorage/services/store.js.js
+++ b/src/angularStorage/services/store.js.js
@@ -1,19 +1,36 @@
 angular.module('angular-storage.store', ['angular-storage.internalStore'])
-  .factory('store', function(InternalStore) {
+  .provider('store', function() {
 
-    var store = new InternalStore();
+    // the default storage
+    var _storage = 'localStorage';
 
     /**
-     * Returns a namespaced store
+     * Sets the storage.
      *
-     * @param {String} namespace The namespace
-     * @param {String} key The key
-     * @returns {InternalStore}
+     * @param {String} storage The storage name
      */
-    store.getNamespacedStore = function(namespace, key) {
-      return new InternalStore(namespace, key);
+    this.setStore = function(storage) {
+      if (storage && angular.isString(storage)) {
+        _storage = storage;
+      }
     };
 
-    return store;
+    this.$get = function(InternalStore) {
+      var store = new InternalStore(null, _storage);
+
+      /**
+       * Returns a namespaced store
+       *
+       * @param {String} namespace The namespace
+       * @param {String} storage The name of the storage service
+       * @param {String} key The key
+       * @returns {InternalStore}
+       */
+      store.getNamespacedStore = function(namespace, storage, key) {
+        return new InternalStore(namespace, storage, key);
+      };
+
+      return store;
+    };
   });
 
diff --git a/test/unit/angularStorage/services/storeSpec.js b/test/unit/angularStorage/services/storeSpec.js
index 47c1025..f46e0aa 100644
--- a/test/unit/angularStorage/services/storeSpec.js
+++ b/test/unit/angularStorage/services/storeSpec.js
@@ -67,69 +67,130 @@ describe('angularStorage store', function() {
     expect(store.get('gonto')).to.eql(value);
     expect(store.get('gonto')).not.to.equal(value);
   }));
+});
 
-  describe('.setStorage()', function () {
+describe('angularStorage storeProvider.setStore("sessionStorage")', function () {
 
-    var $cookieStore;
+  var provider;
 
-    beforeEach(module('ngCookies'));
+  beforeEach(function() {
+    module('angular-storage.store', function(storeProvider) {
+      provider = storeProvider;
+      provider.setStore('sessionStorage');
+    });
+  });
 
-    beforeEach(inject(function( _$cookieStore_) {
-      $cookieStore = _$cookieStore_;
-    }));
+  it('should save items correctly in the sessionStorage', inject(function(store, $window) {
+    var value = 44;
+    store.set('gonto', value);
 
-    it('should should save items correctly when the storage is changed to sessionStorage', inject(function(store, $window) {
-      var value = 11;
-      store.setStorage('sessionStorage');
-      store.set('gonto', value);
+    expect(store.get('gonto')).to.equal(value);
+    expect($window.sessionStorage.getItem('gonto')).to.exist;
+    expect($window.sessionStorage.getItem('gonto')).to.equal(value.toString());
+  }));
+});
 
-      expect(store.get('gonto')).to.equal(value);
-      expect($window.sessionStorage.getItem('gonto')).to.exist;
-      expect($window.sessionStorage.getItem('gonto')).to.equal(value.toString());
-    }));
+describe('angularStorage storeProvider.setStore("localStorage")', function () {
 
-    it('should should save items correctly when the storage is changed to localStorage', inject(function(store, $window) {
-      var value = 22;
-      store.setStorage('localStorage');
-      store.set('gonto', value);
+  var provider;
 
-      expect(store.get('gonto')).to.equal(value);
-      expect($window.localStorage.getItem('gonto')).to.exist;
-      expect($window.localStorage.getItem('gonto')).to.equal(value.toString());
-    }));
+  beforeEach(function() {
+    module('angular-storage.store', function(storeProvider) {
+      provider = storeProvider;
+      provider.setStore('localStorage');
+    });
+  });
+
+  it('should save items correctly in the localStorage', inject(function(store, $window) {
+    var value = 55;
+    store.set('gonto', value);
 
-    it('should should save items correctly when the storage is changed to cookieStorage', inject(function(store) {
-      var value = 22;
-      store.setStorage('cookieStorage');
-      store.set('gonto', value);
+    expect(store.get('gonto')).to.equal(value);
+    expect($window.localStorage.getItem('gonto')).to.exist;
+    expect($window.localStorage.getItem('gonto')).to.equal(value.toString());
+  }));
+});
 
-      expect(store.get('gonto')).to.equal(value);
-      expect($cookieStore.get('gonto')).to.equal(JSON.stringify(value));
-    }));
+describe('angularStorage storeProvider.setStore("cookieStorage")', function () {
 
-    it('should not change store when param storage is not a string', inject(function(store, $window) {
-      var value = 2222;
-      store.setStorage({a:3});
-      store.set('xxx', value);
+  var provider;
+  var $cookieStore;
 
-      expect(store.get('xxx')).to.equal(value);
-      expect($window.localStorage.getItem('xxx')).to.exist;
-      expect($window.localStorage.getItem('xxx')).to.equal(value.toString());
-    }));
+  beforeEach(function() {
+    module('ngCookies', 'angular-storage.store', function(storeProvider) {
+      provider = storeProvider;
+      provider.setStore('cookieStorage');
+    });
+  });
 
-    it('should not change store when param storage is an empty string', inject(function(store, $window) {
-      var value = 2222;
-      store.setStorage('');
-      store.set('xxx', value);
+  beforeEach(inject(function( _$cookieStore_) {
+    $cookieStore = _$cookieStore_;
+  }));
 
-      expect(store.get('xxx')).to.equal(value);
-      expect($window.localStorage.getItem('xxx')).to.exist;
-      expect($window.localStorage.getItem('xxx')).to.equal(value.toString());
-    }));
+  it('should save items correctly in the cookieStorage', inject(function(store) {
+    var value = 66;
+    store.set('gonto', value);
 
-    it('should throw an error when the store is not found', inject(function(store) {
-      expect(function() { store.setStorage('abc'); } ).to.throw(Error, /Unknown provider: abcProvider <- abc/);
-    }));
+    expect(store.get('gonto')).to.equal(value);
+    expect($cookieStore.get('gonto')).to.equal(JSON.stringify(value));
+  }));
+});
+
+describe('angularStorage storeProvider.setStore()', function () {
+
+  var provider;
+
+  beforeEach(function() {
+    module('angular-storage.store', function(storeProvider) {
+      provider = storeProvider;
+      provider.setStore();
+    });
+  });
+
+  it('should save items correctly in the localStorage', inject(function(store, $window) {
+    var value = 77;
+    store.set('gonto', value);
+
+    expect(store.get('gonto')).to.equal(value);
+    expect($window.localStorage.getItem('gonto')).to.exist;
+    expect($window.localStorage.getItem('gonto')).to.equal(value.toString());
+  }));
+});
+
+describe('angularStorage storeProvider.setStore(123)', function () {
+
+  var provider;
+
+  beforeEach(function() {
+    module('angular-storage.store', function(storeProvider) {
+      provider = storeProvider;
+      provider.setStore(123);
+    });
+  });
+
+  it('should save items correctly in the localStorage', inject(function(store, $window) {
+    var value = 77;
+    store.set('gonto', value);
+
+    expect(store.get('gonto')).to.equal(value);
+    expect($window.localStorage.getItem('gonto')).to.exist;
+    expect($window.localStorage.getItem('gonto')).to.equal(value.toString());
+  }));
+});
+
+describe('angularStorage storeProvider.setStore("abc")', function () {
+
+  var provider;
+
+  beforeEach(function() {
+    module('angular-storage.store', function(storeProvider) {
+      provider = storeProvider;
+      provider.setStore('abc');
+    });
+  });
+
+  it('should throw an error when the store is not found', function() {
+    expect(function() { inject(function(store){ store.get('a');}); } ).to.throw();
   });
 });
 
@@ -289,42 +350,53 @@ describe('angularStorage new namespaced store', function() {
     expect(newStore.get('gonto')).not.to.equal(value);
   });
 
-  describe('.setStorage()', function () {
+  it('should should save items correctly when the delimiter is set', inject(function(store, $window) {
+    var value = 111;
+    var aStore = store.getNamespacedStore('aa', 'sessionStorage', '-');
+    aStore.set('wayne', value);
+
+    expect(aStore.get('wayne')).to.equal(value);
+    expect($window.sessionStorage.getItem('aa-wayne')).to.exist;
+    expect($window.sessionStorage.getItem('aa-wayne')).to.equal(value.toString());
+    expect($window.sessionStorage.getItem('wayne')).to.not.exist;
+  }));
+
+  describe('with param storage', function () {
     var $cookieStore;
 
     beforeEach(inject(function( _$cookieStore_) {
       $cookieStore = _$cookieStore_;
     }));
 
-    it('should should save items correctly when the storage is changed to sessionStorage', inject(function( $window) {
+    it('should should save items correctly when the storage is set to sessionStorage', inject(function(store, $window) {
       var value = 111;
-      newStore.setStorage('sessionStorage');
-      newStore.set('wayne', value);
+      var sessionStore = store.getNamespacedStore('aa', 'sessionStorage');
+      sessionStore.set('wayne', value);
 
-      expect(newStore.get('wayne')).to.equal(value);
-      expect($window.sessionStorage.getItem('auth0.wayne')).to.exist;
-      expect($window.sessionStorage.getItem('auth0.wayne')).to.equal(value.toString());
+      expect(sessionStore.get('wayne')).to.equal(value);
+      expect($window.sessionStorage.getItem('aa.wayne')).to.exist;
+      expect($window.sessionStorage.getItem('aa.wayne')).to.equal(value.toString());
       expect($window.sessionStorage.getItem('wayne')).to.not.exist;
     }));
 
-    it('should should save items correctly when the storage is changed to localStorage', inject(function($window) {
+    it('should should save items correctly when the storage is set to localStorage', inject(function(store, $window) {
       var value = 222;
-      newStore.setStorage('localStorage');
-      newStore.set('wayne', value);
+      var localStore = store.getNamespacedStore('bb', 'localStorage');
+      localStore.set('wayne', value);
 
-      expect(newStore.get('wayne')).to.equal(value);
-      expect($window.localStorage.getItem('auth0.wayne')).to.exist;
-      expect($window.localStorage.getItem('auth0.wayne')).to.equal(value.toString());
+      expect(localStore.get('wayne')).to.equal(value);
+      expect($window.localStorage.getItem('bb.wayne')).to.exist;
+      expect($window.localStorage.getItem('bb.wayne')).to.equal(value.toString());
       expect($window.localStorage.getItem('wayne')).to.not.exist;
     }));
 
-    it('should should save items correctly when the storage is changed to cookieStorage', inject(function() {
-      var value = 333;
-      newStore.setStorage('cookieStorage');
-      newStore.set('wayne', value);
+    it('should should save items correctly when the storage is set to cookieStorage', inject(function(store) {
+      var value = 222;
+      var cookieStore = store.getNamespacedStore('cc', 'cookieStorage');
+      cookieStore.set('wayne', value);
 
-      expect(newStore.get('wayne')).to.equal(value);
-      expect($cookieStore.get('auth0.wayne')).to.equal(JSON.stringify(value));
+      expect(cookieStore.get('wayne')).to.equal(value);
+      expect($cookieStore.get('cc.wayne')).to.equal(JSON.stringify(value));
     }));
   });
 });
-- 
GitLab


From 3ffdeb2589a843b2a930c5801a1f8856fc973321 Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Wed, 25 Feb 2015 21:06:44 +0100
Subject: [PATCH 11/12] add code coverage task `gulp cover`

---
 .gitignore                                    |  3 +
 gulpfile.js                                   | 13 +++
 karma-src.coverage.conf.js                    | 85 +++++++++++++++++++
 package.json                                  |  1 +
 .../unit/angularStorage/services/storeSpec.js | 43 ++++++++--
 5 files changed, 140 insertions(+), 5 deletions(-)
 create mode 100644 karma-src.coverage.conf.js

diff --git a/.gitignore b/.gitignore
index a1994cb..376d4b3 100755
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,6 @@ libpeerconnection.log
 
 # Bower components
 bower
+
+# report files
+reports/
diff --git a/gulpfile.js b/gulpfile.js
index 3b8e89b..ac852da 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -83,5 +83,18 @@ gulp.task('test-dist-minified', function (done) {
   }, done);
 });
 
+/**
+ * Run code coverage tests once and exit
+ */
+gulp.task('cover', function (done) {
+  karma.start({
+    configFile: __dirname + '/karma-src.coverage.conf.js',
+    singleRun: true
+  }, function() {
+    console.log('Code coverage report created: %s', require('path').join(process.cwd(), 'reports', 'coverage'));
+    done();
+  });
+});
+
 gulp.task('default', ['lint', 'test', 'build']);
 gulp.task('dist', ['test-dist-concatenated', 'test-dist-minified']);
diff --git a/karma-src.coverage.conf.js b/karma-src.coverage.conf.js
new file mode 100644
index 0000000..af1e571
--- /dev/null
+++ b/karma-src.coverage.conf.js
@@ -0,0 +1,85 @@
+// Karma configuration
+// Generated on Thu Aug 21 2014 10:24:39 GMT+0200 (CEST)
+
+module.exports = function(config) {
+  config.set({
+
+    // base path that will be used to resolve all patterns (eg. files, exclude)
+    basePath: '',
+
+
+    // frameworks to use
+    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+    frameworks: ['mocha', 'chai-jquery', 'jquery-1.8.3', 'sinon-chai'],
+
+    plugins: [
+      'karma-mocha',
+      'karma-chai',
+      'karma-sinon-chai',
+      'karma-chrome-launcher',
+      'karma-phantomjs-launcher',
+      'karma-jquery',
+      'karma-chai-jquery',
+      'karma-mocha-reporter',
+      'karma-coverage'
+    ],
+
+    // list of files / patterns to load in the browser
+    files: [
+      'bower/angular/angular.js',
+      'bower/angular-mocks/angular-mocks.js',
+      'bower/angular-cookies/angular-cookies.js',
+      'src/**/*.js',
+      'test/unit/**/*.js'
+    ],
+
+
+    // list of files to exclude
+    exclude: [
+    ],
+
+
+    // preprocess matching files before serving them to the browser
+    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
+    preprocessors: {
+      'src/**/*.js': 'coverage'
+    },
+
+    coverageReporter: {
+      type: 'html',
+      dir: 'reports/coverage'
+    },
+
+    // test results reporter to use
+    // possible values: 'dots', 'progress'
+    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
+    reporters: ['mocha', 'coverage'],
+
+
+    // web server port
+    port: 9876,
+
+
+    // enable / disable colors in the output (reporters and logs)
+    colors: true,
+
+
+    // level of logging
+    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+    logLevel: config.LOG_INFO,
+
+
+    // enable / disable watching file and executing tests whenever any file changes
+    autoWatch: true,
+
+
+    // start these browsers
+    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
+    browsers: ['PhantomJS'],
+
+
+    // Continuous Integration mode
+    // if true, Karma captures browsers, runs the tests and exits
+    singleRun: false
+  });
+};
diff --git a/package.json b/package.json
index caa5668..e50920a 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
     "karma-chai": "^0.1.0",
     "karma-chai-jquery": "^1.0.0",
     "karma-chrome-launcher": "^0.1.4",
+    "karma-coverage": "^0.2.7",
     "karma-detect-browsers": "^1.1.0",
     "karma-jasmine": "^0.1.5",
     "karma-jquery": "^0.1.0",
diff --git a/test/unit/angularStorage/services/storeSpec.js b/test/unit/angularStorage/services/storeSpec.js
index f46e0aa..fe1e4e6 100644
--- a/test/unit/angularStorage/services/storeSpec.js
+++ b/test/unit/angularStorage/services/storeSpec.js
@@ -81,12 +81,45 @@ describe('angularStorage storeProvider.setStore("sessionStorage")', function ()
   });
 
   it('should save items correctly in the sessionStorage', inject(function(store, $window) {
-    var value = 44;
-    store.set('gonto', value);
+    var value = 99;
+    store.set('gonto123', value);
+    store.inMemoryCache = {};
 
-    expect(store.get('gonto')).to.equal(value);
-    expect($window.sessionStorage.getItem('gonto')).to.exist;
-    expect($window.sessionStorage.getItem('gonto')).to.equal(value.toString());
+    expect(store.get('gonto123')).to.equal(value);
+    expect($window.sessionStorage.getItem('gonto123')).to.exist;
+    expect($window.sessionStorage.getItem('gonto123')).to.equal(value.toString());
+
+    store.remove('gonto123');
+
+    expect(store.get('gonto123')).to.not.exist;
+    expect($window.sessionStorage.getItem('gonto123')).to.not.exist;
+  }));
+});
+
+describe('angularStorage storeProvider.setStore("sessionStorage")', function () {
+
+  var provider, windowMock, $cookieStore;
+
+  beforeEach(function() {
+    module('ngCookies', 'angular-storage.store', function(storeProvider, $provide) {
+      provider = storeProvider;
+      provider.setStore('sessionStorage');
+
+      windowMock = { sessionStorage: undefined };
+      $provide.value('$window', windowMock);
+    });
+  });
+
+  beforeEach(inject(function( _$cookieStore_) {
+    $cookieStore = _$cookieStore_;
+  }));
+
+  it('should fallback to cookieStorage', inject(function(store) {
+    var value = 99;
+    store.set('gonto123', value);
+
+    expect(store.get('gonto123')).to.equal(value);
+    expect($cookieStore.get('gonto123')).to.equal(JSON.stringify(value));
   }));
 });
 
-- 
GitLab


From a844041f87b945378138ea1645b3f54b83fee6fe Mon Sep 17 00:00:00 2001
From: Andreas Krummsdorf <a.krummsdorf@litixsoft.de>
Date: Sat, 14 Mar 2015 07:52:41 +0100
Subject: [PATCH 12/12] test: add code coverage specific karma settings to the
 gulpfile

* makes karma-src.coverage.conf.js unnecessary
---
 gulpfile.js                | 12 +++++-
 karma-src.conf.js          |  5 ++-
 karma-src.coverage.conf.js | 85 --------------------------------------
 package.json               |  4 +-
 4 files changed, 15 insertions(+), 91 deletions(-)
 delete mode 100644 karma-src.coverage.conf.js

diff --git a/gulpfile.js b/gulpfile.js
index ac852da..5f848bf 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -88,8 +88,16 @@ gulp.task('test-dist-minified', function (done) {
  */
 gulp.task('cover', function (done) {
   karma.start({
-    configFile: __dirname + '/karma-src.coverage.conf.js',
-    singleRun: true
+    configFile: __dirname + '/karma-src.conf.js',
+    singleRun: true,
+    preprocessors: {
+      'src/**/*.js': 'coverage'
+    },
+    coverageReporter: {
+      type: 'html',
+      dir: 'reports/coverage'
+    },
+    reporters: ['mocha', 'coverage']
   }, function() {
     console.log('Code coverage report created: %s', require('path').join(process.cwd(), 'reports', 'coverage'));
     done();
diff --git a/karma-src.conf.js b/karma-src.conf.js
index 9147c11..f596e76 100644
--- a/karma-src.conf.js
+++ b/karma-src.conf.js
@@ -20,14 +20,15 @@ module.exports = function(config) {
       'karma-phantomjs-launcher',
       'karma-jquery',
       'karma-chai-jquery',
-      'karma-mocha-reporter'
+      'karma-mocha-reporter',
+      'karma-coverage'
     ],
 
     // list of files / patterns to load in the browser
     files: [
       'bower/angular/angular.js',
       'bower/angular-mocks/angular-mocks.js',
-      'bower/angular-cookies/angular-cookies.js',	  
+      'bower/angular-cookies/angular-cookies.js',
       'src/**/*.js',
       'test/unit/**/*.js'
     ],
diff --git a/karma-src.coverage.conf.js b/karma-src.coverage.conf.js
deleted file mode 100644
index af1e571..0000000
--- a/karma-src.coverage.conf.js
+++ /dev/null
@@ -1,85 +0,0 @@
-// Karma configuration
-// Generated on Thu Aug 21 2014 10:24:39 GMT+0200 (CEST)
-
-module.exports = function(config) {
-  config.set({
-
-    // base path that will be used to resolve all patterns (eg. files, exclude)
-    basePath: '',
-
-
-    // frameworks to use
-    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
-    frameworks: ['mocha', 'chai-jquery', 'jquery-1.8.3', 'sinon-chai'],
-
-    plugins: [
-      'karma-mocha',
-      'karma-chai',
-      'karma-sinon-chai',
-      'karma-chrome-launcher',
-      'karma-phantomjs-launcher',
-      'karma-jquery',
-      'karma-chai-jquery',
-      'karma-mocha-reporter',
-      'karma-coverage'
-    ],
-
-    // list of files / patterns to load in the browser
-    files: [
-      'bower/angular/angular.js',
-      'bower/angular-mocks/angular-mocks.js',
-      'bower/angular-cookies/angular-cookies.js',
-      'src/**/*.js',
-      'test/unit/**/*.js'
-    ],
-
-
-    // list of files to exclude
-    exclude: [
-    ],
-
-
-    // preprocess matching files before serving them to the browser
-    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
-    preprocessors: {
-      'src/**/*.js': 'coverage'
-    },
-
-    coverageReporter: {
-      type: 'html',
-      dir: 'reports/coverage'
-    },
-
-    // test results reporter to use
-    // possible values: 'dots', 'progress'
-    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
-    reporters: ['mocha', 'coverage'],
-
-
-    // web server port
-    port: 9876,
-
-
-    // enable / disable colors in the output (reporters and logs)
-    colors: true,
-
-
-    // level of logging
-    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
-    logLevel: config.LOG_INFO,
-
-
-    // enable / disable watching file and executing tests whenever any file changes
-    autoWatch: true,
-
-
-    // start these browsers
-    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
-    browsers: ['PhantomJS'],
-
-
-    // Continuous Integration mode
-    // if true, Karma captures browsers, runs the tests and exits
-    singleRun: false
-  });
-};
diff --git a/package.json b/package.json
index e50920a..634e354 100644
--- a/package.json
+++ b/package.json
@@ -25,11 +25,11 @@
     "karma-chai-jquery": "^1.0.0",
     "karma-chrome-launcher": "^0.1.4",
     "karma-coverage": "^0.2.7",
-    "karma-detect-browsers": "^1.1.0",
+    "karma-detect-browsers": "^1.1.2",
     "karma-jasmine": "^0.1.5",
     "karma-jquery": "^0.1.0",
     "karma-mocha": "^0.1.8",
-    "karma-mocha-reporter": "^1.0.0",
+    "karma-mocha-reporter": "^1.0.1",
     "karma-phantomjs-launcher": "^0.1.4",
     "karma-sinon-chai": "^0.2.0",
     "mocha": "^1.21.4",
-- 
GitLab