Skip to content

Commit

Permalink
fix: shallow config issue (#607)
Browse files Browse the repository at this point in the history
* fix global renderStubDefaultIssue

* fix rendering issue for renderStubDefaultSlot

* fix format and lint

* remove excess async from stubs.global.spec.ts
  • Loading branch information
YutamaKotaro authored May 20, 2021
1 parent 3aad908 commit 11b5216
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { GlobalMountOptions } from './types'
import { VueWrapper } from './vueWrapper'
import { DOMWrapper } from './domWrapper'

interface GlobalConfigOptions {
export interface GlobalConfigOptions {
global: Required<GlobalMountOptions>
plugins: {
VueWrapper: Pluggable<VueWrapper<ComponentPublicInstance>>
Expand Down
14 changes: 7 additions & 7 deletions src/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,7 @@ export function mount(
...options?.props,
ref: MOUNT_COMPONENT_REF
})

const global = mergeGlobalProperties(config.global, options?.global)
const global = mergeGlobalProperties(options?.global)
component.components = { ...component.components, ...global.components }

// create the wrapper component
Expand Down Expand Up @@ -433,10 +432,7 @@ export function mount(
// stubs
// even if we are using `mount`, we will still
// stub out Transition and Transition Group by default.
stubComponents(
global.stubs,
global.renderStubDefaultSlot ? false : options?.shallow
)
stubComponents(global.stubs, options?.shallow, global?.renderStubDefaultSlot)

// users expect stubs to work with globally registered
// components, too, such as <router-link> and <router-view>
Expand All @@ -448,7 +444,11 @@ export function mount(
if (global?.stubs) {
for (const [name, stub] of Object.entries(global.stubs)) {
if (stub === true) {
const stubbed = createStub({ name, props: {} })
const stubbed = createStub({
name,
props: {},
renderStubDefaultSlot: global?.renderStubDefaultSlot
})
// default stub.
app.component(name, stubbed)
} else {
Expand Down
23 changes: 13 additions & 10 deletions src/stubs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,27 @@ import {
} from 'vue'
import { hyphenate } from './utils/vueShared'
import { MOUNT_COMPONENT_REF, MOUNT_PARENT_NAME } from './constants'
import { config } from './config'
import { matchName } from './utils/matchName'
import { ComponentInternalInstance } from '@vue/runtime-core'

interface StubOptions {
name: string
props?: any
propsDeclaration?: any
}

function getSlots(ctx: ComponentPublicInstance): Slots | undefined {
return !config.renderStubDefaultSlot ? undefined : ctx.$slots
renderStubDefaultSlot?: boolean
}

export const createStub = ({
name,
props,
propsDeclaration
propsDeclaration,
renderStubDefaultSlot
}: StubOptions): ComponentOptions => {
const anonName = 'anonymous-stub'
const tag = name ? `${hyphenate(name)}-stub` : anonName

const render = (ctx: ComponentPublicInstance) => {
return h(tag, props, getSlots(ctx))
return h(tag, props, renderStubDefaultSlot ? ctx.$slots : undefined)
}

return defineComponent({
Expand Down Expand Up @@ -112,7 +109,8 @@ const isFunctionalComponent = (type: VNodeTypes): type is ComponentOptions =>

export function stubComponents(
stubs: Record<any, any> = {},
shallow: boolean = false
shallow: boolean = false,
renderStubDefaultSlot: boolean = false
) {
transformVNodeArgs((args, instance: ComponentInternalInstance | null) => {
const [nodeType, props, children, patchFlag, dynamicProps] = args
Expand Down Expand Up @@ -161,7 +159,7 @@ export function stubComponents(

// No name found?
if (!registeredName && !componentName) {
return shallow ? ['stub'] : args
return renderStubDefaultSlot || !shallow ? args : ['stub']
}

let stub = null
Expand Down Expand Up @@ -199,7 +197,12 @@ export function stubComponents(
}

const propsDeclaration = type?.props || {}
const newStub = createStub({ name, propsDeclaration, props })
const newStub = createStub({
name,
propsDeclaration,
props,
renderStubDefaultSlot
})
stubs[name] = newStub
return [newStub, props, children, patchFlag, dynamicProps]
}
Expand Down
13 changes: 8 additions & 5 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { GlobalMountOptions } from './types'
import { AppConfig } from 'vue'
import { config } from './config'

function mergeStubs(target: Record<string, any>, source: GlobalMountOptions) {
if (source.stubs) {
Expand All @@ -14,14 +15,18 @@ function mergeStubs(target: Record<string, any>, source: GlobalMountOptions) {
}

export function mergeGlobalProperties(
configGlobal: GlobalMountOptions = {},
mountGlobal: GlobalMountOptions = {}
): Required<GlobalMountOptions> {
const stubs: Record<string, any> = {}

const configGlobal: GlobalMountOptions = config?.global ?? {}
mergeStubs(stubs, configGlobal)
mergeStubs(stubs, mountGlobal)

const renderStubDefaultSlot =
mountGlobal.renderStubDefaultSlot ??
config?.renderStubDefaultSlot ??
configGlobal?.renderStubDefaultSlot

return {
mixins: [...(configGlobal.mixins || []), ...(mountGlobal.mixins || [])],
plugins: [...(configGlobal.plugins || []), ...(mountGlobal.plugins || [])],
Expand All @@ -31,9 +36,7 @@ export function mergeGlobalProperties(
mocks: { ...configGlobal.mocks, ...mountGlobal.mocks },
config: { ...configGlobal.config, ...mountGlobal.config },
directives: { ...configGlobal.directives, ...mountGlobal.directives },
renderStubDefaultSlot: !!(mountGlobal.renderStubDefaultSlot !== undefined
? mountGlobal.renderStubDefaultSlot
: configGlobal.renderStubDefaultSlot)
renderStubDefaultSlot
}
}

Expand Down
26 changes: 26 additions & 0 deletions tests/mountingOptions/global.components.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mount } from '../../src'
import { defineComponent } from 'vue'

describe('global.components', () => {
it('registers a component to all components', () => {
Expand Down Expand Up @@ -70,4 +71,29 @@ describe('global.components', () => {
spy.mockRestore()
expect(wrapper.text()).toBe('Global')
})
it('render children with shallow and renderStubDefaultSlot', () => {
const Child = defineComponent({
template: '<div><p>child</p><slot /></div>'
})
const Component = defineComponent({
template: '<div><Child><div>hello</div></Child></div>',
components: {
Child
}
})
const wrapper = mount(Component, {
shallow: true,
global: {
renderStubDefaultSlot: true
}
})

expect(wrapper.html()).toEqual(
'<div>\n' +
' <child-stub>\n' +
' <div>hello</div>\n' +
' </child-stub>\n' +
'</div>'
)
})
})

0 comments on commit 11b5216

Please sign in to comment.