forked from vuejs/vue-test-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextend-extended-components.js
105 lines (99 loc) · 3.37 KB
/
extend-extended-components.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { warn } from 'shared/util'
import { addHook } from './add-hook'
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.`
)
}
const extendedComp = _Vue.extend(comp)
// Used to identify component in a render tree
extendedComp.options.$_vueTestUtils_original = comp
extendedComponents[c] = extendedComp
}
// If a component has been replaced with an extended component
// all its child components must also be replaced.
extendExtendedComponents(
comp,
_Vue,
logModifiedComponents,
{},
shouldExtendComponent
)
})
if (Object.keys(extendedComponents).length > 0) {
addHook(_Vue.options, 'beforeCreate', function addExtendedOverwrites () {
if (createdFrom(this.constructor, component)) {
Object.assign(
this.$options.components,
extendedComponents
)
}
})
}
}