Skip to content

Commit 8b566a6

Browse files
authored
refactor: update find (#942)
1 parent 22b909e commit 8b566a6

23 files changed

+660
-658
lines changed

Diff for: packages/create-instance/add-stubs.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { createComponentStubs } from 'shared/stub-components'
1+
import { createStubsFromStubsObject } from 'shared/create-component-stubs'
22

33
export function addStubs (component, stubs, _Vue) {
4-
const stubComponents = createComponentStubs(
4+
const stubComponents = createStubsFromStubsObject(
55
component.components,
66
stubs
77
)

Diff for: packages/create-instance/create-instance.js

+9-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import addMocks from './add-mocks'
55
import { addEventLogger } from './log-events'
66
import { addStubs } from './add-stubs'
77
import { throwError, vueVersion } from 'shared/util'
8-
import { compileTemplate } from 'shared/compile-template'
8+
import {
9+
compileTemplate,
10+
compileTemplateForSlots
11+
} from 'shared/compile-template'
912
import { isRequiredComponent } from 'shared/validators'
1013
import extractInstanceOptions from './extract-instance-options'
1114
import createFunctionalComponent from './create-functional-component'
@@ -15,17 +18,6 @@ import createScopedSlots from './create-scoped-slots'
1518
import { extendExtendedComponents } from './extend-extended-components'
1619
import Vue from 'vue'
1720

18-
function compileTemplateForSlots (slots: Object): void {
19-
Object.keys(slots).forEach(key => {
20-
const slot = Array.isArray(slots[key]) ? slots[key] : [slots[key]]
21-
slot.forEach(slotValue => {
22-
if (componentNeedsCompiling(slotValue)) {
23-
compileTemplate(slotValue)
24-
}
25-
})
26-
})
27-
}
28-
2921
function vueExtendUnsupportedOption (option: string) {
3022
return `options.${option} is not supported for ` +
3123
`components created with Vue.extend in Vue < 2.3. ` +
@@ -124,8 +116,13 @@ export default function createInstance (
124116
// Keep reference to component mount was called with
125117
Constructor._vueTestUtilsRoot = component
126118

119+
// used to identify extended component using constructor
120+
Constructor.options.$_vueTestUtils_original = component
127121
if (options.slots) {
128122
compileTemplateForSlots(options.slots)
123+
// validate slots outside of the createSlots function so
124+
// that we can throw an error without it being caught by
125+
// the Vue error handler
129126
// $FlowIgnore
130127
validateSlots(options.slots)
131128
}

Diff for: packages/create-instance/extend-extended-components.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,13 @@ export function extendExtendedComponents (
7575
`config.logModifiedComponents option to false.`
7676
)
7777
}
78-
extendedComponents[c] = _Vue.extend(comp)
78+
const extendedComp = _Vue.extend(comp)
79+
// used to identify instance when calling find with component selector
80+
if (extendedComp.extendOptions.options) {
81+
extendedComp.extendOptions.options.$_vueTestUtils_original = comp
82+
}
83+
extendedComp.extendOptions.$_vueTestUtils_original = comp
84+
extendedComponents[c] = extendedComp
7985
}
8086
// If a component has been replaced with an extended component
8187
// all its child components must also be replaced.

Diff for: packages/shared/compile-template.js

+24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
// @flow
22

33
import { compileToFunctions } from 'vue-template-compiler'
4+
import { componentNeedsCompiling } from './validators'
5+
import { throwError } from './util'
6+
7+
export function compileFromString (str: string) {
8+
if (!compileToFunctions) {
9+
throwError(
10+
`vueTemplateCompiler is undefined, you must pass ` +
11+
`precompiled components if vue-template-compiler is ` +
12+
`undefined`
13+
)
14+
}
15+
return compileToFunctions(str)
16+
}
417

518
export function compileTemplate (component: Component): void {
619
if (component.template) {
@@ -24,3 +37,14 @@ export function compileTemplate (component: Component): void {
2437
compileTemplate(component.options)
2538
}
2639
}
40+
41+
export function compileTemplateForSlots (slots: Object): void {
42+
Object.keys(slots).forEach(key => {
43+
const slot = Array.isArray(slots[key]) ? slots[key] : [slots[key]]
44+
slot.forEach(slotValue => {
45+
if (componentNeedsCompiling(slotValue)) {
46+
compileTemplate(slotValue)
47+
}
48+
})
49+
})
50+
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// @flow
22

33
import Vue from 'vue'
4-
import { compileToFunctions } from 'vue-template-compiler'
54
import {
65
throwError,
76
camelize,
@@ -11,30 +10,21 @@ import {
1110
import {
1211
componentNeedsCompiling,
1312
templateContainsComponent,
14-
isVueComponent,
15-
isRequiredComponent
13+
isVueComponent
1614
} from './validators'
17-
import { compileTemplate } from './compile-template'
18-
19-
function compileFromString (str) {
20-
if (!compileToFunctions) {
21-
throwError(
22-
`vueTemplateCompiler is undefined, you must pass ` +
23-
`precompiled components if vue-template-compiler is ` +
24-
`undefined`
25-
)
26-
}
27-
return compileToFunctions(str)
28-
}
15+
import {
16+
compileTemplate,
17+
compileFromString
18+
} from './compile-template'
2919

3020
function isVueComponentStub (comp): boolean {
3121
return comp && comp.template || isVueComponent(comp)
3222
}
3323

3424
function isValidStub (stub: any): boolean {
3525
return (
26+
typeof stub === 'boolean' ||
3627
(!!stub && typeof stub === 'string') ||
37-
stub === true ||
3828
isVueComponentStub(stub)
3929
)
4030
}
@@ -67,33 +57,14 @@ function getCoreProperties (componentOptions: Component): Object {
6757
}
6858
}
6959

70-
function createStubFromString (
71-
templateString: string,
72-
originalComponent: Component,
73-
name: string
74-
): Component {
75-
if (templateContainsComponent(templateString, name)) {
76-
throwError('options.stub cannot contain a circular reference')
77-
}
78-
79-
const componentOptions = typeof originalComponent === 'function'
80-
? originalComponent.extendOptions
81-
: originalComponent
82-
83-
return {
84-
...getCoreProperties(componentOptions),
85-
...compileFromString(templateString)
86-
}
87-
}
88-
8960
function createClassString (staticClass, dynamicClass) {
9061
if (staticClass && dynamicClass) {
9162
return staticClass + ' ' + dynamicClass
9263
}
9364
return staticClass || dynamicClass
9465
}
9566

96-
export function createBlankStub (
67+
export function createStubFromComponent (
9768
originalComponent: Component,
9869
name: string
9970
): Component {
@@ -109,6 +80,7 @@ export function createBlankStub (
10980

11081
return {
11182
...getCoreProperties(componentOptions),
83+
$_vueTestUtils_original: originalComponent,
11284
render (h, context) {
11385
return h(
11486
tagName,
@@ -130,101 +102,123 @@ export function createBlankStub (
130102
}
131103
}
132104

133-
export function createComponentStubs (
105+
function createStubFromString (
106+
templateString: string,
107+
originalComponent: Component = {},
108+
name: string
109+
): Component {
110+
if (templateContainsComponent(templateString, name)) {
111+
throwError('options.stub cannot contain a circular reference')
112+
}
113+
114+
const componentOptions = typeof originalComponent === 'function'
115+
? originalComponent.extendOptions
116+
: originalComponent
117+
118+
return {
119+
...getCoreProperties(componentOptions),
120+
...compileFromString(templateString)
121+
}
122+
}
123+
124+
function validateStub (stub) {
125+
if (!isValidStub(stub)) {
126+
throwError(
127+
`options.stub values must be passed a string or ` +
128+
`component`
129+
)
130+
}
131+
}
132+
133+
export function createStubsFromStubsObject (
134134
originalComponents: Object = {},
135135
stubs: Object
136136
): Components {
137-
const components = {}
138-
if (!stubs) {
139-
return components
140-
}
141-
Object.keys(stubs).forEach(stubName => {
137+
return Object.keys(stubs || {}).reduce((acc, stubName) => {
142138
const stub = stubs[stubName]
143-
if (stub === false) {
144-
return
145-
}
146139

147-
if (!isValidStub(stub)) {
148-
throwError(
149-
`options.stub values must be passed a string or ` + `component`
150-
)
140+
validateStub(stub)
141+
142+
if (stub === false) {
143+
return acc
151144
}
152145

153146
if (stub === true) {
154147
const component = resolveComponent(originalComponents, stubName)
155-
components[stubName] = createBlankStub(component, stubName)
156-
return
157-
}
158-
159-
if (typeof stub !== 'string' && componentNeedsCompiling(stub)) {
160-
compileTemplate(stub)
148+
acc[stubName] = createStubFromComponent(component, stubName)
149+
return acc
161150
}
162151

163152
if (originalComponents[stubName]) {
164153
// Remove cached constructor
165154
delete originalComponents[stubName]._Ctor
166-
if (typeof stub === 'string') {
167-
components[stubName] = createStubFromString(
168-
stub,
169-
originalComponents[stubName],
170-
stubName
171-
)
172-
} else {
173-
const stubObject = (stub: Object)
174-
components[stubName] = {
175-
...stubObject,
176-
name: originalComponents[stubName].name
177-
}
178-
}
179-
} else {
180-
if (typeof stub === 'string') {
181-
components[stubName] = {
182-
...compileFromString(stub)
183-
}
184-
} else {
185-
const stubObject = (stub: Object)
186-
components[stubName] = {
187-
...stubObject
188-
}
189-
}
190155
}
191-
})
192-
return components
156+
157+
if (typeof stub === 'string') {
158+
acc[stubName] = createStubFromString(
159+
stub,
160+
originalComponents[stubName],
161+
stubName
162+
)
163+
return acc
164+
}
165+
166+
if (componentNeedsCompiling(stub)) {
167+
compileTemplate(stub)
168+
}
169+
const name = originalComponents[stubName] &&
170+
originalComponents[stubName].name
171+
172+
acc[stubName] = {
173+
name,
174+
...stub
175+
}
176+
177+
return acc
178+
}, {})
193179
}
194180

195181
function stubComponents (
196182
components: Components,
197183
stubbedComponents: Components
198184
): void {
199-
Object.keys(components).forEach(component => {
185+
for (const component in components) {
200186
const cmp = components[component]
201187
const componentOptions = typeof cmp === 'function'
202188
? cmp.extendOptions
203189
: cmp
204190

205191
if (!componentOptions) {
206-
stubbedComponents[component] = createBlankStub({}, component)
192+
stubbedComponents[component] = createStubFromComponent(
193+
{},
194+
component
195+
)
207196
return
208197
}
209198
// Remove cached constructor
210199
delete componentOptions._Ctor
211-
if (!componentOptions.name) {
212-
componentOptions.name = component
213-
}
214-
stubbedComponents[component] = createBlankStub(componentOptions, component)
215-
})
200+
201+
stubbedComponents[component] = createStubFromComponent(
202+
cmp,
203+
component
204+
)
205+
}
216206
}
217207

218-
export function createComponentStubsForAll (component: Component): Components {
208+
export function createStubsForComponent (
209+
component: Component
210+
): Components {
219211
const stubbedComponents = {}
220212

213+
if (component.options) {
214+
stubComponents(component.options.components, stubbedComponents)
215+
}
216+
221217
if (component.components) {
222218
stubComponents(component.components, stubbedComponents)
223219
}
224220

225221
let extended = component.extends
226-
227-
// Loop through extended component chains to stub all child components
228222
while (extended) {
229223
if (extended.components) {
230224
stubComponents(extended.components, stubbedComponents)
@@ -242,18 +236,3 @@ export function createComponentStubsForAll (component: Component): Components {
242236

243237
return stubbedComponents
244238
}
245-
246-
export function createComponentStubsForGlobals (
247-
instance: Component
248-
): Components {
249-
const components = {}
250-
for (const c in instance.options.components) {
251-
if (isRequiredComponent(c)) {
252-
continue
253-
}
254-
components[c] = createBlankStub(instance.options.components[c], c)
255-
delete instance.options.components[c]._Ctor
256-
delete components[c]._Ctor
257-
}
258-
return components
259-
}

Diff for: packages/shared/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export * from './compile-template'
2-
export * from './stub-components'
2+
export * from './create-component-stubs'
33
export * from './util'
44
export * from './validators'

0 commit comments

Comments
 (0)