Skip to content

Commit 250610c

Browse files
committed
fix(stubs): teleport stub children as a function
Fixes #1829
1 parent 9673f47 commit 250610c

File tree

4 files changed

+33
-8
lines changed

4 files changed

+33
-8
lines changed

src/vnodeTransformers/util.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { isComponent } from '../utils'
22
import { registerStub } from '../stubs'
3-
import { ConcreteComponent, transformVNodeArgs } from 'vue'
3+
import { ConcreteComponent, Teleport, transformVNodeArgs } from 'vue'
44

55
type VNodeArgsTransformerFn = NonNullable<
66
Parameters<typeof transformVNodeArgs>[0]
@@ -20,6 +20,8 @@ export type VTUVNodeTypeTransformer = (
2020
instance: InstanceArgsType
2121
) => VNodeTransformerInputComponentType
2222

23+
const isTeleport = (type: any): boolean => type.__isTeleport
24+
2325
export const createVNodeTransformer = ({
2426
transformers
2527
}: {
@@ -31,15 +33,20 @@ export const createVNodeTransformer = ({
3133
> = new WeakMap()
3234

3335
return (args: VNodeTransformerArgsType, instance: InstanceArgsType) => {
34-
const [originalType, ...restVNodeArgs] = args
36+
const [originalType, props, children, ...restVNodeArgs] = args
3537

3638
if (!isComponent(originalType)) {
37-
return [originalType, ...restVNodeArgs]
39+
return [originalType, props, children, ...restVNodeArgs]
3840
}
3941

4042
const cachedTransformation = transformationCache.get(originalType)
4143
if (cachedTransformation) {
42-
return [cachedTransformation, ...restVNodeArgs]
44+
// https://github.com/vuejs/test-utils/issues/1829
45+
// Teleport should return child nodes as a function
46+
if (isTeleport(originalType)) {
47+
return [cachedTransformation, props, () => children, ...restVNodeArgs]
48+
}
49+
return [cachedTransformation, props, children, ...restVNodeArgs]
4350
}
4451

4552
const componentType: VNodeTransformerInputComponentType = originalType
@@ -53,8 +60,12 @@ export const createVNodeTransformer = ({
5360
transformationCache.set(originalType, transformedType)
5461

5562
registerStub({ source: originalType, stub: transformedType })
63+
// https://github.com/vuejs/test-utils/issues/1829
64+
// Teleport should return child nodes as a function
65+
if (isTeleport(originalType)) {
66+
return [transformedType, props, () => children, ...restVNodeArgs]
67+
}
5668
}
57-
58-
return [transformedType, ...restVNodeArgs]
69+
return [transformedType, props, children, ...restVNodeArgs]
5970
}
6071
}

tests/element.spec.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from 'vitest'
1+
import { describe, expect, it, vi } from 'vitest'
22
import { defineComponent, h } from 'vue'
33

44
import { mount } from '../src'
@@ -107,12 +107,17 @@ describe('element', () => {
107107
})
108108

109109
it('returns correct element for component which renders other component with array of vnodes in default slot', () => {
110+
const spy = vi.spyOn(console, 'warn').mockImplementation(() => {})
110111
const Nested = {
111112
template: '<div class="nested-root"><slot></slot></div>'
112113
}
113114
const Root = () => h(Nested, {}, [h('div', {}, 'foo'), h('div', {}, 'bar')])
114115

115116
const wrapper = mount(Root)
116117
expect(wrapper.element.innerHTML).toBe('<div>foo</div><div>bar</div>')
118+
// we're expecting a warning from Vue as we're using non-function slots
119+
expect(spy.mock.calls[0][0]).toContain(
120+
'Non-function value encountered for default slot'
121+
)
117122
})
118123
})

tests/findAllComponents.spec.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from 'vitest'
1+
import { describe, expect, it, vi } from 'vitest'
22
import { mount } from '../src'
33
import Hello from './components/Hello.vue'
44
import { DefineComponent, defineComponent, h } from 'vue'
@@ -100,6 +100,7 @@ describe('findAllComponents', () => {
100100
})
101101

102102
it('findAllComponents with non-function slots', () => {
103+
const spy = vi.spyOn(console, 'warn').mockImplementation(() => {})
103104
const ComponentA = defineComponent({
104105
template: '<div><slot /></div>'
105106
})
@@ -119,5 +120,9 @@ describe('findAllComponents', () => {
119120
})
120121
expect(wrapper.findAll('span')).toHaveLength(3)
121122
expect(wrapper.findAllComponents(ComponentB)).toHaveLength(3)
123+
// we're expecting a warning from Vue as we're using non-function slots
124+
expect(spy.mock.calls[0][0]).toContain(
125+
'Non-function value encountered for default slot'
126+
)
122127
})
123128
})

tests/mountingOptions/global.stubs.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ describe('mounting options: stubs', () => {
512512
})
513513

514514
it('opts in to stubbing teleport ', () => {
515+
const spy = vi.spyOn(console, 'warn')
515516
const Comp = {
516517
template: `<teleport to="body"><div id="content" /></teleport>`
517518
}
@@ -528,6 +529,9 @@ describe('mounting options: stubs', () => {
528529
' <div id="content"></div>\n' +
529530
'</teleport-stub>'
530531
)
532+
// Make sure that we don't have a warning when stubbing teleport
533+
// https://github.com/vuejs/test-utils/issues/1829
534+
expect(spy).not.toHaveBeenCalled()
531535
})
532536

533537
it('does not stub teleport with shallow', () => {

0 commit comments

Comments
 (0)