Skip to content

Commit

Permalink
fix: throw error if functional find not supported
Browse files Browse the repository at this point in the history
closes #296
  • Loading branch information
eddyerburgh committed Jan 2, 2018
1 parent c5cab72 commit d064eaa
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
4 changes: 4 additions & 0 deletions src/lib/consts.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import Vue from 'vue'

export const NAME_SELECTOR = 'NAME_SELECTOR'
export const COMPONENT_SELECTOR = 'COMPONENT_SELECTOR'
export const REF_SELECTOR = 'REF_SELECTOR'
export const DOM_SELECTOR = 'DOM_SELECTOR'
export const VUE_VERSION = Number(`${Vue.version.split('.')[0]}.${Vue.version.split('.')[1]}`)
export const FUNCTIONAL_OPTIONS = VUE_VERSION >= 2.5 ? 'fnOptions' : 'functionalOptions'
23 changes: 16 additions & 7 deletions src/lib/find-vue-components.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// @flow
import {
COMPONENT_SELECTOR
COMPONENT_SELECTOR,
FUNCTIONAL_OPTIONS,
VUE_VERSION
} from './consts'
import {
throwError
} from './util'

function findAllVueComponentsFromVm (
vm: Component,
Expand Down Expand Up @@ -35,7 +40,7 @@ function findAllFunctionalComponentsFromVnode (
vnode: Component,
components: Array<Component> = []
): Array<Component> {
if (vnode.fnOptions) {
if (vnode[FUNCTIONAL_OPTIONS] || vnode.functionalContext) {
components.push(vnode)
}
if (vnode.children) {
Expand All @@ -61,11 +66,15 @@ export function vmCtorMatchesSelector (component: Component, selector: Object) {
}

export function vmFunctionalCtorMatchesSelector (component: VNode, Ctor: Object) {
if (!component.fnOptions) {
if (VUE_VERSION < 2.3) {
throwError('find for functional components is not support in Vue < 2.3')
}

if (!component[FUNCTIONAL_OPTIONS]) {
return false
}
const Ctors = Object.keys(component.fnOptions._Ctor)
return Ctors.some(c => Ctor[c] === component.fnOptions._Ctor[c])
const Ctors = Object.keys(component[FUNCTIONAL_OPTIONS]._Ctor)
return Ctors.some(c => Ctor[c] === component[FUNCTIONAL_OPTIONS]._Ctor[c])
}

export default function findVueComponents (
Expand All @@ -74,10 +83,10 @@ export default function findVueComponents (
selector: Object
): Array<Component> {
if (selector.functional) {
const components = root._vnode
const nodes = root._vnode
? findAllFunctionalComponentsFromVnode(root._vnode)
: findAllFunctionalComponentsFromVnode(root)
return components.filter(component => vmFunctionalCtorMatchesSelector(component, selector._Ctor))
return nodes.filter(node => vmFunctionalCtorMatchesSelector(node, selector._Ctor))
}
const components = root._isVue
? findAllVueComponentsFromVm(root)
Expand Down
24 changes: 23 additions & 1 deletion test/unit/specs/mount/Wrapper/find.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import ComponentWithVFor from '~resources/components/component-with-v-for.vue'
import Component from '~resources/components/component.vue'
import FunctionalComponent from '~resources/components/functional-component.vue'
import ComponentAsAClass from '~resources/components/component-as-a-class.vue'
import { functionalSFCsSupported } from '~resources/test-utils'
import { functionalSFCsSupported, vueVersion } from '~resources/test-utils'

describe('find', () => {
it('returns a Wrapper matching tag selector passed', () => {
Expand Down Expand Up @@ -141,6 +141,28 @@ describe('find', () => {
expect(wrapper.find(FunctionalComponent).vm).to.equal(undefined)
})

it('returns Wrapper of Vue Component matching functional component with name', () => {
const TestFunctionalComponent = {
render: h => h('div'),
functional: true,
name: 'test-functional-component'
}
const TestComponent = {
template: '<div><test-functional-component /></div>',
components: {
TestFunctionalComponent
}
}
const wrapper = mount(TestComponent)
if (vueVersion < 2.3) {
const message = '[vue-test-utils]: find for functional components is not support in Vue < 2.3'
const fn = () => wrapper.find(TestFunctionalComponent)
expect(fn).to.throw().with.property('message', message)
} else {
expect(wrapper.find(TestFunctionalComponent).exists()).to.equal(true)
}
})

it('returns correct number of Vue Wrappers when component has a v-for', () => {
const items = [{ id: 1 }, { id: 2 }, { id: 3 }]
const wrapper = mount(ComponentWithVFor, { propsData: { items }})
Expand Down

0 comments on commit d064eaa

Please sign in to comment.