From dd6fe54834b85600effd5043baa27a854ad6ce47 Mon Sep 17 00:00:00 2001 From: Keegan Date: Wed, 15 Jun 2016 23:58:41 -0700 Subject: [PATCH] allow array syntax inside of the messageKey property of a config item --- dev/config.js | 12 +++++++++++ index.js | 49 ++++++++++++++++++++++++++++++++++++------- test/fixture.js | 4 +++- test/spec/index.js | 52 +++++++++++++++++++++++++++++----------------- 4 files changed, 89 insertions(+), 28 deletions(-) diff --git a/dev/config.js b/dev/config.js index ee98c1c..c98ef72 100644 --- a/dev/config.js +++ b/dev/config.js @@ -77,6 +77,18 @@ module.exports = [ "label": "This is a Toggle", "defaultValue": false }, + { + "type": "toggle", + "messageKey": "arrayToggle[0]", + "label": "This is a Toggle", + "defaultValue": false + }, + { + "type": "toggle", + "messageKey": "arrayToggle[1]", + "label": "This is a Toggle", + "defaultValue": false + }, { "type": "color", "messageKey": "colorTest", diff --git a/index.js b/index.js index e0f7210..d245089 100755 --- a/index.js +++ b/index.js @@ -265,9 +265,8 @@ Clay.prepareForAppMessage = function(val) { if (Array.isArray(val)) { result = []; - val.forEach(function(item) { - var itemConverted = Clay.prepareForAppMessage(item); - result.push(itemConverted); + val.forEach(function(item, index) { + result[index] = Clay.prepareForAppMessage(item); }); } else if (typeof val === 'object' && val) { if (typeof val.value === 'number') { @@ -297,20 +296,54 @@ Clay.prepareForAppMessage = function(val) { * assign arrays into individual keys * @see {prepareForAppMessage} * @param {Object} settings - * @param {Object} messageKeys * @returns {{}} */ -Clay.prepareSettingsForAppMessage = function(settings, messageKeys) { - var result = {}; +Clay.prepareSettingsForAppMessage = function(settings) { + + // flatten settings + var flatSettings = {}; Object.keys(settings).forEach(function(key) { + var val = settings[key]; + var matches = key.match(/(.+?)(?:\[(\d*)\])?$/); + + if (!matches[2]) { + flatSettings[key] = val; + return; + } + + var position = parseInt(matches[2] || 0, 10); + key = matches[1]; + + if (typeof flatSettings[key] === 'undefined') { + flatSettings[key] = []; + } + + flatSettings[key][position] = val; + }); + + var result = {}; + Object.keys(flatSettings).forEach(function(key) { var messageKey = messageKeys[key]; - var settingArr = Clay.prepareForAppMessage(settings[key]); + var settingArr = Clay.prepareForAppMessage(flatSettings[key]); settingArr = Array.isArray(settingArr) ? settingArr : [settingArr]; settingArr.forEach(function(setting, index) { - result[messageKey + index] = setting; + if (typeof setting !== 'undefined') { + result[messageKey + index] = setting; + } }); }); + + // validate the settings + Object.keys(result).forEach(function(key) { + if (Array.isArray(result[key])) { + throw new Error('Clay does not support 2 dimensional arrays for item ' + + 'values. Make sure you are not attempting to use array ' + + 'syntax (eg: "myMessageKey[2]") in the messageKey for ' + + 'components that return an array, such as a checkboxgroup'); + } + }); + return result; }; diff --git a/test/fixture.js b/test/fixture.js index d23d197..83e67f9 100644 --- a/test/fixture.js +++ b/test/fixture.js @@ -172,7 +172,9 @@ module.exports.messageKeysExpected = function(expected) { 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; + if (typeof val !== 'undefined') { + result[messageKeys[key] + index] = val; + } }); }); diff --git a/test/spec/index.js b/test/spec/index.js index c725d91..b2b22c6 100644 --- a/test/spec/index.js +++ b/test/spec/index.js @@ -523,24 +523,21 @@ describe('Clay', function() { precision: undefined }), 12); }); + + it('Handles sparse arrays', function() { + var sparseArr = []; + sparseArr[1] = 'two'; + sparseArr[2] = 'three'; + assert.deepEqual(Clay.prepareForAppMessage(sparseArr), sparseArr); + }); }); 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', + 'test2[0]': 'val-1', + 'test2[1]': 'val-2', test3: true, test4: ['cb-1', 'cb-3'], test5: 12345, @@ -549,22 +546,39 @@ describe('Clay', function() { test8: { precision: 2, value: 12.34 - } + }, + 'test9[1]': 'foo' }; - var expected = fixture.messageKeysExpected({ + var expected = { test1: 0, - test2: 'val-2', + test2: ['val-1', 'val-2'], test3: 1, test4: ['cb-1', 'cb-3'], test5: 12345, test6: [1, 2, 3, 4], test7: [1, 0, 1], - test8: 1234 - }); + test8: 1234, + test9: [undefined, 'foo'] + }; - var result = Clay.prepareSettingsForAppMessage(settings, messageKeys); - assert.deepEqual(result, expected); + stubMessageKeys(fixture.messageKeysObjToArray(expected)); + + var result = Clay.prepareSettingsForAppMessage(settings); + + assert.deepEqual(result, fixture.messageKeysExpected(expected)); + }); + + it('throws if a 2 dimension array is present', function() { + var settings = { + 'test1[1]': ['bad', 'developer!'] + }; + + stubMessageKeys(['test1[2]']); + + assert.throws(function() { + Clay.prepareSettingsForAppMessage(settings); + }, /2 dimensional array/i); }); }); });