From 3cffa3a275059fb4b4bbbc793e956ef4ec60846a Mon Sep 17 00:00:00 2001 From: Keegan Date: Wed, 15 Jun 2016 21:50:36 -0700 Subject: [PATCH] Send messageKeys down to appMessage in the new format --- gulpfile.js | 8 +++-- index.js | 22 ++++++++---- test/fixture.js | 52 ++++++++++++++++++++++++++++ test/karma.conf.js | 7 +++- test/spec/index.js | 86 +++++++++++++++++++++++++++++++++++++++------- 5 files changed, 152 insertions(+), 23 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 80cec06..1130469 100755 --- a/gulpfile.js +++ b/gulpfile.js @@ -15,6 +15,7 @@ var uglify = require('gulp-uglify'); var sassify = require('sassify'); var autoprefixify = require('./src/scripts/vendor/autoprefixify'); var insert = require('gulp-insert'); +var clayPackage = require('./package.json'); var sassIncludePaths = [].concat( require('bourbon').includePaths, @@ -37,7 +38,7 @@ var autoprefixerOptions = { var stringifyOptions = ['.html', '.tpl']; var versionMessage = '/* Clay - https://github.com/pebble/clay - Version: ' + - require('./package.json').version + + clayPackage.version + ' - Build Date: ' + new Date().toISOString() + ' */\n'; gulp.task('clean-js', function() { @@ -84,13 +85,14 @@ gulp.task('inlineHtml', ['js', 'sass'], function() { gulp.task('clay', ['inlineHtml'], function() { return browserify('index.js', { debug: false, - standalone: 'clay' + standalone: clayPackage.name }) .transform('deamdify') .transform(stringify(stringifyOptions)) .transform(sassify, sassifyOptions) .transform(autoprefixify, autoprefixerOptions) - .require(require.resolve('./index'), {expose: 'pebble-clay'}) + .require(require.resolve('./index'), {expose: clayPackage.name}) + .exclude('message_keys') .bundle() .pipe(source('index.js')) .pipe(buffer()) diff --git a/index.js b/index.js index 19d143b..e0f7210 100755 --- a/index.js +++ b/index.js @@ -5,6 +5,7 @@ var toSource = require('tosource'); var standardComponents = require('./src/scripts/components'); var deepcopy = require('deepcopy/build/deepcopy.min'); var version = require('./package.json').version; +var messageKeys = require('message_keys'); /** * @param {Array} config - the Clay config @@ -209,7 +210,9 @@ Clay.prototype.getSettings = function(response, convert) { localStorage.setItem('clay-settings', JSON.stringify(settingsStorage)); - return convert === false ? settings : Clay.prepareSettingsForAppMessage(settings); + return convert === false ? + settings : + Clay.prepareSettingsForAppMessage(settings, messageKeys); }; /** @@ -265,9 +268,6 @@ Clay.prepareForAppMessage = function(val) { val.forEach(function(item) { var itemConverted = Clay.prepareForAppMessage(item); result.push(itemConverted); - if (typeof itemConverted === 'string') { - result.push(0); - } }); } else if (typeof val === 'object' && val) { if (typeof val.value === 'number') { @@ -293,15 +293,23 @@ Clay.prepareForAppMessage = function(val) { /** * Converts a Clay settings dict into one that is compatible with - * Pebble.sendAppMessage(); + * Pebble.sendAppMessage(); It also uses the provided messageKeys to correctly + * assign arrays into individual keys * @see {prepareForAppMessage} * @param {Object} settings + * @param {Object} messageKeys * @returns {{}} */ -Clay.prepareSettingsForAppMessage = function(settings) { +Clay.prepareSettingsForAppMessage = function(settings, messageKeys) { var result = {}; Object.keys(settings).forEach(function(key) { - result[key] = Clay.prepareForAppMessage(settings[key]); + var messageKey = messageKeys[key]; + var settingArr = Clay.prepareForAppMessage(settings[key]); + settingArr = Array.isArray(settingArr) ? settingArr : [settingArr]; + + settingArr.forEach(function(setting, index) { + result[messageKey + index] = setting; + }); }); return result; }; diff --git a/test/fixture.js b/test/fixture.js index 06582ee..d23d197 100644 --- a/test/fixture.js +++ b/test/fixture.js @@ -126,3 +126,55 @@ module.exports.clay = function(config, customFn, options, destroyLocalStorage) { } return new Clay(config, customFn, options); }; + +/** + * @param {Array} keys + * @return {Object} + */ +module.exports.messageKeys = function(keys) { + var counter = 10000; + var result = {}; + + keys.forEach(function(key) { + var matches = key.match(/(.+?)(?:\[(\d*)\])?$/); + var parsedKey = matches[1]; + var length = parseInt(matches[2] || 1, 10); + + result[parsedKey] = counter; + + counter += length; + }); + + return result; +}; + +/** + * @param {Object} obj + * @returns {Array} + */ +module.exports.messageKeysObjToArray = function(obj) { + return Object.keys(obj).map(function(key) { + return Array.isArray(obj[key]) ? + key + '[' + obj[key].length + ']' : + key; + }); +}; + +/** + * @param {Object} expected + * @return {Object} + */ +module.exports.messageKeysExpected = function(expected) { + var result = {}; + var messageKeys = module.exports.messageKeysObjToArray(expected); + messageKeys = module.exports.messageKeys(messageKeys); + + Object.keys(expected).forEach(function(key) { + var expectedVal = Array.isArray(expected[key]) ? expected[key] : [expected[key]]; + expectedVal.forEach(function(val, index) { + result[messageKeys[key] + index] = val; + }); + }); + + return result; +}; diff --git a/test/karma.conf.js b/test/karma.conf.js index ff82618..31a3c23 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -53,7 +53,12 @@ module.exports = function(config) { ] } ] - ] + ], + configure: function(bundle) { + bundle.on('prebundle', function() { + bundle.ignore('message_keys'); + }); + } }, // list of files / patterns to load in the browser diff --git a/test/spec/index.js b/test/spec/index.js index c0ebb2d..c725d91 100644 --- a/test/spec/index.js +++ b/test/spec/index.js @@ -23,6 +23,24 @@ function stubPebble() { }; } +/** + * @param {Array} keys + * @return {Object} + */ +function stubMessageKeys(keys) { + var messageKeys = require('message_keys'); + Object.keys(messageKeys).forEach(function(key) { + delete messageKeys[key]; + }); + + var newKeys = fixture.messageKeys(keys); + Object.keys(newKeys).forEach(function(key) { + messageKeys[key] = newKeys[key]; + }); + + return messageKeys; +} + describe('Clay', function() { describe('Clay constructor', function() { it('throws if the config is not an array', function() { @@ -89,12 +107,16 @@ describe('Clay', function() { stubPebble(); fixture.clay([]); var logStub = sinon.stub(console, 'log'); + var expected = {someSetting: 'value'}; + + stubMessageKeys(fixture.messageKeysObjToArray(expected)); Pebble.addEventListener .withArgs('webviewclosed') - .callArgWith(1, { response: '%7B%22messageKey%22%3A%22value%22%7D' }); + .callArgWith(1, {response: encodeURIComponent(JSON.stringify(expected))}); + var expectedAppMessage = fixture.messageKeysExpected(expected); assert(Pebble.addEventListener.calledWith('webviewclosed')); - assert(Pebble.sendAppMessage.calledWith({ messageKey: 'value' })); + assert(Pebble.sendAppMessage.calledWith(expectedAppMessage)); Pebble.sendAppMessage.callArg(1); assert(logStub.calledWith('Sent config data to Pebble')); @@ -259,9 +281,15 @@ describe('Clay', function() { key1: 'value1', key2: 'value2' }; + + stubMessageKeys(fixture.messageKeysObjToArray(expected)); + var result = clay.getSettings(settings); - assert.equal(localStorage.getItem('clay-settings'), JSON.stringify(expected)); - assert.deepEqual(result, expected); + assert.equal( + localStorage.getItem('clay-settings'), + JSON.stringify(expected) + ); + assert.deepEqual(result, fixture.messageKeysExpected(expected)); }); it('it writes to localStorage and returns the data when input is not encoded', @@ -275,9 +303,15 @@ describe('Clay', function() { key1: 'value1', key2: 'value2%7Dbreaks' }; + + stubMessageKeys(fixture.messageKeysObjToArray(expected)); + var result = clay.getSettings(settings); - assert.equal(localStorage.getItem('clay-settings'), JSON.stringify(expected)); - assert.deepEqual(result, expected); + assert.equal( + localStorage.getItem('clay-settings'), + JSON.stringify(expected) + ); + assert.deepEqual(result, fixture.messageKeysExpected(expected)); }); it('does not store the response if it is invalid JSON and logs an error', @@ -314,7 +348,7 @@ describe('Clay', function() { test1: 0, test2: 'val-2', test3: 1, - test4: ['cb-1', 0, 'cb-3', 0], + test4: ['cb-1', 'cb-3'], test5: 12345, test6: [1, 2, 3, 4], test7: [1, 0, 1], @@ -322,7 +356,12 @@ describe('Clay', function() { test9: [10, 20, 30, 40] }; - assert.deepEqual(clay.getSettings(response), expected); + stubMessageKeys(fixture.messageKeysObjToArray(expected)); + + assert.deepEqual( + clay.getSettings(response), + fixture.messageKeysExpected(expected) + ); }); it('does not prepare the settings for sendAppMessage if convert is false', @@ -413,6 +452,16 @@ describe('Clay', function() { }); describe('.prepareForAppMessage', function() { + it('converts an array correctly when array contains strings', function() { + assert.deepEqual( + Clay.prepareForAppMessage(['one', 'two', 'three']), + ['one', 'two', 'three'] + ); + assert.deepEqual( + Clay.prepareForAppMessage([{value: 'one'}, 'two', 'three']), + ['one', 'two', 'three']); + }); + it('converts an array correctly when array contains numbers', function() { assert.deepEqual(Clay.prepareForAppMessage([1, 2, 3]), [1, 2, 3]); assert.deepEqual(Clay.prepareForAppMessage( @@ -478,6 +527,17 @@ describe('Clay', function() { describe('.prepareSettingsForAppMessage', function() { it('converts the settings correctly', function() { + var messageKeys = fixture.messageKeys([ + 'test1', + 'test2', + 'test3', + 'test4[2]', + 'test5', + 'test6[4]', + 'test7[3]', + 'test8' + ]); + var settings = { test1: false, test2: 'val-2', @@ -491,18 +551,20 @@ describe('Clay', function() { value: 12.34 } }; - var expected = { + + var expected = fixture.messageKeysExpected({ test1: 0, test2: 'val-2', test3: 1, - test4: ['cb-1', 0, 'cb-3', 0], + test4: ['cb-1', 'cb-3'], test5: 12345, test6: [1, 2, 3, 4], test7: [1, 0, 1], test8: 1234 - }; + }); - assert.deepEqual(Clay.prepareSettingsForAppMessage(settings), expected); + var result = Clay.prepareSettingsForAppMessage(settings, messageKeys); + assert.deepEqual(result, expected); }); }); });