Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #1845: add functional component check in component name match #1857

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions packages/test-utils/src/matches.js
Expand Up @@ -3,16 +3,20 @@ import {
COMPONENT_SELECTOR,
FUNCTIONAL_OPTIONS
} from 'shared/consts'
import { isConstructor } from 'shared/validators'
import { isConstructor, isFunctionalComponent } from 'shared/validators'
import { capitalize, camelize } from 'shared/util'

function vmMatchesName(vm, name) {
// We want to mirror how Vue resolves component names in SFCs:
// For example, <test-component />, <TestComponent /> and `<testComponent />
// all resolve to the same component
const componentName = vm.name || (vm.$options && vm.$options.name) || ''
const componentName = isFunctionalComponent(vm)
? vm.name
: vm.$options && vm.$options.name

return (
!!name &&
!!componentName &&
(componentName === name ||
// testComponent -> TestComponent
componentName === capitalize(name) ||
Expand Down
12 changes: 12 additions & 0 deletions test/resources/components/component-with-name-prop.vue
@@ -0,0 +1,12 @@
<template>
<div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a functional component? Since the patch is related to functional component name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the patch is related to functional components but the fix is for normal components.

Eg for a functional component when you access vm.name you will get the name of the component. But accessing vm.name for a normal component will return the name property if that exists. Previously the code was just too greedy by always preferring to use vm.name if it exists. But given the aformentioned that will result in a find bug when you try to find a normal component that has a name prop itself

<p class="prop-name">{{ name }}</p>
</div>
</template>

<script>
export default {
name: 'component-with-name-prop',
props: ['name']
}
</script>
10 changes: 10 additions & 0 deletions test/specs/wrapper/find.spec.js
Expand Up @@ -3,6 +3,7 @@ import { createLocalVue, shallowMount } from 'packages/test-utils/src'
import Vue from 'vue'
import VueRouter from 'vue-router'
import ComponentWithChild from '~resources/components/component-with-child.vue'
import ComponentWithNameProp from '~resources/components/component-with-name-prop.vue'
import ComponentWithoutName from '~resources/components/component-without-name.vue'
import ComponentWithSlots from '~resources/components/component-with-slots.vue'
import ComponentWithVFor from '~resources/components/component-with-v-for.vue'
Expand Down Expand Up @@ -556,6 +557,15 @@ describeWithShallowAndMount('find', mountingMethod => {
expect(wrapper.find({ name: 'CamelCase' }).name()).toEqual('camel-case')
})

it('returns a Wrapper matching a component name if Component has a name prop', () => {
const wrapper = mountingMethod(ComponentWithNameProp, {
propsData: { name: 'prop1' }
})
expect(
wrapper.findComponent({ name: 'component-with-name-prop' }).vnode
).toBeTruthy()
})

it('returns Wrapper of Vue Component matching the ref in options object', () => {
const wrapper = mountingMethod(ComponentWithChild)
expect(wrapper.find({ ref: 'child' }).isVueInstance()).toEqual(true)
Expand Down