mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-10 07:02:24 +03:00
add tests for getComponentOption
This commit is contained in:
@@ -10,6 +10,7 @@ import deepmerge from 'deepmerge'
|
||||
* @param {Object} opts.component - Vue component to fetch option data from
|
||||
* @param {String} opts.option - what option to look for
|
||||
* @param {Boolean} opts.deep - look for data in child components as well?
|
||||
* @param {Function} opts.arrayMerge - how should arrays be merged?
|
||||
* @param {Object} [result={}] - result so far
|
||||
* @return {Object} - final aggregated result
|
||||
*/
|
||||
@@ -18,32 +19,35 @@ export default function getComponentOption (opts, result = {}) {
|
||||
const { $options } = component
|
||||
|
||||
// only collect option data if it exists
|
||||
if ($options[option]) {
|
||||
if (typeof $options[option] !== 'undefined' && $options[option] !== null) {
|
||||
const data = $options[option]
|
||||
|
||||
// TODO: check data is plain object, throw if not
|
||||
|
||||
// bind context of option methods (if any) to this component
|
||||
for (const key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
const value = data[key]
|
||||
if (typeof value === 'function') {
|
||||
data[key] = value.bind(component)
|
||||
if (typeof data === 'object') {
|
||||
// bind context of option methods (if any) to this component
|
||||
for (const key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
const value = data[key]
|
||||
if (typeof value === 'function') {
|
||||
data[key] = value.bind(component)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// merge with existing options
|
||||
result = deepmerge(result, data, { arrayMerge })
|
||||
}
|
||||
// merge with existing options
|
||||
result = deepmerge(result, data, { arrayMerge })
|
||||
|
||||
// collect & aggregate child options if deep = true
|
||||
if (deep) {
|
||||
const { $children } = component
|
||||
for (let i = 0, len = $children.length; i < len; i++) {
|
||||
const component = $children[i]
|
||||
result = getComponentOption({ option, deep, component, arrayMerge }, result)
|
||||
// collect & aggregate child options if deep = true
|
||||
if (deep) {
|
||||
const { $children } = component
|
||||
for (let i = 0, len = $children.length; i < len; i++) {
|
||||
const component = $children[i]
|
||||
result = getComponentOption({ option, deep, component, arrayMerge }, result)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
result = data
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import Vue from 'vue'
|
||||
import getComponentOption from '../src/shared/getComponentOption'
|
||||
|
||||
describe('getComponentOption', () => {
|
||||
const container = document.createElement('div')
|
||||
let component
|
||||
|
||||
afterEach(() => component.$destroy())
|
||||
|
||||
it('fetches the given option from the given component', () => {
|
||||
component = new Vue({ someOption: 'foo' })
|
||||
const fetchedOption = getComponentOption({ component, option: 'someOption' })
|
||||
expect(fetchedOption).to.eql('foo')
|
||||
})
|
||||
|
||||
it('fetches deeply nested component options and merges them', () => {
|
||||
Vue.component('merge-child', { template: '<div></div>', foo: { bar: 'baz' } })
|
||||
|
||||
component = new Vue({
|
||||
foo: { fizz: 'buzz' },
|
||||
render: (h) => h('div', null, [h('merge-child')]),
|
||||
el: container
|
||||
})
|
||||
|
||||
const fetchedOption = getComponentOption({ component, option: 'foo', deep: true })
|
||||
expect(fetchedOption).to.eql({ bar: 'baz', fizz: 'buzz' })
|
||||
})
|
||||
|
||||
it('allows for a custom array merge strategy', () => {
|
||||
Vue.component('array-child', {
|
||||
template: '<div></div>',
|
||||
foo: [
|
||||
{ name: 'flower', content: 'rose' }
|
||||
]
|
||||
})
|
||||
|
||||
component = new Vue({
|
||||
render: (h) => h('div', null, [h('array-child')]),
|
||||
foo: [
|
||||
{ name: 'flower', content: 'tulip' }
|
||||
],
|
||||
el: container
|
||||
})
|
||||
|
||||
const fetchedOption = getComponentOption({
|
||||
component,
|
||||
option: 'foo',
|
||||
deep: true,
|
||||
arrayMerge (target, source) {
|
||||
return target.concat(source)
|
||||
}
|
||||
})
|
||||
|
||||
expect(fetchedOption).to.eql([
|
||||
{ name: 'flower', content: 'tulip' },
|
||||
{ name: 'flower', content: 'rose' }
|
||||
])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user