Skip to content
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

fix(stubs): teleport stub children as a function #1833

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 16 additions & 5 deletions src/vnodeTransformers/util.ts
Expand Up @@ -20,6 +20,8 @@ export type VTUVNodeTypeTransformer = (
instance: InstanceArgsType
) => VNodeTransformerInputComponentType

const isTeleport = (type: any): boolean => type.__isTeleport

export const createVNodeTransformer = ({
transformers
}: {
Expand All @@ -31,15 +33,20 @@ export const createVNodeTransformer = ({
> = new WeakMap()

return (args: VNodeTransformerArgsType, instance: InstanceArgsType) => {
const [originalType, ...restVNodeArgs] = args
const [originalType, props, children, ...restVNodeArgs] = args

if (!isComponent(originalType)) {
return [originalType, ...restVNodeArgs]
return [originalType, props, children, ...restVNodeArgs]
}

const cachedTransformation = transformationCache.get(originalType)
if (cachedTransformation) {
return [cachedTransformation, ...restVNodeArgs]
// https://github.com/vuejs/test-utils/issues/1829
// Teleport should return child nodes as a function
if (isTeleport(originalType)) {
return [cachedTransformation, props, () => children, ...restVNodeArgs]
}
return [cachedTransformation, props, children, ...restVNodeArgs]
cexbrayat marked this conversation as resolved.
Show resolved Hide resolved
}

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

registerStub({ source: originalType, stub: transformedType })
// https://github.com/vuejs/test-utils/issues/1829
// Teleport should return child nodes as a function
if (isTeleport(originalType)) {
return [transformedType, props, () => children, ...restVNodeArgs]
}
}

return [transformedType, ...restVNodeArgs]
return [transformedType, props, children, ...restVNodeArgs]
}
}
7 changes: 6 additions & 1 deletion tests/element.spec.ts
@@ -1,4 +1,4 @@
import { describe, expect, it } from 'vitest'
import { describe, expect, it, vi } from 'vitest'
import { defineComponent, h } from 'vue'

import { mount } from '../src'
Expand Down Expand Up @@ -107,12 +107,17 @@ describe('element', () => {
})

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

const wrapper = mount(Root)
expect(wrapper.element.innerHTML).toBe('<div>foo</div><div>bar</div>')
// we're expecting a warning from Vue as we're using non-function slots
expect(spy.mock.calls[0][0]).toContain(
'Non-function value encountered for default slot'
)
})
})
7 changes: 6 additions & 1 deletion tests/findAllComponents.spec.ts
@@ -1,4 +1,4 @@
import { describe, expect, it } from 'vitest'
import { describe, expect, it, vi } from 'vitest'
import { mount } from '../src'
import Hello from './components/Hello.vue'
import { DefineComponent, defineComponent, h } from 'vue'
Expand Down Expand Up @@ -100,6 +100,7 @@ describe('findAllComponents', () => {
})

it('findAllComponents with non-function slots', () => {
const spy = vi.spyOn(console, 'warn').mockImplementation(() => {})
const ComponentA = defineComponent({
template: '<div><slot /></div>'
})
Expand All @@ -119,5 +120,9 @@ describe('findAllComponents', () => {
})
expect(wrapper.findAll('span')).toHaveLength(3)
expect(wrapper.findAllComponents(ComponentB)).toHaveLength(3)
// we're expecting a warning from Vue as we're using non-function slots
expect(spy.mock.calls[0][0]).toContain(
'Non-function value encountered for default slot'
)
})
})
4 changes: 4 additions & 0 deletions tests/mountingOptions/global.stubs.spec.ts
Expand Up @@ -512,6 +512,7 @@ describe('mounting options: stubs', () => {
})

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

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