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

feat: support object class binding in stubbed functional components #1476

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
21 changes: 18 additions & 3 deletions packages/create-instance/create-component-stubs.js
Expand Up @@ -60,10 +60,25 @@ function getCoreProperties(componentOptions: Component): Object {
}

function createClassString(staticClass, dynamicClass) {
if (staticClass && dynamicClass) {
return staticClass + ' ' + dynamicClass
// :class="someComputedObject" can return a string, object or undefined
// if it is a string, we don't need to do anything special.
let evalutedDynamicClass = dynamicClass
afontcu marked this conversation as resolved.
Show resolved Hide resolved

// if it is an object, eg { 'foo': true }, we need to evaluate it.
// see https://github.com/vuejs/vue-test-utils/issues/1474 for more context.
if (typeof dynamicClass === 'object') {
evalutedDynamicClass = Object.keys(dynamicClass).reduce((acc, key) => {
if (dynamicClass[key] === true) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we check if this is a truthy value or like this, straight up true?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure, I just went with this to be explicit. I haven't seen people use something like :class={ 'my-class': 'some-truthy-val' }. I guess we should just copy whatever Vue does - will try it out.

return acc + ' ' + key
}
return acc
}, '')
}

if (staticClass && evalutedDynamicClass) {
return staticClass + ' ' + evalutedDynamicClass
}
return staticClass || dynamicClass
return staticClass || evalutedDynamicClass
}

function resolveOptions(component, _Vue) {
Expand Down
22 changes: 22 additions & 0 deletions test/resources/components/component-with-functional-child.vue
@@ -0,0 +1,22 @@
<template>
<functional-component
:class="{ bar: a + b === 2, foo: a === 1, qux: a === 2 }"
/>
</template>

<script>
import FunctionalComponent from './functional-component.vue'

export default {
components: {
FunctionalComponent
},

data() {
return {
a: 1,
b: 1
}
}
}
</script>
12 changes: 12 additions & 0 deletions test/specs/shallow-mount.spec.js
Expand Up @@ -3,6 +3,7 @@ import Vue from 'vue'
import { mount, shallowMount, createLocalVue } from '@vue/test-utils'
import Component from '~resources/components/component.vue'
import ComponentWithChild from '~resources/components/component-with-child.vue'
import ComponentWithFunctionalChild from '~resources/components/component-with-functional-child.vue'
import ComponentWithNestedChildren from '~resources/components/component-with-nested-children.vue'
import ComponentWithLifecycleHooks from '~resources/components/component-with-lifecycle-hooks.vue'
import ComponentWithoutName from '~resources/components/component-without-name.vue'
Expand All @@ -25,6 +26,17 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => {
sandbox.restore()
})

it('renders dynamic class of functional child', () => {
const wrapper = shallowMount(ComponentWithFunctionalChild)
expect(wrapper.find('functional-component-stub').classes()).to.contain(
'foo',
'bar'
)
expect(wrapper.find('functional-component-stub').classes()).not.to.contain(
'qux'
)
})

it('returns new VueWrapper of Vue localVue if no options are passed', () => {
const compiled = compileToFunctions('<div><input /></div>')
const wrapper = shallowMount(compiled)
Expand Down