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: use Teleport with disabled=true instead of stub #2632

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/vnodeTransformers/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,16 @@ export const createVNodeTransformer = ({
registerStub({ source: originalType, stub: transformedType })
// https://github.com/vuejs/test-utils/issues/1829 & https://github.com/vuejs/test-utils/issues/1888
// Teleport/KeepAlive should return child nodes as a function
if (isTeleport(originalType) || isKeepAlive(originalType)) {
if (isTeleport(originalType)) {
return [
originalType,
{ ...props, disabled: true },
children,
...restVNodeArgs
]
}

if (isKeepAlive(originalType)) {
return [transformedType, props, () => children, ...restVNodeArgs]
}
}
Expand Down
17 changes: 17 additions & 0 deletions tests/components/TeleportRemountChild.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'

const emit = defineEmits<{ myEvent: ['mount' | 'unmount'] }>()

onMounted(() => {
emit('myEvent', 'mount')
})

onUnmounted(() => {
emit('myEvent', 'unmount')
})
</script>

<template>
<span>child</span>
</template>
18 changes: 18 additions & 0 deletions tests/components/TeleportRemountParent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
import { ref } from 'vue'
import Child from './TeleportRemountChild.vue'

const parentValue = ref<Array<'mount' | 'unmount'>>([])

const handleEmit = (e: 'mount' | 'unmount') => {
parentValue.value.push(e)
}
</script>
<template>
<div>
<p id="parent-value">{{ JSON.stringify(parentValue) }}</p>
<Teleport to="#teleport-target">
<Child @my-event="handleEmit" />
</Teleport>
</div>
</template>
6 changes: 3 additions & 3 deletions tests/features/teleport.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ describe('teleport', () => {

expect(wrapper.html()).toBe(
'<div><button>Add</button>\n' +
' <teleport-stub to="body">\n' +
' <div id="count">1</div>\n' +
' </teleport-stub>\n' +
' <!--teleport start-->\n' +
' <div id="count">1</div>\n' +
' <!--teleport end-->\n' +
'</div>'
)

Expand Down
62 changes: 55 additions & 7 deletions tests/mountingOptions/global.stubs.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { h, defineComponent, defineAsyncComponent, Directive } from 'vue'
import {
h,
defineComponent,
defineAsyncComponent,
Directive,
nextTick
} from 'vue'
import { config, flushPromises, mount, RouterLinkStub } from '../../src'
import Hello from '../components/Hello.vue'
import ComponentWithoutName from '../components/ComponentWithoutName.vue'
import ComponentWithSlots from '../components/ComponentWithSlots.vue'
import ScriptSetupWithChildren from '../components/ScriptSetupWithChildren.vue'
import AutoImportScriptSetup from '../components/AutoImportScriptSetup.vue'
import TeleportRemountParent from '../components/TeleportRemountParent.vue'

describe('mounting options: stubs', () => {
const configStubsSave = config.global.stubs
Expand Down Expand Up @@ -603,9 +610,9 @@ describe('mounting options: stubs', () => {
})

expect(wrapper.html()).toBe(
'<teleport-stub to="body">\n' +
' <div id="content"></div>\n' +
'</teleport-stub>'
'<!--teleport start-->\n' +
'<div id="content"></div>\n' +
'<!--teleport end-->'
)
// Make sure that we don't have a warning when stubbing teleport
// https://github.com/vuejs/test-utils/issues/1829
Expand Down Expand Up @@ -643,11 +650,52 @@ describe('mounting options: stubs', () => {
})

expect(wrapper.html()).toBe(
'<teleport-stub to="body">\n' +
' <div id="content-global-stubs-teleport"></div>\n' +
'</teleport-stub>'
'<!--teleport start-->\n' +
'<div id="content-global-stubs-teleport"></div>\n' +
'<!--teleport end-->'
)
})

describe('should not unmount the content', () => {
it('without stub', async () => {
const div = document.createElement('div')
div.id = 'teleport-target'
document.body.appendChild(div)

const wrapper = mount(TeleportRemountParent, {
global: {
stubs: {
teleport: false
}
}
})

await nextTick()

const childElement = div.innerHTML
expect(childElement).toBe('<span>child</span>')

const parentValue = wrapper.find('#parent-value').text()
expect(JSON.parse(parentValue!)).toStrictEqual(['mount'])

document.body.innerHTML = ''
})

it('with stub', async () => {
const wrapper = mount(TeleportRemountParent, {
global: {
stubs: {
teleport: true
}
}
})

await nextTick()

const parentValue = wrapper.find('#parent-value').text()
expect(JSON.parse(parentValue)).toStrictEqual(['mount'])
})
})
})

describe('keep-alive', () => {
Expand Down