CookieJS icon indicating copy to clipboard operation
CookieJS copied to clipboard

Some extra features; ability to save cookies as JSON objects, unit tests

Open mrozbarry opened this issue 10 years ago • 1 comments

Are you okay with my possibly adding some features and unit testing? I ask because this was one of the top main feature-complete and lightweight cookie handling libraries, and it could definitely use some extra love.

I was mainly thinking of being able to save/retrieve data more like JSON, so you could do something like:

  // Backwards compatible
  CookieJS.set({name: 'some.type.of.namespaced.objec', value: 'foobar'});

  // Object notation
  CookieJS.setObject({object: {some:{type:{of:{namespaced:{object:'foobar'}}}}}});

  // Namespace notation
  CookieJS.set({name:['some', 'type', 'of', 'namespaced','object'], value: 'foobar'});

CookieJS.set could probably intelligently detect if the value is an object so the second case could just become:

CookieJS.set({value: {some:{type:{of:{namespaced:{object:'foobar'}}}}}});

Internally, there are two options for storaged:

  1. Use the root object member as the cookie name, save using JSON.stringify()

    CookieJS.setObject = function(params) {
     var keys = params.object.keys(); // Get a list of root keys
     for(var key in keys) {
       CookieJS.set({name: key, value: JSON.stringify(params.object[key])});
     }
    }
    
  2. Use one cookie per path as a larger JSON object

    // Attempt to use already implemented merge object functions if available, otherwise, roll our own
    var mergeObject = null;
    if (typeof Object.prototype.assign == 'function') {
      mergeObject = Object.prototype.assign;
    }  else if (_ && _.extend) {
      mergeObject = _.extend;
    } else {
      mergeObject = function(object, extension) {
        if (object == {} && extension ) return extension;
        var modifiedObject = object;
        for(var key in extension.keys()) {
          if (typeof extension[key] == 'object' && typeof modifiedObject[key] == 'object') {
            modifiedObject[key] = mergeObject(modifiedObject[key], extension[key]);
          } else {
            modifiedObject[key] = extension[key];
          }
        }
        return modifiedObject;
      };
    }
    
    CookieJS.setObject = function(params) {
      var key = params.path || '/';
      try {
        var obj = JSON.parse(CookieJS.get(key));
      } catch {
        var obj = {};
      }
      CookieJS.set({name: key, value: mergeObject(obj, params.value)});
    }
    

Also, it may be good if CookieJS.set returns the value it set so it would be possible to chain it with other functions.


For unit tests, I think QUnit may be a good choice here, as we're modifying document.cookies, and I don't trust things like PhantomJS to emulate cookie behaviour properly (not that it wouldn't work, but the real thing is always best). I think, however, using a combination of mocha with QUnit will use PhantomJS anyway, and mocha would be nice to run inside of gulp. Any preferences on this?

mrozbarry avatar Feb 07 '15 16:02 mrozbarry

Sounds like a good idea. Sorry my late response.

Since I'm using my time learning and doing other stuff than this library, I don't have time to maintain this one. Reason I created this library was just because I needed those features. So as long as those features works after your new ones, you can just add them.

How you want to test is your call.

I just got a couple of things, and that is you need to follow editorconfig and jshintrc. Thats it.

bjarneo avatar Feb 09 '15 07:02 bjarneo