From 35a1fe73130e082ad1bc9597b1baa3c5b25c3c13 Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sat, 22 Feb 2020 19:43:01 -0300 Subject: [PATCH 01/13] Update index.js --- src/index.js | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 376865da..599778a5 100644 --- a/src/index.js +++ b/src/index.js @@ -23,7 +23,7 @@ export function getField(state) { } export function updateField(state, { path, value }) { - path.split(/[.[\]]+/).reduce((prev, key, index, array) => { + path.split(/[.[\]]+/).filter((x) => x ).reduce((prev, key, index, array) => { if (array.length === index + 1) { // eslint-disable-next-line no-param-reassign prev[key] = value; @@ -91,6 +91,49 @@ export const mapMultiRowFields = normalizeNamespace(( }, {}); }); +export const mapRowFields = normalizeNamespace(( + namespace, + paths, + getterType, + mutationType, +) => { + const pathsObject = Array.isArray(paths) ? arrayToObject(paths) : paths; + + return Object.keys(pathsObject).reduce((entries, key) => { + const path = pathsObject[key]; + + // eslint-disable-next-line no-param-reassign + entries[key] = { + get() { + const store = this.$store; + const row = store.getters[getterType](path); + if(!row) return {}; + + return Object.keys(row).reduce((prev, fieldKey) => { + const fieldPath = `${path}.${fieldKey}` + return Object.defineProperty(prev, fieldKey, { + get() { + return store.getters[getterType](fieldPath); + }, + set(value) { + store.commit(mutationType, { path: fieldPath, value }); + }, + }); + }, {}); + }, + set(value){ + var store = this.$store; + store.commit(mutationType, { + path, + value + }); + } + }; + + return entries; + }, {}); +}); + export const createHelpers = ({ getterType, mutationType }) => ({ [getterType]: getField, [mutationType]: updateField, From 81434419a7be296aed5982b6158ddb7fca1d23b1 Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sat, 22 Feb 2020 19:50:19 -0300 Subject: [PATCH 02/13] mapRow --- CODE_OF_CONDUCT.md | 0 CONTRIBUTING.md | 0 LICENSE | 0 README.md | 0 babel.config.js | 0 package.json | 0 rollup.config.js | 0 src/index.js | 0 src/index.spec.js | 0 src/lib/array-to-object.js | 0 src/lib/array-to-object.spec.js | 0 test/module-namespaced-double.test.js | 0 test/module-namespaced-inline.test.js | 0 test/module-namespaced.test.js | 0 test/module.test.js | 0 test/multi-row.test.js | 0 test/nested-store.test.js | 0 test/packaged.test.js | 0 test/utils/component.js | 0 test/utils/fake-publish.sh | 0 test/utils/store.js | 0 yarn.lock | 0 22 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 CODE_OF_CONDUCT.md mode change 100644 => 100755 CONTRIBUTING.md mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md mode change 100644 => 100755 babel.config.js mode change 100644 => 100755 package.json mode change 100644 => 100755 rollup.config.js mode change 100644 => 100755 src/index.js mode change 100644 => 100755 src/index.spec.js mode change 100644 => 100755 src/lib/array-to-object.js mode change 100644 => 100755 src/lib/array-to-object.spec.js mode change 100644 => 100755 test/module-namespaced-double.test.js mode change 100644 => 100755 test/module-namespaced-inline.test.js mode change 100644 => 100755 test/module-namespaced.test.js mode change 100644 => 100755 test/module.test.js mode change 100644 => 100755 test/multi-row.test.js mode change 100644 => 100755 test/nested-store.test.js mode change 100644 => 100755 test/packaged.test.js mode change 100644 => 100755 test/utils/component.js mode change 100644 => 100755 test/utils/fake-publish.sh mode change 100644 => 100755 test/utils/store.js mode change 100644 => 100755 yarn.lock diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md old mode 100644 new mode 100755 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/babel.config.js b/babel.config.js old mode 100644 new mode 100755 diff --git a/package.json b/package.json old mode 100644 new mode 100755 diff --git a/rollup.config.js b/rollup.config.js old mode 100644 new mode 100755 diff --git a/src/index.js b/src/index.js old mode 100644 new mode 100755 diff --git a/src/index.spec.js b/src/index.spec.js old mode 100644 new mode 100755 diff --git a/src/lib/array-to-object.js b/src/lib/array-to-object.js old mode 100644 new mode 100755 diff --git a/src/lib/array-to-object.spec.js b/src/lib/array-to-object.spec.js old mode 100644 new mode 100755 diff --git a/test/module-namespaced-double.test.js b/test/module-namespaced-double.test.js old mode 100644 new mode 100755 diff --git a/test/module-namespaced-inline.test.js b/test/module-namespaced-inline.test.js old mode 100644 new mode 100755 diff --git a/test/module-namespaced.test.js b/test/module-namespaced.test.js old mode 100644 new mode 100755 diff --git a/test/module.test.js b/test/module.test.js old mode 100644 new mode 100755 diff --git a/test/multi-row.test.js b/test/multi-row.test.js old mode 100644 new mode 100755 diff --git a/test/nested-store.test.js b/test/nested-store.test.js old mode 100644 new mode 100755 diff --git a/test/packaged.test.js b/test/packaged.test.js old mode 100644 new mode 100755 diff --git a/test/utils/component.js b/test/utils/component.js old mode 100644 new mode 100755 diff --git a/test/utils/fake-publish.sh b/test/utils/fake-publish.sh old mode 100644 new mode 100755 diff --git a/test/utils/store.js b/test/utils/store.js old mode 100644 new mode 100755 diff --git a/yarn.lock b/yarn.lock old mode 100644 new mode 100755 From f355153b12da9057f53c31bc333db9c88a2de540 Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sun, 23 Feb 2020 00:22:53 -0300 Subject: [PATCH 03/13] tests added --- src/index.js | 3 +-- test/row.test.js | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 test/row.test.js diff --git a/src/index.js b/src/index.js index 599778a5..f70e5346 100755 --- a/src/index.js +++ b/src/index.js @@ -19,7 +19,7 @@ function normalizeNamespace(fn) { } export function getField(state) { - return path => path.split(/[.[\]]+/).reduce((prev, key) => prev[key], state); + return path => path.split(/[.[\]]+/).filter((x) => x ).reduce((prev, key) => prev[key], state); } export function updateField(state, { path, value }) { @@ -98,7 +98,6 @@ export const mapRowFields = normalizeNamespace(( mutationType, ) => { const pathsObject = Array.isArray(paths) ? arrayToObject(paths) : paths; - return Object.keys(pathsObject).reduce((entries, key) => { const path = pathsObject[key]; diff --git a/test/row.test.js b/test/row.test.js new file mode 100644 index 00000000..adc85ee2 --- /dev/null +++ b/test/row.test.js @@ -0,0 +1,69 @@ +import Vuex from 'vuex'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; + +import { mapRowFields, getField, updateField } from '../src'; + +const localVue = createLocalVue(); + +localVue.use(Vuex); + +describe(`Component initialized with row setup.`, () => { + let Component; + let store; + let wrapper; + + beforeEach(() => { + Component = { + template: ` +
+ + +
+ `, + computed: { + ...mapRowFields({user: `users[0]`}), + }, + }; + + store = new Vuex.Store({ + state: { + users: [ + { + name: `Foo`, + email: `foo@foo.com`, + }, + { + name: `Bar`, + email: `bar@bar.com`, + }, + ], + }, + getters: { + getField, + }, + mutations: { + updateField, + }, + }); + + wrapper = shallowMount(Component, { localVue, store }); + }); + + test(`It should render the component.`, () => { + expect(wrapper.exists()).toBe(true); + }); + + test(`It should update field values when the store is updated.`, () => { + store.state.users[0].name = `New Name`; + store.state.users[0].email = `new@email.com`; + + expect(wrapper.find(`input`).element.value).toBe(`New Name`); + }); + + test(`It should update the store when the field values are updated.`, () => { + wrapper.find(`input`).element.value = `New Name`; + wrapper.find(`input`).trigger(`input`); + + expect(store.state.users[0].name).toBe(`New Name`); + }); +}); From 58b38c4a30c8f8ad3e36b3baf82ab234606933de Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sun, 23 Feb 2020 00:43:39 -0300 Subject: [PATCH 04/13] Update index.js --- src/index.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/index.js b/src/index.js index f70e5346..62e1abc2 100755 --- a/src/index.js +++ b/src/index.js @@ -119,13 +119,6 @@ export const mapRowFields = normalizeNamespace(( }, }); }, {}); - }, - set(value){ - var store = this.$store; - store.commit(mutationType, { - path, - value - }); } }; From aa081952340422dc018e3648d4607195260123d0 Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sun, 23 Feb 2020 01:59:43 -0300 Subject: [PATCH 05/13] object or string on multiple paths --- src/lib/array-to-object.js | 1 + test/row.test.js | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/array-to-object.js b/src/lib/array-to-object.js index 7528582e..2f77c2cc 100755 --- a/src/lib/array-to-object.js +++ b/src/lib/array-to-object.js @@ -1,5 +1,6 @@ export default function arrayToObject(fields = []) { return fields.reduce((prev, path) => { + if(typeof path === "object") return Object.assign(prev, path); const key = path.split(`.`).slice(-1)[0]; if (prev[key]) { diff --git a/test/row.test.js b/test/row.test.js index adc85ee2..38922d35 100644 --- a/test/row.test.js +++ b/test/row.test.js @@ -18,10 +18,13 @@ describe(`Component initialized with row setup.`, () => {
+
+          {{noUser}}
+          
`, computed: { - ...mapRowFields({user: `users[0]`}), + ...mapRowFields([{user: `users[0]`}, {noUser: `users[2]`}]), }, }; From 35166a855c49964bae787f269d6c5778157a4fd7 Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sun, 23 Feb 2020 02:12:43 -0300 Subject: [PATCH 06/13] Update row.test.js --- test/row.test.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/row.test.js b/test/row.test.js index 38922d35..4279b71a 100644 --- a/test/row.test.js +++ b/test/row.test.js @@ -19,12 +19,16 @@ describe(`Component initialized with row setup.`, () => {
+          {{user1}}
+          
+
           {{noUser}}
           
`, computed: { - ...mapRowFields([{user: `users[0]`}, {noUser: `users[2]`}]), + ...mapRowFields({user: `users[0]`}), + ...mapRowFields([{user1: `users[1]`}, {noUser: `users[2]`}]), }, }; From e54385403388b4f50f3c28346096caf348e431d5 Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Tue, 25 Feb 2020 14:15:03 -0300 Subject: [PATCH 07/13] accept function on paths --- src/index.js | 12 ++++++++---- test/row.test.js | 15 ++++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/index.js b/src/index.js index 62e1abc2..4855e0c9 100755 --- a/src/index.js +++ b/src/index.js @@ -68,12 +68,13 @@ export const mapMultiRowFields = normalizeNamespace(( // eslint-disable-next-line no-param-reassign entries[key] = { get() { + let tpath = typeof path === "function" ? path.call(null, this) : path; const store = this.$store; - const rows = Object.entries(store.getters[getterType](path)); + const rows = Object.entries(store.getters[getterType](tpath)); return rows .map((fieldsObject, index) => Object.keys(fieldsObject[1]).reduce((prev, fieldKey) => { - const fieldPath = `${path}[${fieldsObject[0]}].${fieldKey}`; + const fieldPath = `${tpath}[${fieldsObject[0]}].${fieldKey}`; return Object.defineProperty(prev, fieldKey, { get() { @@ -98,18 +99,21 @@ export const mapRowFields = normalizeNamespace(( mutationType, ) => { const pathsObject = Array.isArray(paths) ? arrayToObject(paths) : paths; + // console.log(pathsObject); return Object.keys(pathsObject).reduce((entries, key) => { const path = pathsObject[key]; // eslint-disable-next-line no-param-reassign entries[key] = { get() { + let tpath = typeof path === "function" ? path.call(null, this) : path; const store = this.$store; - const row = store.getters[getterType](path); + const row = store.getters[getterType](tpath); + if(!row) return {}; return Object.keys(row).reduce((prev, fieldKey) => { - const fieldPath = `${path}.${fieldKey}` + const fieldPath = `${tpath}.${fieldKey}` return Object.defineProperty(prev, fieldKey, { get() { return store.getters[getterType](fieldPath); diff --git a/test/row.test.js b/test/row.test.js index 4279b71a..79206dc7 100644 --- a/test/row.test.js +++ b/test/row.test.js @@ -16,19 +16,24 @@ describe(`Component initialized with row setup.`, () => { Component = { template: `
- - + +
-          {{user1}}
+          {{user0}}
           
           {{noUser}}
           
`, + data() { + return { + ative_room: '0' + }; + }, computed: { - ...mapRowFields({user: `users[0]`}), - ...mapRowFields([{user1: `users[1]`}, {noUser: `users[2]`}]), + ...mapRowFields([{userFun: (c) => { return `users[${c.ative_room}]`; }}, {user0: `users[0]`}]), + ...mapRowFields({noUser: `users[2]`}), }, }; From 21aebf704de16db6586b6bfe8ce4be6f4018a9da Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Tue, 25 Feb 2020 14:26:18 -0300 Subject: [PATCH 08/13] test --- src/index.js | 6 ------ test/multi-row.test.js | 6 +++++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/index.js b/src/index.js index 4855e0c9..b175975f 100755 --- a/src/index.js +++ b/src/index.js @@ -46,7 +46,6 @@ export const mapFields = normalizeNamespace((namespace, fields, getterType, muta this.$store.commit(mutationType, { path, value }); }, }; - // eslint-disable-next-line no-param-reassign prev[key] = field; @@ -64,7 +63,6 @@ export const mapMultiRowFields = normalizeNamespace(( return Object.keys(pathsObject).reduce((entries, key) => { const path = pathsObject[key]; - // eslint-disable-next-line no-param-reassign entries[key] = { get() { @@ -87,7 +85,6 @@ export const mapMultiRowFields = normalizeNamespace(( }, {})); }, }; - return entries; }, {}); }); @@ -99,10 +96,8 @@ export const mapRowFields = normalizeNamespace(( mutationType, ) => { const pathsObject = Array.isArray(paths) ? arrayToObject(paths) : paths; - // console.log(pathsObject); return Object.keys(pathsObject).reduce((entries, key) => { const path = pathsObject[key]; - // eslint-disable-next-line no-param-reassign entries[key] = { get() { @@ -125,7 +120,6 @@ export const mapRowFields = normalizeNamespace(( }, {}); } }; - return entries; }, {}); }); diff --git a/test/multi-row.test.js b/test/multi-row.test.js index 3cfa43ee..30953972 100755 --- a/test/multi-row.test.js +++ b/test/multi-row.test.js @@ -20,10 +20,14 @@ describe(`Component initialized with multi row setup.`, () => { +
+ + +
`, computed: { - ...mapMultiRowFields([`users`]), + ...mapMultiRowFields([`users`, { usersfun: () => { return 'users'; }}]), }, }; From c3fc1dc01103d494a7f317c11c096712e3c3e77d Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sat, 9 May 2020 01:27:51 -0300 Subject: [PATCH 09/13] helpers --- src/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/index.js b/src/index.js index da9abf80..6cddebc0 100755 --- a/src/index.js +++ b/src/index.js @@ -143,4 +143,10 @@ export const createHelpers = ({ getterType, mutationType }) => ({ getterType, mutationType, )), + mapRowFields: normalizeNamespace((namespace, paths) => mapRowFields( + namespace, + paths, + getterType, + mutationType, + )), }); From 8acbd901981564ee5c6909330d1a05b27149beea Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sat, 9 May 2020 12:42:12 -0300 Subject: [PATCH 10/13] Revert "mapRow" This reverts commit 81434419a7be296aed5982b6158ddb7fca1d23b1. --- CODE_OF_CONDUCT.md | 0 CONTRIBUTING.md | 0 LICENSE | 0 README.md | 0 babel.config.js | 0 package.json | 0 rollup.config.js | 0 src/index.js | 0 src/index.spec.js | 0 src/lib/array-to-object.js | 0 src/lib/array-to-object.spec.js | 0 test/module-namespaced-double.test.js | 0 test/module-namespaced-inline.test.js | 0 test/module-namespaced.test.js | 0 test/module.test.js | 0 test/multi-row.test.js | 0 test/nested-store.test.js | 0 test/packaged.test.js | 0 test/utils/component.js | 0 test/utils/fake-publish.sh | 0 test/utils/store.js | 0 yarn.lock | 0 22 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 CODE_OF_CONDUCT.md mode change 100755 => 100644 CONTRIBUTING.md mode change 100755 => 100644 LICENSE mode change 100755 => 100644 README.md mode change 100755 => 100644 babel.config.js mode change 100755 => 100644 package.json mode change 100755 => 100644 rollup.config.js mode change 100755 => 100644 src/index.js mode change 100755 => 100644 src/index.spec.js mode change 100755 => 100644 src/lib/array-to-object.js mode change 100755 => 100644 src/lib/array-to-object.spec.js mode change 100755 => 100644 test/module-namespaced-double.test.js mode change 100755 => 100644 test/module-namespaced-inline.test.js mode change 100755 => 100644 test/module-namespaced.test.js mode change 100755 => 100644 test/module.test.js mode change 100755 => 100644 test/multi-row.test.js mode change 100755 => 100644 test/nested-store.test.js mode change 100755 => 100644 test/packaged.test.js mode change 100755 => 100644 test/utils/component.js mode change 100755 => 100644 test/utils/fake-publish.sh mode change 100755 => 100644 test/utils/store.js mode change 100755 => 100644 yarn.lock diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md old mode 100755 new mode 100644 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md old mode 100755 new mode 100644 diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/babel.config.js b/babel.config.js old mode 100755 new mode 100644 diff --git a/package.json b/package.json old mode 100755 new mode 100644 diff --git a/rollup.config.js b/rollup.config.js old mode 100755 new mode 100644 diff --git a/src/index.js b/src/index.js old mode 100755 new mode 100644 diff --git a/src/index.spec.js b/src/index.spec.js old mode 100755 new mode 100644 diff --git a/src/lib/array-to-object.js b/src/lib/array-to-object.js old mode 100755 new mode 100644 diff --git a/src/lib/array-to-object.spec.js b/src/lib/array-to-object.spec.js old mode 100755 new mode 100644 diff --git a/test/module-namespaced-double.test.js b/test/module-namespaced-double.test.js old mode 100755 new mode 100644 diff --git a/test/module-namespaced-inline.test.js b/test/module-namespaced-inline.test.js old mode 100755 new mode 100644 diff --git a/test/module-namespaced.test.js b/test/module-namespaced.test.js old mode 100755 new mode 100644 diff --git a/test/module.test.js b/test/module.test.js old mode 100755 new mode 100644 diff --git a/test/multi-row.test.js b/test/multi-row.test.js old mode 100755 new mode 100644 diff --git a/test/nested-store.test.js b/test/nested-store.test.js old mode 100755 new mode 100644 diff --git a/test/packaged.test.js b/test/packaged.test.js old mode 100755 new mode 100644 diff --git a/test/utils/component.js b/test/utils/component.js old mode 100755 new mode 100644 diff --git a/test/utils/fake-publish.sh b/test/utils/fake-publish.sh old mode 100755 new mode 100644 diff --git a/test/utils/store.js b/test/utils/store.js old mode 100755 new mode 100644 diff --git a/yarn.lock b/yarn.lock old mode 100755 new mode 100644 From 68153780888d87eee9f072702ce2e2622b977b6c Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sat, 9 May 2020 16:07:06 -0300 Subject: [PATCH 11/13] eslint and helper coverage --- src/index.js | 42 +++++++++++++++++++++----------------- src/lib/array-to-object.js | 3 ++- test/multi-row.test.js | 2 +- test/row.test.js | 7 ++++++- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/index.js b/src/index.js index 6cddebc0..ae9147ff 100644 --- a/src/index.js +++ b/src/index.js @@ -23,11 +23,11 @@ function normalizeNamespace(fn) { } export function getField(state) { - return path => path.split(/[.[\]]+/).filter((x) => x ).reduce((prev, key) => prev[key], state); + return path => path.split(/[.[\]]+/).filter(x => x).reduce((prev, key) => prev[key], state); } export function updateField(state, { path, value }) { - path.split(/[.[\]]+/).filter((x) => x ).reduce((prev, key, index, array) => { + path.split(/[.[\]]+/).filter(x => x).reduce((prev, key, index, array) => { if (array.length === index + 1) { // eslint-disable-next-line no-param-reassign prev[key] = value; @@ -50,6 +50,7 @@ export const mapFields = normalizeNamespace((namespace, fields, getterType, muta this.$store.commit(mutationType, { path, value }); }, }; + // eslint-disable-next-line no-param-reassign prev[key] = field; @@ -67,16 +68,17 @@ export const mapMultiRowFields = normalizeNamespace(( return Object.keys(pathsObject).reduce((entries, key) => { const path = pathsObject[key]; + // eslint-disable-next-line no-param-reassign entries[key] = { get() { - let tpath = typeof path === "function" ? path.call(null, this) : path; + const tpath = typeof path === `function` ? path.call(null, this) : path; const store = this.$store; - const rows = objectEntries(store.getters[getterType](path)); + const rows = objectEntries(store.getters[getterType](tpath)); return rows .map(fieldsObject => Object.keys(fieldsObject[1]).reduce((prev, fieldKey) => { - const fieldPath = `${path}[${fieldsObject[0]}].${fieldKey}`; + const fieldPath = `${tpath}[${fieldsObject[0]}].${fieldKey}`; return Object.defineProperty(prev, fieldKey, { get() { @@ -89,6 +91,7 @@ export const mapMultiRowFields = normalizeNamespace(( }, {})); }, }; + return entries; }, {}); }); @@ -105,25 +108,26 @@ export const mapRowFields = normalizeNamespace(( // eslint-disable-next-line no-param-reassign entries[key] = { get() { - let tpath = typeof path === "function" ? path.call(null, this) : path; + const tpath = typeof path === `function` ? path.call(null, this) : path; const store = this.$store; const row = store.getters[getterType](tpath); - - if(!row) return {}; + + if (!row) return {}; return Object.keys(row).reduce((prev, fieldKey) => { - const fieldPath = `${tpath}.${fieldKey}` - return Object.defineProperty(prev, fieldKey, { - get() { - return store.getters[getterType](fieldPath); - }, - set(value) { - store.commit(mutationType, { path: fieldPath, value }); - }, - }); - }, {}); - } + const fieldPath = `${tpath}.${fieldKey}`; + return Object.defineProperty(prev, fieldKey, { + get() { + return store.getters[getterType](fieldPath); + }, + set(value) { + store.commit(mutationType, { path: fieldPath, value }); + }, + }); + }, {}); + }, }; + return entries; }, {}); }); diff --git a/src/lib/array-to-object.js b/src/lib/array-to-object.js index 2f77c2cc..452098cb 100644 --- a/src/lib/array-to-object.js +++ b/src/lib/array-to-object.js @@ -1,6 +1,7 @@ export default function arrayToObject(fields = []) { return fields.reduce((prev, path) => { - if(typeof path === "object") return Object.assign(prev, path); + if (typeof path === `object`) return { ...prev, ...path }; + const key = path.split(`.`).slice(-1)[0]; if (prev[key]) { diff --git a/test/multi-row.test.js b/test/multi-row.test.js index 30953972..441b8269 100644 --- a/test/multi-row.test.js +++ b/test/multi-row.test.js @@ -27,7 +27,7 @@ describe(`Component initialized with multi row setup.`, () => { `, computed: { - ...mapMultiRowFields([`users`, { usersfun: () => { return 'users'; }}]), + ...mapMultiRowFields([`users`, { usersfun: () => `users` }}]), }, }; diff --git a/test/row.test.js b/test/row.test.js index 79206dc7..987eedf1 100644 --- a/test/row.test.js +++ b/test/row.test.js @@ -1,12 +1,17 @@ import Vuex from 'vuex'; import { createLocalVue, shallowMount } from '@vue/test-utils'; -import { mapRowFields, getField, updateField } from '../src'; +import { createHelpers, getField, updateField } from '../src'; const localVue = createLocalVue(); localVue.use(Vuex); +const { mapRowFields } = createHelpers({ + getterType: `getField`, + mutationType: `updateField`, +}); + describe(`Component initialized with row setup.`, () => { let Component; let store; From 570b5d9fddcfefba3b763ab543308c485585d839 Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sat, 9 May 2020 20:02:56 -0300 Subject: [PATCH 12/13] Update multi-row.test.js --- test/multi-row.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/multi-row.test.js b/test/multi-row.test.js index 441b8269..a321156e 100644 --- a/test/multi-row.test.js +++ b/test/multi-row.test.js @@ -27,7 +27,7 @@ describe(`Component initialized with multi row setup.`, () => { `, computed: { - ...mapMultiRowFields([`users`, { usersfun: () => `users` }}]), + ...mapMultiRowFields([`users`, { usersfun: () => `users` }]), }, }; From 50e3c03903a42a9cdab92e014941faea760240c0 Mon Sep 17 00:00:00 2001 From: Guilherme Lemos Date: Sat, 9 May 2020 22:50:52 -0300 Subject: [PATCH 13/13] function param and map entire object --- src/index.js | 88 ++++++++------------ test/{row.test.js => function-param.test.js} | 23 ++--- test/map-object-properties.test.js | 86 +++++++++++++++++++ 3 files changed, 130 insertions(+), 67 deletions(-) rename test/{row.test.js => function-param.test.js} (76%) create mode 100644 test/map-object-properties.test.js diff --git a/src/index.js b/src/index.js index ae9147ff..6edfdbd3 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,10 @@ function objectEntries(obj) { return Object.keys(obj).map(key => [key, obj[key]]); } +function typeOf(obj) { + return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); +} + function normalizeNamespace(fn) { return (...params) => { // eslint-disable-next-line prefer-const @@ -37,24 +41,44 @@ export function updateField(state, { path, value }) { }, state); } -export const mapFields = normalizeNamespace((namespace, fields, getterType, mutationType) => { - const fieldsObject = Array.isArray(fields) ? arrayToObject(fields) : fields; +export const mapFields = normalizeNamespace(( + namespace, + paths, + getterType, + mutationType, +) => { + const pathsObject = Array.isArray(paths) ? arrayToObject(paths) : paths; + return Object.keys(pathsObject).reduce((entries, key) => { + const path = pathsObject[key]; - return Object.keys(fieldsObject).reduce((prev, key) => { - const path = fieldsObject[key]; - const field = { + // eslint-disable-next-line no-param-reassign + entries[key] = { get() { - return this.$store.getters[getterType](path); + const tpath = typeof path === `function` ? path.call(null, this) : path; + const store = this.$store; + const row = store.getters[getterType](tpath); + + if (!row || typeOf(row) !== `object`) return row; + + return Object.keys(row).reduce((prev, fieldKey) => { + const fieldPath = `${tpath}.${fieldKey}`; + return Object.defineProperty(prev, fieldKey, { + get() { + return store.getters[getterType](fieldPath); + }, + set(value) { + store.commit(mutationType, { path: fieldPath, value }); + }, + }); + }, {}); }, set(value) { - this.$store.commit(mutationType, { path, value }); + const tpath = typeof path === `function` ? path.call(null, this) : path; + this.$store.commit(mutationType, { path: tpath, value }); }, }; - // eslint-disable-next-line no-param-reassign - prev[key] = field; - - return prev; + return entries; }, {}); }); @@ -96,42 +120,6 @@ export const mapMultiRowFields = normalizeNamespace(( }, {}); }); -export const mapRowFields = normalizeNamespace(( - namespace, - paths, - getterType, - mutationType, -) => { - const pathsObject = Array.isArray(paths) ? arrayToObject(paths) : paths; - return Object.keys(pathsObject).reduce((entries, key) => { - const path = pathsObject[key]; - // eslint-disable-next-line no-param-reassign - entries[key] = { - get() { - const tpath = typeof path === `function` ? path.call(null, this) : path; - const store = this.$store; - const row = store.getters[getterType](tpath); - - if (!row) return {}; - - return Object.keys(row).reduce((prev, fieldKey) => { - const fieldPath = `${tpath}.${fieldKey}`; - return Object.defineProperty(prev, fieldKey, { - get() { - return store.getters[getterType](fieldPath); - }, - set(value) { - store.commit(mutationType, { path: fieldPath, value }); - }, - }); - }, {}); - }, - }; - - return entries; - }, {}); -}); - export const createHelpers = ({ getterType, mutationType }) => ({ [getterType]: getField, [mutationType]: updateField, @@ -147,10 +135,4 @@ export const createHelpers = ({ getterType, mutationType }) => ({ getterType, mutationType, )), - mapRowFields: normalizeNamespace((namespace, paths) => mapRowFields( - namespace, - paths, - getterType, - mutationType, - )), }); diff --git a/test/row.test.js b/test/function-param.test.js similarity index 76% rename from test/row.test.js rename to test/function-param.test.js index 987eedf1..b93af628 100644 --- a/test/row.test.js +++ b/test/function-param.test.js @@ -7,7 +7,7 @@ const localVue = createLocalVue(); localVue.use(Vuex); -const { mapRowFields } = createHelpers({ +const { mapFields } = createHelpers({ getterType: `getField`, mutationType: `updateField`, }); @@ -18,18 +18,14 @@ describe(`Component initialized with row setup.`, () => { let wrapper; beforeEach(() => { + Component = { template: `
- - -
-          {{user0}}
-          
-
-          {{noUser}}
-          
-
+
+ +
+ `, data() { return { @@ -37,9 +33,8 @@ describe(`Component initialized with row setup.`, () => { }; }, computed: { - ...mapRowFields([{userFun: (c) => { return `users[${c.ative_room}]`; }}, {user0: `users[0]`}]), - ...mapRowFields({noUser: `users[2]`}), - }, + ...mapFields([{name: (c) => `users[${c.ative_room}].name` }]), + } }; store = new Vuex.Store({ @@ -72,7 +67,7 @@ describe(`Component initialized with row setup.`, () => { test(`It should update field values when the store is updated.`, () => { store.state.users[0].name = `New Name`; - store.state.users[0].email = `new@email.com`; + // store.state.users[0].email = `new@email.com`; expect(wrapper.find(`input`).element.value).toBe(`New Name`); }); diff --git a/test/map-object-properties.test.js b/test/map-object-properties.test.js new file mode 100644 index 00000000..1d1622c9 --- /dev/null +++ b/test/map-object-properties.test.js @@ -0,0 +1,86 @@ +import Vuex from 'vuex'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; + +import { createHelpers, getField, updateField } from '../src'; + +const localVue = createLocalVue(); + +localVue.use(Vuex); + +const { mapFields } = createHelpers({ + getterType: `getField`, + mutationType: `updateField`, +}); + +describe(`Component initialized with row setup.`, () => { + let Component; + let store; + let wrapper; + + beforeEach(() => { + + Component = { + template: ` +
+
+ + +
+
+ `, + data() { + return { + ative_room: '0' + }; + }, + computed: { + ...mapFields({user: `users[0]` }), + } + }; + + store = new Vuex.Store({ + state: { + users: [ + { + name: `Foo`, + email: `foo@foo.com`, + }, + { + name: `Bar`, + email: `bar@bar.com`, + }, + ], + }, + getters: { + getField, + }, + mutations: { + updateField, + }, + }); + + wrapper = shallowMount(Component, { localVue, store }); + }); + + test(`It should render the component.`, () => { + expect(wrapper.exists()).toBe(true); + }); + + test(`It should update field values when the store is updated.`, () => { + store.state.users[0].name = `New Name`; + store.state.users[0].email = `new@email.com`; + + expect(wrapper.find(`input`).element.value).toBe(`New Name`); + expect(wrapper.find(`input:nth-child(2)`).element.value).toBe(`new@email.com`); + }); + + test(`It should update the store when the field values are updated.`, () => { + wrapper.find(`input`).element.value = `Foo`; + wrapper.find(`input:nth-child(2)`).element.value = `foo@foo.com`; + wrapper.find(`input`).trigger(`input`); + wrapper.find(`input:nth-child(2)`).trigger(`input`); + + expect(store.state.users[0].name).toBe(`Foo`); + expect(store.state.users[0].email).toBe(`foo@foo.com`); + }); +});