Skip to content

Commit

Permalink
refactor: update find (#942)
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyerburgh authored Aug 26, 2018
1 parent 22b909e commit 8b566a6
Show file tree
Hide file tree
Showing 23 changed files with 660 additions and 658 deletions.
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

0 comments on commit 8b566a6

Please sign in to comment.