-
Notifications
You must be signed in to change notification settings - Fork 668
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: wrap extended child components (#840)
- Loading branch information
1 parent
bee7cb0
commit 4faf5fb
Showing
15 changed files
with
435 additions
and
238 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { createComponentStubs } from 'shared/stub-components' | ||
|
||
export function addStubs (component, stubs, _Vue) { | ||
const stubComponents = createComponentStubs( | ||
component.components, | ||
stubs | ||
) | ||
|
||
function addStubComponentsMixin () { | ||
Object.assign( | ||
this.$options.components, | ||
stubComponents | ||
) | ||
} | ||
|
||
_Vue.mixin({ | ||
beforeMount: addStubComponentsMixin, | ||
// beforeCreate is for components created in node, which | ||
// never mount | ||
beforeCreate: addStubComponentsMixin | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { warn } from 'shared/util' | ||
|
||
function createdFrom (extendOptions, componentOptions) { | ||
while (extendOptions) { | ||
if (extendOptions === componentOptions) { | ||
return true | ||
} | ||
if (extendOptions._vueTestUtilsRoot === componentOptions) { | ||
return true | ||
} | ||
extendOptions = extendOptions.extendOptions | ||
} | ||
} | ||
|
||
function resolveComponents (options = {}, components = {}) { | ||
let extendOptions = options.extendOptions | ||
while (extendOptions) { | ||
resolveComponents(extendOptions, components) | ||
extendOptions = extendOptions.extendOptions | ||
} | ||
let extendsFrom = options.extends | ||
while (extendsFrom) { | ||
resolveComponents(extendsFrom, components) | ||
extendsFrom = extendsFrom.extends | ||
} | ||
Object.keys(options.components || {}).forEach((c) => { | ||
components[c] = options.components[c] | ||
}) | ||
return components | ||
} | ||
|
||
function shouldExtend (component) { | ||
while (component) { | ||
if (component.extendOptions) { | ||
return true | ||
} | ||
component = component.extends | ||
} | ||
} | ||
|
||
// Components created with Vue.extend are not created internally in Vue | ||
// by extending a localVue constructor. To make sure they inherit | ||
// properties add to a localVue constructor, we must create new components by | ||
// extending the original extended components from the localVue constructor. | ||
// We apply a global mixin that overwrites the components original | ||
// components with the extended components when they are created. | ||
export function extendExtendedComponents ( | ||
component, | ||
_Vue, | ||
logModifiedComponents, | ||
excludedComponents = { }, | ||
stubAllComponents = false | ||
) { | ||
const extendedComponents = Object.create(null) | ||
const components = resolveComponents(component) | ||
|
||
Object.keys(components).forEach(c => { | ||
const comp = components[c] | ||
const shouldExtendComponent = | ||
(shouldExtend(comp) && | ||
!excludedComponents[c]) || | ||
stubAllComponents | ||
if (shouldExtendComponent) { | ||
if (logModifiedComponents) { | ||
warn( | ||
`The child component <${c}> has been modified to ensure ` + | ||
`it is created with properties injected by Vue Test Utils. \n` + | ||
`This is because the component was created with Vue.extend, ` + | ||
`or uses the Vue Class Component decorator. \n` + | ||
`Because the component has been modified, it is not possible ` + | ||
`to find it with a component selector. To find the ` + | ||
`component, you must stub it manually using the stubs mounting ` + | ||
`option, or use a name or ref selector. \n` + | ||
`You can hide this warning by setting the Vue Test Utils ` + | ||
`config.logModifiedComponents option to false.` | ||
) | ||
} | ||
extendedComponents[c] = _Vue.extend(comp) | ||
} | ||
// If a component has been replaced with an extended component | ||
// all its child components must also be replaced. | ||
extendExtendedComponents( | ||
comp, | ||
_Vue, | ||
logModifiedComponents, | ||
{}, | ||
shouldExtendComponent | ||
) | ||
}) | ||
if (extendedComponents) { | ||
_Vue.mixin({ | ||
created () { | ||
if (createdFrom(this.constructor, component)) { | ||
Object.assign( | ||
this.$options.components, | ||
extendedComponents | ||
) | ||
} | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { isPlainObject } from './validators' | ||
import { throwError } from './util' | ||
|
||
export function normalizeStubs (stubs = {}) { | ||
if (isPlainObject(stubs)) { | ||
return stubs | ||
} | ||
if (Array.isArray(stubs)) { | ||
return stubs.reduce((acc, stub) => { | ||
if (typeof stub !== 'string') { | ||
throwError('each item in an options.stubs array must be a string') | ||
} | ||
acc[stub] = true | ||
return acc | ||
}, {}) | ||
} | ||
throwError('options.stubs must be an object or an Array') | ||
} |
Oops, something went wrong.