Skip to content

Commit

Permalink
fix: handle options applied by mixins (#1101)
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyerburgh committed Jan 18, 2019
1 parent c13cac3 commit d2f26e8
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 17 deletions.
26 changes: 17 additions & 9 deletions packages/create-instance/create-component-stubs.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ function getCoreProperties (componentOptions: Component): Object {
return {
attrs: componentOptions.attrs,
name: componentOptions.name,
props: componentOptions.props,
on: componentOptions.on,
key: componentOptions.key,
ref: componentOptions.ref,
props: componentOptions.props,
domProps: componentOptions.domProps,
class: componentOptions.class,
staticClass: componentOptions.staticClass,
Expand All @@ -64,15 +64,22 @@ function createClassString (staticClass, dynamicClass) {
return staticClass || dynamicClass
}

function resolveOptions (component, _Vue) {
if (typeof component === 'function' && !component.cid) {
return {}
}

return typeof component === 'function'
? component.options
: _Vue.extend(component).options
}

export function createStubFromComponent (
originalComponent: Component,
name: string
name: string,
_Vue: Component
): Component {
const componentOptions =
typeof originalComponent === 'function' && originalComponent.cid
? originalComponent.extendOptions
: originalComponent

const componentOptions = resolveOptions(originalComponent, _Vue)
const tagName = `${name || 'anonymous'}-stub`

// ignoreElements does not exist in Vue 2.0.x
Expand Down Expand Up @@ -137,7 +144,8 @@ function validateStub (stub) {

export function createStubsFromStubsObject (
originalComponents: Object = {},
stubs: Object
stubs: Object,
_Vue: Component
): Components {
return Object.keys(stubs || {}).reduce((acc, stubName) => {
const stub = stubs[stubName]
Expand All @@ -150,7 +158,7 @@ export function createStubsFromStubsObject (

if (stub === true) {
const component = resolveComponent(originalComponents, stubName)
acc[stubName] = createStubFromComponent(component, stubName)
acc[stubName] = createStubFromComponent(component, stubName, _Vue)
return acc
}

Expand Down
7 changes: 4 additions & 3 deletions packages/create-instance/create-instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { componentNeedsCompiling, isPlainObject } from 'shared/validators'
import { validateSlots } from './validate-slots'
import createScopedSlots from './create-scoped-slots'
import { createStubsFromStubsObject } from './create-component-stubs'
import { patchRender } from './patch-render'
import { patchCreateElement } from './patch-create-element'

function vueExtendUnsupportedOption (option: string) {
return `options.${option} is not supported for ` +
Expand Down Expand Up @@ -60,13 +60,14 @@ export default function createInstance (
const stubComponentsObject = createStubsFromStubsObject(
component.components,
// $FlowIgnore
options.stubs
options.stubs,
_Vue
)

addEventLogger(_Vue)
addMocks(_Vue, options.mocks)
addStubs(_Vue, stubComponentsObject)
patchRender(_Vue, stubComponentsObject, options.shouldProxy)
patchCreateElement(_Vue, stubComponentsObject, options.shouldProxy)

if (
(component.options && component.options.functional) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function extend (component, _Vue) {

function createStubIfNeeded (shouldStub, component, _Vue, el) {
if (shouldStub) {
return createStubFromComponent(component || {}, el)
return createStubFromComponent(component || {}, el, _Vue)
}

if (shouldExtend(component, _Vue)) {
Expand All @@ -49,14 +49,14 @@ function isComponentOptions (el) {
return typeof el === 'object' && (el.template || el.render)
}

export function patchRender (_Vue, stubs, stubAllComponents) {
export function patchCreateElement (_Vue, stubs, stubAllComponents) {
// This mixin patches vm.$createElement so that we can stub all components
// before they are rendered in shallow mode. We also need to ensure that
// component constructors were created from the _Vue constructor. If not,
// we must replace them with components created from the _Vue constructor
// before calling the original $createElement. This ensures that components
// have the correct instance properties and stubs when they are rendered.
function patchRenderMixin () {
function patchCreateElementMixin () {
const vm = this

if (
Expand All @@ -77,7 +77,7 @@ export function patchRender (_Vue, stubs, stubAllComponents) {

if (isConstructor(el) || isComponentOptions(el)) {
if (stubAllComponents) {
const stub = createStubFromComponent(el, el.name || 'anonymous')
const stub = createStubFromComponent(el, el.name || 'anonymous', _Vue)
return originalCreateElement(stub, ...args)
}
const Constructor = shouldExtend(el, _Vue) ? extend(el, _Vue) : el
Expand Down Expand Up @@ -121,6 +121,6 @@ export function patchRender (_Vue, stubs, stubAllComponents) {
}

_Vue.mixin({
[BEFORE_RENDER_LIFECYCLE_HOOK]: patchRenderMixin
[BEFORE_RENDER_LIFECYCLE_HOOK]: patchCreateElementMixin
})
}
32 changes: 32 additions & 0 deletions test/specs/shallow-mount.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,38 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => {
expect(wrapper.find('p').exists()).to.equal(false)
})

it('stubs components that receive props through mixin', () => {
const addProps = {
props: ['a']
}

const ChildComponent = {
template: '<div />',
mixins: [addProps]
}

const ChildComponentExtended = Vue.extend({
template: '<div />',
mixins: [addProps]
})

const TestComponent = {
template: `
<div>
<child-component a="val" />
<child-component-extended a="val" />
</div>
`,
components: {
ChildComponent,
ChildComponentExtended
}
}
const wrapper = shallowMount(TestComponent)
expect(wrapper.find(ChildComponent).props('a')).to.equal('val')
expect(wrapper.find(ChildComponentExtended).props('a')).to.equal('val')
})

itDoNotRunIf(
vueVersion < 2.3,
'stubs Vue class component children', () => {
Expand Down

0 comments on commit d2f26e8

Please sign in to comment.