From e74e2bfa6dea052f57535ccbd0afc3c02c6133fe Mon Sep 17 00:00:00 2001 From: Viacheslav Landau Date: Mon, 7 Dec 2020 04:41:48 +0300 Subject: [PATCH] feat: support array class binding in stubbed functional components (#1744) Co-authored-by: palpich --- .../create-instance/create-component-stubs.js | 45 ++++--------------- .../component-with-functional-child.vue | 9 +++- test/specs/shallow-mount.spec.js | 9 ++++ 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/packages/create-instance/create-component-stubs.js b/packages/create-instance/create-component-stubs.js index 8c0749f26..8ffd002a7 100644 --- a/packages/create-instance/create-component-stubs.js +++ b/packages/create-instance/create-component-stubs.js @@ -61,28 +61,6 @@ function getCoreProperties(componentOptions: Component): Object { } } -function createClassString(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 evaluatedDynamicClass = dynamicClass - - // 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') { - evaluatedDynamicClass = Object.keys(dynamicClass).reduce((acc, key) => { - if (dynamicClass[key]) { - return acc + ' ' + key - } - return acc - }, '') - } - - if (staticClass && evaluatedDynamicClass) { - return staticClass + ' ' + evaluatedDynamicClass - } - return staticClass || evaluatedDynamicClass -} - function resolveOptions(component, _Vue) { if (isDynamicComponent(component)) { return {} @@ -134,24 +112,19 @@ export function createStubFromComponent( render(h, context) { return h( tagName, - { - ref: componentOptions.functional ? context.data.ref : undefined, - domProps: componentOptions.functional - ? context.data.domProps - : undefined, - attrs: componentOptions.functional - ? { + componentOptions.functional + ? { + ...context.data, + attrs: { ...context.props, - ...context.data.attrs, - class: createClassString( - context.data.staticClass, - context.data.class - ) + ...context.data.attrs } - : { + } + : { + attrs: { ...this.$props } - }, + }, context ? context.children : this.$options._renderChildren || diff --git a/test/resources/components/component-with-functional-child.vue b/test/resources/components/component-with-functional-child.vue index 16d638a02..14bc2ab68 100644 --- a/test/resources/components/component-with-functional-child.vue +++ b/test/resources/components/component-with-functional-child.vue @@ -1,7 +1,8 @@ @@ -19,6 +20,12 @@ export default { b: 1, something: 'value' } + }, + + methods: { + handleFunctionalComponentClick() { + this.something = 'newValue' + } } } diff --git a/test/specs/shallow-mount.spec.js b/test/specs/shallow-mount.spec.js index 4d668a39d..4e5ce3ffe 100644 --- a/test/specs/shallow-mount.spec.js +++ b/test/specs/shallow-mount.spec.js @@ -33,6 +33,7 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => { it('renders dynamic class of functional child', () => { const wrapper = shallowMount(ComponentWithFunctionalChild) expect(wrapper.find('functional-component-stub').classes()).toContain( + 'baz', 'foo', 'bar' ) @@ -46,6 +47,14 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => { expect(wrapper.find('functional-component-stub').text()).toBe('value') }) + it('trigger click must change content of functional child', async () => { + const wrapper = shallowMount(ComponentWithFunctionalChild) + + await wrapper.trigger('click') + + expect(wrapper.find('functional-component-stub').text()).toBe('newValue') + }) + it('returns new VueWrapper of Vue localVue if no options are passed', () => { const compiled = compileToFunctions('
') const wrapper = shallowMount(compiled)