Skip to content

refactor: update find #942

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Aug 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/create-instance/add-stubs.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createComponentStubs } from 'shared/stub-components'
import { createStubsFromStubsObject } from 'shared/create-component-stubs'

export function addStubs (component, stubs, _Vue) {
const stubComponents = createComponentStubs(
const stubComponents = createStubsFromStubsObject(
component.components,
stubs
)
Expand Down
21 changes: 9 additions & 12 deletions packages/create-instance/create-instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import addMocks from './add-mocks'
import { addEventLogger } from './log-events'
import { addStubs } from './add-stubs'
import { throwError, vueVersion } from 'shared/util'
import { compileTemplate } from 'shared/compile-template'
import {
compileTemplate,
compileTemplateForSlots
} from 'shared/compile-template'
import { isRequiredComponent } from 'shared/validators'
import extractInstanceOptions from './extract-instance-options'
import createFunctionalComponent from './create-functional-component'
Expand All @@ -15,17 +18,6 @@ import createScopedSlots from './create-scoped-slots'
import { extendExtendedComponents } from './extend-extended-components'
import Vue from 'vue'

function compileTemplateForSlots (slots: Object): void {
Object.keys(slots).forEach(key => {
const slot = Array.isArray(slots[key]) ? slots[key] : [slots[key]]
slot.forEach(slotValue => {
if (componentNeedsCompiling(slotValue)) {
compileTemplate(slotValue)
}
})
})
}

function vueExtendUnsupportedOption (option: string) {
return `options.${option} is not supported for ` +
`components created with Vue.extend in Vue < 2.3. ` +
Expand Down Expand Up @@ -124,8 +116,13 @@ export default function createInstance (
// Keep reference to component mount was called with
Constructor._vueTestUtilsRoot = component

// used to identify extended component using constructor
Constructor.options.$_vueTestUtils_original = component
if (options.slots) {
compileTemplateForSlots(options.slots)
// validate slots outside of the createSlots function so
// that we can throw an error without it being caught by
// the Vue error handler
// $FlowIgnore
validateSlots(options.slots)
}
Expand Down
8 changes: 7 additions & 1 deletion packages/create-instance/extend-extended-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,13 @@ export function extendExtendedComponents (
`config.logModifiedComponents option to false.`
)
}
extendedComponents[c] = _Vue.extend(comp)
const extendedComp = _Vue.extend(comp)
// used to identify instance when calling find with component selector
if (extendedComp.extendOptions.options) {
extendedComp.extendOptions.options.$_vueTestUtils_original = comp
}
extendedComp.extendOptions.$_vueTestUtils_original = comp
extendedComponents[c] = extendedComp
}
// If a component has been replaced with an extended component
// all its child components must also be replaced.
Expand Down
24 changes: 24 additions & 0 deletions packages/shared/compile-template.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
// @flow

import { compileToFunctions } from 'vue-template-compiler'
import { componentNeedsCompiling } from './validators'
import { throwError } from './util'

export function compileFromString (str: string) {
if (!compileToFunctions) {
throwError(
`vueTemplateCompiler is undefined, you must pass ` +
`precompiled components if vue-template-compiler is ` +
`undefined`
)
}
return compileToFunctions(str)
}

export function compileTemplate (component: Component): void {
if (component.template) {
Expand All @@ -24,3 +37,14 @@ export function compileTemplate (component: Component): void {
compileTemplate(component.options)
}
}

export function compileTemplateForSlots (slots: Object): void {
Object.keys(slots).forEach(key => {
const slot = Array.isArray(slots[key]) ? slots[key] : [slots[key]]
slot.forEach(slotValue => {
if (componentNeedsCompiling(slotValue)) {
compileTemplate(slotValue)
}
})
})
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @flow

import Vue from 'vue'
import { compileToFunctions } from 'vue-template-compiler'
import {
throwError,
camelize,
Expand All @@ -11,30 +10,21 @@ import {
import {
componentNeedsCompiling,
templateContainsComponent,
isVueComponent,
isRequiredComponent
isVueComponent
} from './validators'
import { compileTemplate } from './compile-template'

function compileFromString (str) {
if (!compileToFunctions) {
throwError(
`vueTemplateCompiler is undefined, you must pass ` +
`precompiled components if vue-template-compiler is ` +
`undefined`
)
}
return compileToFunctions(str)
}
import {
compileTemplate,
compileFromString
} from './compile-template'

function isVueComponentStub (comp): boolean {
return comp && comp.template || isVueComponent(comp)
}

function isValidStub (stub: any): boolean {
return (
typeof stub === 'boolean' ||
(!!stub && typeof stub === 'string') ||
stub === true ||
isVueComponentStub(stub)
)
}
Expand Down Expand Up @@ -67,33 +57,14 @@ function getCoreProperties (componentOptions: Component): Object {
}
}

function createStubFromString (
templateString: string,
originalComponent: Component,
name: string
): Component {
if (templateContainsComponent(templateString, name)) {
throwError('options.stub cannot contain a circular reference')
}

const componentOptions = typeof originalComponent === 'function'
? originalComponent.extendOptions
: originalComponent

return {
...getCoreProperties(componentOptions),
...compileFromString(templateString)
}
}

function createClassString (staticClass, dynamicClass) {
if (staticClass && dynamicClass) {
return staticClass + ' ' + dynamicClass
}
return staticClass || dynamicClass
}

export function createBlankStub (
export function createStubFromComponent (
originalComponent: Component,
name: string
): Component {
Expand All @@ -109,6 +80,7 @@ export function createBlankStub (

return {
...getCoreProperties(componentOptions),
$_vueTestUtils_original: originalComponent,
render (h, context) {
return h(
tagName,
Expand All @@ -130,101 +102,123 @@ export function createBlankStub (
}
}

export function createComponentStubs (
function createStubFromString (
templateString: string,
originalComponent: Component = {},
name: string
): Component {
if (templateContainsComponent(templateString, name)) {
throwError('options.stub cannot contain a circular reference')
}

const componentOptions = typeof originalComponent === 'function'
? originalComponent.extendOptions
: originalComponent

return {
...getCoreProperties(componentOptions),
...compileFromString(templateString)
}
}

function validateStub (stub) {
if (!isValidStub(stub)) {
throwError(
`options.stub values must be passed a string or ` +
`component`
)
}
}

export function createStubsFromStubsObject (
originalComponents: Object = {},
stubs: Object
): Components {
const components = {}
if (!stubs) {
return components
}
Object.keys(stubs).forEach(stubName => {
return Object.keys(stubs || {}).reduce((acc, stubName) => {
const stub = stubs[stubName]
if (stub === false) {
return
}

if (!isValidStub(stub)) {
throwError(
`options.stub values must be passed a string or ` + `component`
)
validateStub(stub)

if (stub === false) {
return acc
}

if (stub === true) {
const component = resolveComponent(originalComponents, stubName)
components[stubName] = createBlankStub(component, stubName)
return
}

if (typeof stub !== 'string' && componentNeedsCompiling(stub)) {
compileTemplate(stub)
acc[stubName] = createStubFromComponent(component, stubName)
return acc
}

if (originalComponents[stubName]) {
// Remove cached constructor
delete originalComponents[stubName]._Ctor
if (typeof stub === 'string') {
components[stubName] = createStubFromString(
stub,
originalComponents[stubName],
stubName
)
} else {
const stubObject = (stub: Object)
components[stubName] = {
...stubObject,
name: originalComponents[stubName].name
}
}
} else {
if (typeof stub === 'string') {
components[stubName] = {
...compileFromString(stub)
}
} else {
const stubObject = (stub: Object)
components[stubName] = {
...stubObject
}
}
}
})
return components

if (typeof stub === 'string') {
acc[stubName] = createStubFromString(
stub,
originalComponents[stubName],
stubName
)
return acc
}

if (componentNeedsCompiling(stub)) {
compileTemplate(stub)
}
const name = originalComponents[stubName] &&
originalComponents[stubName].name

acc[stubName] = {
name,
...stub
}

return acc
}, {})
}

function stubComponents (
components: Components,
stubbedComponents: Components
): void {
Object.keys(components).forEach(component => {
for (const component in components) {
const cmp = components[component]
const componentOptions = typeof cmp === 'function'
? cmp.extendOptions
: cmp

if (!componentOptions) {
stubbedComponents[component] = createBlankStub({}, component)
stubbedComponents[component] = createStubFromComponent(
{},
component
)
return
}
// Remove cached constructor
delete componentOptions._Ctor
if (!componentOptions.name) {
componentOptions.name = component
}
stubbedComponents[component] = createBlankStub(componentOptions, component)
})

stubbedComponents[component] = createStubFromComponent(
cmp,
component
)
}
}

export function createComponentStubsForAll (component: Component): Components {
export function createStubsForComponent (
component: Component
): Components {
const stubbedComponents = {}

if (component.options) {
stubComponents(component.options.components, stubbedComponents)
}

if (component.components) {
stubComponents(component.components, stubbedComponents)
}

let extended = component.extends

// Loop through extended component chains to stub all child components
while (extended) {
if (extended.components) {
stubComponents(extended.components, stubbedComponents)
Expand All @@ -242,18 +236,3 @@ export function createComponentStubsForAll (component: Component): Components {

return stubbedComponents
}

export function createComponentStubsForGlobals (
instance: Component
): Components {
const components = {}
for (const c in instance.options.components) {
if (isRequiredComponent(c)) {
continue
}
components[c] = createBlankStub(instance.options.components[c], c)
delete instance.options.components[c]._Ctor
delete components[c]._Ctor
}
return components
}
2 changes: 1 addition & 1 deletion packages/shared/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './compile-template'
export * from './stub-components'
export * from './create-component-stubs'
export * from './util'
export * from './validators'
Loading