Skip to content

Commit

Permalink
fix: do not stub slots content when using shallow mount
Browse files Browse the repository at this point in the history
  • Loading branch information
xanf committed Jun 27, 2021
1 parent 015c765 commit c22df8f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 24 deletions.
10 changes: 10 additions & 0 deletions src/stubs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ interface StubOptions {
renderStubDefaultSlot?: boolean
}

const doNotStubComponents: WeakSet<ComponentOptions> = new WeakSet()

const shouldNotStub = (type: ComponentOptions) => doNotStubComponents.has(type)
export const addToDoNotStubComponents = (type: ComponentOptions) =>
doNotStubComponents.add(type)

export const createStub = ({
name,
propsDeclaration,
Expand Down Expand Up @@ -154,6 +160,10 @@ export function stubComponents(
}

if (isComponent(type) || isFunctionalComponent(type)) {
if (shouldNotStub(type)) {
return args
}

const registeredName = getComponentRegisteredName(instance, type)
const componentName = type['name'] || type['displayName']

Expand Down
36 changes: 21 additions & 15 deletions src/utils/compileSlots.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
import { compile } from '@vue/compiler-dom'
import * as vue from 'vue'
import type { SetupContext } from 'vue'
import { addToDoNotStubComponents } from '../stubs'

const SlotWrapper = {
inheritAttrs: false,
setup(_: Record<string, any>, ctx: SetupContext) {
return () => {
const names = Object.keys(ctx.slots)
if (names.length === 0) {
return []
} else {
const slotName = names[0]
return ctx.slots[slotName]!(ctx.attrs)
}
}
}
}
addToDoNotStubComponents(SlotWrapper)

export function processSlot(source = '', Vue = vue) {
let template = source.trim()
Expand All @@ -23,24 +40,13 @@ export function processSlot(source = '', Vue = vue) {
__BROWSER__ ? `'use strict';\n${code}` : code
)

return {
const Component = {
inheritAttrs: false,
render: createRenderFunction(Vue),
components: {
SlotWrapper: {
inheritAttrs: false,
setup(_: Record<string, any>, ctx: SetupContext) {
return () => {
const names = Object.keys(ctx.slots)
if (names.length === 0) {
return []
} else {
const slotName = names[0]
return ctx.slots[slotName]!(ctx.attrs)
}
}
}
}
SlotWrapper
}
}
addToDoNotStubComponents(Component)
return Component
}
17 changes: 8 additions & 9 deletions tests/config.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ComponentPublicInstance, h, inject } from 'vue'
import { defineComponent, ComponentPublicInstance, h, inject } from 'vue'
import { config, mount } from '../src'
import Hello from './components/Hello.vue'
import ComponentWithSlots from './components/ComponentWithSlots.vue'
Expand Down Expand Up @@ -67,11 +67,13 @@ describe('config', () => {
})

it('should evaluate given option as boolean', () => {
const Child = defineComponent({ template: '<div><slot></slot></div>' })
const Component = defineComponent({
components: { Child },
template: '<child><div id="default-slot" /></child>'
})
// @ts-expect-error
let comp = mount(ComponentWithSlots, {
slots: {
default: '<div id="default-slot" />'
},
let comp = mount(Component, {
shallow: true,
global: {
renderStubDefaultSlot: 'truthy'
Expand All @@ -81,10 +83,7 @@ describe('config', () => {
expect(comp.find('#default-slot').exists()).toBe(true)

// @ts-expect-error
let comp = mount(ComponentWithSlots, {
slots: {
default: '<div id="default-slot" />'
},
let comp = mount(Component, {
shallow: true,
global: {
renderStubDefaultSlot: 0
Expand Down
13 changes: 13 additions & 0 deletions tests/shallowMount.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ describe('shallowMount', () => {
)
})

it('correctly renders slot content', () => {
const ComponentWithSlot = defineComponent({
template: '<div><slot></slot></div>'
})

const wrapper = shallowMount(ComponentWithSlot, {
slots: {
default: '<span class="slot-content">test</span>'
}
})
expect(wrapper.find('.slot-content').exists()).toBe(true)
})

it('stubs all components, but allows providing custom stub', () => {
const wrapper = mount(ComponentWithChildren, {
shallow: true,
Expand Down

0 comments on commit c22df8f

Please sign in to comment.