From 4bc5e671abd1595c059ac668c41994342565908b Mon Sep 17 00:00:00 2001 From: Josh Lind Date: Tue, 16 Dec 2014 01:37:56 -0800 Subject: [PATCH 1/4] documentation first, improved get function, test todos --- DOCS.md | 76 ++++++++++++++++++++++++++------------- README.md | 37 +++++++++---------- groucho.json | 2 +- src/groucho.js | 85 ++++++++++++++++++++++++++++++++++---------- test/groucho_test.js | 58 +++++++++++++++++++++++++++--- 5 files changed, 188 insertions(+), 70 deletions(-) diff --git a/DOCS.md b/DOCS.md index 0228d39..3a28dea 100644 --- a/DOCS.md +++ b/DOCS.md @@ -119,10 +119,11 @@ groucho.config = { ] } ``` -To write your own features, grab browsing history and work with it like this... + +To write your own features, grab browsing history and work with it. You'll need to use a little structure to define the condition, in this case: the name of the tracking group... ```javascript -$.each(groucho.getActivities('browsing'), function (key, record) { +$.each(groucho.getActivities(), function (key, record) { someComparison(record.property, record.url); }); ``` @@ -270,45 +271,70 @@ var favCategoryTerms = groucho.getFavoriteTerms('*', false, 7); You can register your own tracking activities like this... ```javascript -// Track your own activities. -$('.my-special-links').bind('click', function (e) { - myObj.linkText = $(this).text() - myObj.myProperty = $(this).attr('data-property'); - groucho.createActivity('my_activity', myObj); +$('.videos a.play').bind('click', function() { + groucho.createActivity('watch', { + 'videoId' : $(this).data('videoId'), + 'category' : $(this).data('category'), + 'videoTitle' : $(this).text() + }); }); ``` -They will be stored as key/value in jStorage. But can be returned as an array, filtered down to the group specified. +They will be stored as key/value in jStorage. But can be returned as an array, filtered down to the group specified. Remember to structure the condition. ```javascript -var myActivities = groucho.getActivities('my_activity'); +var condition = {'group' : 'watch'}, + myActivities = groucho.getActivities(condition); ``` + ```json [{ - "_key" : "track.my_activity.398649600", - "linkText" : "Link text from page", - "myProperty" : "the-property-value" + "_key" : "track.watch.398649600", + "videoId" : 456, + "category" : "tutorial", + "videoTitle" : "Learn About Something" }, { - "_key" : "track.my_activity.398649999", - "linkText" : "Other link text", - "myProperty" : "this-property-value" + "_key" : "track.watch.398649999", + "videoId" : 789, + "category" : "fun", + "videoTitle" : "Be Entertained" }] ``` -You can work directly with tracking activites and create your own smart functions... +You can work directly with tracking activites and create your own smart functions. This example finds tutorial videos watched in the last week... + ```javascript -function myActivitySmarts () { - var myActivities = groucho.getActivities('my_activity'), - record; - - for (i in myActivities) { - record = myActivities[i]; - if (myComparison(record.property, record.url, record._key.split('.')[2])) { - count++; +function recentVideos(timeframe, category) { + var query = { + 'group' : 'watch', + 'conditions' : [ + 'property' : 'type', + 'values' : category + ] + }, + myActivities = groucho.getActivities(query), + now = new Date().getTime(), + recentList, + timestamp; + + for (var i in myActivities) { + timestamp = myActivities[i]._key.split('.')[2]); + if (timestamp > (now - timeframe)) { + returnRecent.push({ + 'videoTitle' : myActivities[i].videoTitle, + 'url' : myActivities[i].url + }); } } - return count; } + +$.each(recentVideos(604800, ['tutorial']), function() { + newItem = '
  • ' + this.videoTitle + '
  • '; + $('ul.recentlyWatched').append(newItem); +}); ``` +_...but you shouldn't insert HTML this way._ + + ### Local Storage This library uses in-browser key/value localStorage with the convenient jStorage abstraction library. If you're new to localStorage, it's no big deal and is a new tool we should all be using. diff --git a/README.md b/README.md index e726074..b58ec76 100644 --- a/README.md +++ b/README.md @@ -100,11 +100,11 @@ if (groucho.favoriteTerms.hasOwnProperty(taxonomy)) { ### Pageview Tracking Use page view activity tracking to dig through history and alter UX. - ```javascript -var history = groucho.getActivities('browsing'), +var history = groucho.getActivities(), links = $('a.promoted'), count = 0; + for (var i in history) { // Determine if they've seen a page with a specific property. if (history[i].hasOwnProperty('myProperty') count++; @@ -114,37 +114,32 @@ if (count < 2) links.addClass('featured'); else if (count >= 2 && count < 7) links.addClass('reduced'); else links.addClass('hidden'); ``` -Show the last viewed item of a given type. Example is last watched video... - -```javascript -var history = groucho.getActivities('watch'); -if (history.length) { - $.get("videos.json?id=" + history[0].videoId, function(data) { - $('.recent').html(displayVideo(data)); - }); -} -``` ## Custom Activies Register your own tracking activities like this... +```javascript +$('.videos a.play').bind('click', function() { + groucho.createActivity('watch', {'videoId' : 789}); +}); +``` +Retrieve activities later to personalize pages. Example swaps in the last watched video... ```javascript -// Track your own activities. -$('.my-special-links').bind('click', function (e) { - groucho.createActivity('my_activity', { - 'linkText' : $(this).text(), - 'myProperty' : $(this).attr('data-property') +var history = groucho.getActivities({'group' : 'watch'}); + +if (history.length) { + $.get("videos.json?id=" + history[0].videoId, function(data) { + $('.recent').find('.title').text(data.title) + .find('.graphic').text(data.graphic) + .find('a').attr('href', data.url); }); -}); -// Later... -myActivites = groucho.getActivities('my_activity'); +} ``` ### Basic User Info Wait for data availability and user basic user info. - ```javascript (function ($) { $(document).ready(function(){ diff --git a/groucho.json b/groucho.json index 02bd53b..f93f572 100644 --- a/groucho.json +++ b/groucho.json @@ -2,7 +2,7 @@ "name": "groucho", "title": "Groucho", "description": "Know more about your anonymous users. In-browser storage tracking tool.", - "version": "0.2.1", + "version": "0.3.0", "homepage": "https://github.com/tableau-mkt/groucho", "author": { "name": "Josh Lind", diff --git a/src/groucho.js b/src/groucho.js index da90ea9..6087a40 100644 --- a/src/groucho.js +++ b/src/groucho.js @@ -97,7 +97,7 @@ var groucho = window.groucho || {}; */ groucho.createActivity = function createActivity(group, data) { - var results = groucho.getActivities(group), + var results = groucho.getActivities({'group' : group}), n = new Date().getTime(), diff = 0; @@ -116,36 +116,83 @@ var groucho = window.groucho || {}; /** * Access records of a specific tracking group. * - * @param {string} group - * Name of the tracking group to return values for. + * @param {object} query + * Strucutured conditions for activity lookup: {group, property, [values]}. * * return {array} * List of tracking localStorage entries. */ - groucho.getActivities = function getActivities(group) { - - var results = $.jStorage.index(), + groucho.getActivities = function getActivities(query) { + + var conditions = query || {}, + group = (conditions.hasOwnProperty('group')) ? conditions.group : false, + property = (conditions.hasOwnProperty('property')) ? conditions.property : false, + values = (conditions.hasOwnProperty('values')) ? conditions.values : false, + groupMatch = new RegExp("^track." + group + ".", "g"), + results = $.jStorage.index(), returnVals = [], - matchable = new RegExp("^track." + group + ".", "g"), record; + /** + * Grab record from storage, add to returns. + * + * @param string key + * Browser storage lookup key. + */ + function addRecord(key) { + record = $.jStorage.get(key); + // Move key to special property. + record._key = key; + returnVals.push(record); + } + + /** + * Confirm property is of desired values. + * NOTE: String comparison only! + * + * @param {string} property + * Name of record property. + * @param {array} values + * List of acceptable values. + * @param {string} record + * Record value to check. + * + * @return {boolean} + * Result of match check. + */ + function checkProperty(property, values, record) { + // Confirm conditions required. + if (property && values) { + // Picky about types. + if (typeof property === 'string' && values instanceof Array) { + for (var i in values) { + // Confirm an acceptable value. + if (record.hasOwnProperty(property) && record.property === values[i]) { + addRecord(record); + // Only need one match per value set. + break; + } + } + } + } + else { + // Property or values not in conditions. + addRecord(record); + } + } + + // Look through storage index. for (var i in results) { // Remove unwanted types and return records. if (group) { - if (results[i].match(matchable) !== null) { - // Collect relevant. - record = $.jStorage.get(results[i]); - // Move key to property. - record._key = results[i]; - returnVals.push(record); + if (results[i].match(groupMatch) !== null) { + // Move on to checking property or just add. + checkProperty(property, values, results[i]); } } else { - // Collect and return all. - record = $.jStorage.get(results[i]); - // Move key to property. - record._key = results[i]; - returnVals.push(record); + // Just check property or just add. + checkProperty(property, values, results[i]); } } @@ -166,7 +213,7 @@ var groucho = window.groucho || {}; */ groucho.getFavoriteTerms = function getFavoriteTerms(vocab, returnAll, threshold) { - var results = groucho.getActivities('browsing'), + var results = groucho.getActivities({'group' : 'browsing'}), termProp = groucho.config.taxonomyProperty, pages = [], returnTerms = {}, diff --git a/test/groucho_test.js b/test/groucho_test.js index b008719..0950ae7 100644 --- a/test/groucho_test.js +++ b/test/groucho_test.js @@ -84,7 +84,7 @@ }); test('Pageview activities', function() { - var myResults = groucho.getActivities('browsing'), + var myResults = groucho.getActivities({'group' : 'browsing'}), fakeData = { 'meainingLess': 'info' }, timeout = 0; @@ -110,7 +110,7 @@ history.pushState('', 'New Page Title', window.location + '#another-page'); // Manually create another browsing record. groucho.trackHit(); - myResults = groucho.getActivities('browsing'); + myResults = groucho.getActivities({'group' : 'browsing'}); strictEqual( myResults.length, 2, @@ -127,7 +127,7 @@ timeout = i * 150; stop(); setTimeout(function () { - groucho.createActivity('fake_thing', fakeData); + groucho.createActivity('fake_thing', fakeData); start(); }, timeout); } @@ -137,7 +137,7 @@ setTimeout(function () { strictEqual( - groucho.getActivities('fake_thing').length, + groucho.getActivities({'group' : 'fake_thing'}).length, groucho.config.trackExtent, 'Tracking activities are kept within the configured extent' ); @@ -158,6 +158,56 @@ }); + //@todo Confirm granular activity request work. + test('Activity retrieval', function() { + +/* + + groucho.getActivities(); + + groucho.getActivities({ + 'group' : 'fake_thing', + }); + + groucho.getActivities({ + 'group' : 'wrong', + }); + + groucho.getActivities({ + 'group' : 'fake_thing', + 'property' : 'entityBundle' + }); + + groucho.getActivities({ + 'group' : 'fake_thing', + 'value' : ['article'] + }); + + groucho.getActivities({ + 'group' : 'fake_thing', + 'property' : 'entityBundle', + 'value' : 'article' + }); + + groucho.getActivities({ + 'group' : 'fake_thing', + 'property' : 'entityBundle', + 'value' : ['article'] + }); + + groucho.getActivities({ + 'group' : 'fake_thing', + 'property' : 'entityBundle', + 'value' : ['wrong', 'article'] + }); + + groucho.getActivities({ + 'group' : 'fake_thing', + 'property' : 'entityBundle', + 'value' : ['wrong'] + }); +*/ + }); module('Favorites'); From f634859ebc9c68379d5c51d20e1a24da68b5fa2e Mon Sep 17 00:00:00 2001 From: Josh Lind Date: Tue, 16 Dec 2014 01:44:41 -0800 Subject: [PATCH 2/4] doc accuracy, faux test number --- DOCS.md | 8 +++----- README.md | 2 +- test/groucho_test.js | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/DOCS.md b/DOCS.md index 3a28dea..c486fb2 100644 --- a/DOCS.md +++ b/DOCS.md @@ -123,7 +123,7 @@ groucho.config = { To write your own features, grab browsing history and work with it. You'll need to use a little structure to define the condition, in this case: the name of the tracking group... ```javascript -$.each(groucho.getActivities(), function (key, record) { +$.each(groucho.getActivities({'group' : 'browsing'}), function (key, record) { someComparison(record.property, record.url); }); ``` @@ -306,10 +306,8 @@ You can work directly with tracking activites and create your own smart function function recentVideos(timeframe, category) { var query = { 'group' : 'watch', - 'conditions' : [ - 'property' : 'type', - 'values' : category - ] + 'property' : 'type', + 'values' : [category] }, myActivities = groucho.getActivities(query), now = new Date().getTime(), diff --git a/README.md b/README.md index b58ec76..aaec91a 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ if (groucho.favoriteTerms.hasOwnProperty(taxonomy)) { Use page view activity tracking to dig through history and alter UX. ```javascript -var history = groucho.getActivities(), +var history = groucho.getActivities({'group' : 'browsing'}), links = $('a.promoted'), count = 0; diff --git a/test/groucho_test.js b/test/groucho_test.js index 0950ae7..07ab8ae 100644 --- a/test/groucho_test.js +++ b/test/groucho_test.js @@ -159,7 +159,7 @@ }); //@todo Confirm granular activity request work. - test('Activity retrieval', function() { + test('Activity retrieval', 0, function() { /* From abfe5df75b1989b90a861a8431cc4db93f012587 Mon Sep 17 00:00:00 2001 From: Josh Lind Date: Tue, 16 Dec 2014 14:21:57 -0800 Subject: [PATCH 3/4] improve condition structure for getActivities --- DOCS.md | 29 ++++++------ README.md | 4 +- src/groucho.js | 106 ++++++++++++++++++++++++++----------------- test/groucho_test.js | 52 +++++++++++---------- 4 files changed, 108 insertions(+), 83 deletions(-) diff --git a/DOCS.md b/DOCS.md index c486fb2..3931b3f 100644 --- a/DOCS.md +++ b/DOCS.md @@ -123,7 +123,7 @@ groucho.config = { To write your own features, grab browsing history and work with it. You'll need to use a little structure to define the condition, in this case: the name of the tracking group... ```javascript -$.each(groucho.getActivities({'group' : 'browsing'}), function (key, record) { +$.each(groucho.getActivities('browsing'), function (key, record) { someComparison(record.property, record.url); }); ``` @@ -282,8 +282,7 @@ $('.videos a.play').bind('click', function() { They will be stored as key/value in jStorage. But can be returned as an array, filtered down to the group specified. Remember to structure the condition. ```javascript -var condition = {'group' : 'watch'}, - myActivities = groucho.getActivities(condition); +var myActivities = groucho.getActivities('watch'); ``` ```json @@ -304,28 +303,26 @@ You can work directly with tracking activites and create your own smart function ```javascript function recentVideos(timeframe, category) { - var query = { - 'group' : 'watch', - 'property' : 'type', - 'values' : [category] - }, - myActivities = groucho.getActivities(query), + var conditions = [{'type' : [category]}], + activityList = groucho.getActivities('watch', conditions), now = new Date().getTime(), - recentList, + recentList = [], timestamp; - for (var i in myActivities) { - timestamp = myActivities[i]._key.split('.')[2]); + for (var i in activityList) { + timestamp = activityList[i]._key.split('.')[2]); if (timestamp > (now - timeframe)) { - returnRecent.push({ - 'videoTitle' : myActivities[i].videoTitle, - 'url' : myActivities[i].url + recentList.push({ + 'videoTitle' : activityList[i].videoTitle, + 'url' : activityList[i].url }); } } + + return recentList; } -$.each(recentVideos(604800, ['tutorial']), function() { +$.each(recentVideos(604800, 'tutorial'), function() { newItem = '
  • ' + this.videoTitle + '
  • '; $('ul.recentlyWatched').append(newItem); }); diff --git a/README.md b/README.md index aaec91a..c58df65 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ if (groucho.favoriteTerms.hasOwnProperty(taxonomy)) { Use page view activity tracking to dig through history and alter UX. ```javascript -var history = groucho.getActivities({'group' : 'browsing'}), +var history = groucho.getActivities('browsing'), links = $('a.promoted'), count = 0; @@ -126,7 +126,7 @@ $('.videos a.play').bind('click', function() { Retrieve activities later to personalize pages. Example swaps in the last watched video... ```javascript -var history = groucho.getActivities({'group' : 'watch'}); +var history = groucho.getActivities('watch'); if (history.length) { $.get("videos.json?id=" + history[0].videoId, function(data) { diff --git a/src/groucho.js b/src/groucho.js index 6087a40..bd15afd 100644 --- a/src/groucho.js +++ b/src/groucho.js @@ -97,7 +97,7 @@ var groucho = window.groucho || {}; */ groucho.createActivity = function createActivity(group, data) { - var results = groucho.getActivities({'group' : group}), + var results = groucho.getActivities(group), n = new Date().getTime(), diff = 0; @@ -116,83 +116,107 @@ var groucho = window.groucho || {}; /** * Access records of a specific tracking group. * - * @param {object} query - * Strucutured conditions for activity lookup: {group, property, [values]}. + * @param {string} group + * Strucutured conditions for activity lookup: {type, [conditionList]}. + * @param {array} conditions + * List of acceptable property [key/[values]] objects. * * return {array} * List of tracking localStorage entries. */ - groucho.getActivities = function getActivities(query) { + groucho.getActivities = function getActivities(type, conditionList) { - var conditions = query || {}, - group = (conditions.hasOwnProperty('group')) ? conditions.group : false, - property = (conditions.hasOwnProperty('property')) ? conditions.property : false, - values = (conditions.hasOwnProperty('values')) ? conditions.values : false, + // Optional params. + var group = type || false, + conditions = conditionList || false, groupMatch = new RegExp("^track." + group + ".", "g"), results = $.jStorage.index(), returnVals = [], record; /** - * Grab record from storage, add to returns. + * Confirm properties are of desired values. + * NOTE: String comparisons only! * - * @param string key - * Browser storage lookup key. + * @param {array} conditions + * List of acceptable property [key/[values]] objects. + * @param {string} record + * History record to check against. + * + * @return {boolean} + * Result of match check. */ - function addRecord(key) { - record = $.jStorage.get(key); - // Move key to special property. - record._key = key; - returnVals.push(record); + function checkProperties(conditions, record) { + // Check all conditions, be picky about type. + if (conditions && conditions instanceof Array) { + for (var i in conditions) { + // Confirm an acceptable value. + if (checkValues(i, conditions[i], record)) { + addRecord(record); + } + + } + } + else { + // No conditions, or wrong type-- add everything. + addRecord(record); + } } /** - * Confirm property is of desired values. - * NOTE: String comparison only! + * Confirm one of values matches the record. + * NOTE: String comparisons only! * * @param {string} property - * Name of record property. - * @param {array} values + * Property to check. + * @param {array} values * List of acceptable values. * @param {string} record - * Record value to check. + * History record to check against. * * @return {boolean} * Result of match check. */ - function checkProperty(property, values, record) { - // Confirm conditions required. - if (property && values) { - // Picky about types. - if (typeof property === 'string' && values instanceof Array) { - for (var i in values) { - // Confirm an acceptable value. - if (record.hasOwnProperty(property) && record.property === values[i]) { - addRecord(record); - // Only need one match per value set. - break; - } + function checkValues(property, values, record) { + // Check all values, be picky about type. + if (values instanceof Array) { + for (var i in values) { + // Confirm an acceptable value. + if (record.hasOwnProperty(property) && record.property === values[i]) { + addRecord(record); + // Only need one match per value set. + break; } } } - else { - // Property or values not in conditions. - addRecord(record); - } } + /** + * Grab record from storage, add to returns. + * + * @param string key + * Browser storage lookup key. + */ + function addRecord(key) { + record = $.jStorage.get(key); + // Move key to special property. + record._key = key; + returnVals.push(record); + } + + // Look through storage index. for (var i in results) { // Remove unwanted types and return records. if (group) { if (results[i].match(groupMatch) !== null) { - // Move on to checking property or just add. - checkProperty(property, values, results[i]); + // Move on to checking conditions (potentially just add it). + checkProperties(conditions, results[i]); } } else { // Just check property or just add. - checkProperty(property, values, results[i]); + checkProperties(conditions, results[i]); } } @@ -213,7 +237,7 @@ var groucho = window.groucho || {}; */ groucho.getFavoriteTerms = function getFavoriteTerms(vocab, returnAll, threshold) { - var results = groucho.getActivities({'group' : 'browsing'}), + var results = groucho.getActivities('browsing'), termProp = groucho.config.taxonomyProperty, pages = [], returnTerms = {}, diff --git a/test/groucho_test.js b/test/groucho_test.js index 07ab8ae..013a0cd 100644 --- a/test/groucho_test.js +++ b/test/groucho_test.js @@ -84,7 +84,7 @@ }); test('Pageview activities', function() { - var myResults = groucho.getActivities({'group' : 'browsing'}), + var myResults = groucho.getActivities('browsing'), fakeData = { 'meainingLess': 'info' }, timeout = 0; @@ -110,7 +110,7 @@ history.pushState('', 'New Page Title', window.location + '#another-page'); // Manually create another browsing record. groucho.trackHit(); - myResults = groucho.getActivities({'group' : 'browsing'}); + myResults = groucho.getActivities('browsing'); strictEqual( myResults.length, 2, @@ -137,7 +137,7 @@ setTimeout(function () { strictEqual( - groucho.getActivities({'group' : 'fake_thing'}).length, + groucho.getActivities('fake_thing').length, groucho.config.trackExtent, 'Tracking activities are kept within the configured extent' ); @@ -165,48 +165,52 @@ groucho.getActivities(); - groucho.getActivities({ - 'group' : 'fake_thing', - }); + groucho.getActivities('fake_thing'); - groucho.getActivities({ - 'group' : 'wrong', + groucho.getActivities('wrong'); + + groucho.getActivities( + 'fake_thing', + [{'entityBundle'}] }); groucho.getActivities({ - 'group' : 'fake_thing', - 'property' : 'entityBundle' + 'fake_thing', + [{'entityBundle' : 'article'}] }); groucho.getActivities({ - 'group' : 'fake_thing', - 'value' : ['article'] + 'fake_thing', + [{entityBundle' : ['article']}] }); groucho.getActivities({ - 'group' : 'fake_thing', - 'property' : 'entityBundle', - 'value' : 'article' + 'fake_thing', + [{'entityBundle' : ['wrong', 'article']}} }); groucho.getActivities({ - 'group' : 'fake_thing', - 'property' : 'entityBundle', - 'value' : ['article'] + 'fake_thing', + ['entityBundle' : ['wrong']}] }); groucho.getActivities({ - 'group' : 'fake_thing', - 'property' : 'entityBundle', - 'value' : ['wrong', 'article'] + 'fake_thing', + [ + {entityBundle' : ['article']}, + {entityBundle' : ['article']} + ] }); groucho.getActivities({ - 'group' : 'fake_thing', - 'property' : 'entityBundle', - 'value' : ['wrong'] + 'fake_thing', + [ + {entityBundle' : ['article']}, + {entityBundle' : ['profile', 'blog']} + ] }); */ + }); module('Favorites'); From 647145639862a7a77775440007bf1557b1d8f63b Mon Sep 17 00:00:00 2001 From: Josh Lind Date: Wed, 4 Feb 2015 22:24:47 -0800 Subject: [PATCH 4/4] stub tests for coverage --- test/groucho_test.js | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/test/groucho_test.js b/test/groucho_test.js index 013a0cd..3f2782f 100644 --- a/test/groucho_test.js +++ b/test/groucho_test.js @@ -161,6 +161,65 @@ //@todo Confirm granular activity request work. test('Activity retrieval', 0, function() { + // Mock functions. + var counters = { + 'checkProperties': 0, + 'checkValues': 0, + 'addRecord': 0 + }; + groucho.getActivities.checkProperties = function() { + counters[this.name]++ + }; + groucho.getActivities.checkValues = function() { + counters[this.name]++ + }; + groucho.getActivities.addRecord = function() { + counters[this.name]++ + }; + + // Create activities! + groucho.createActivity('testThingy', { + 'neato' : 'definately', + 'yep' : 'probably' + }); + groucho.createActivity('testStuff', { + 'neato' : 'definately', + 'yep' : 'probably' + }); + groucho.createActivity('testThingy', { + 'neato' : 'unclear' + }); + groucho.createActivity('testThingy', { + 'wow' : 'indeed', + 'yep' : 'probably' + }); + + // Tests... + groucho.getActivities('testThingy'); + + groucho.getActivities('testStuff'); + + groucho.getActivities('testThingy', [ + {'neato' : ['definately']} + ]); + + groucho.getActivities('testThingy', [ + {'neato' : ['definately', 'unclear']} + ]); + + groucho.getActivities('testThingy', [ + {'neato' : ['definately']}, + {'wow' : ['indeed']} + ]); + + groucho.createActivity('testStuff', [ + {'neato' : ['unclear']}, + {'neato' : ['definately']} + ]); + + + + /* groucho.getActivities();