import { flushPromises, mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { Fragment, computed, defineComponent, h, ref } from 'vue'
import { useForwardExpose } from './useForwardExpose'
describe('useForwardRef', async () => {
it('should forward plain DOM element ref', async () => {
const comp = defineComponent({
setup() {
const { forwardRef } = useForwardExpose()
return { forwardRef }
},
template: `
inner element
`,
})
const wrapper = mount(
defineComponent(() => {
const el = ref()
const forwardedRef = computed(() => el.value?.$el)
return () =>
h('div', { test: forwardedRef.value }, [h(comp, { ref: el })])
}),
)
await flushPromises()
expect(wrapper.attributes('test')).toBe('[object HTMLSpanElement]')
})
it('should forward plain DOM element ref - 2', async () => {
const comp = defineComponent({
setup() {
const { forwardRef } = useForwardExpose()
return { forwardRef }
},
template: `
inner element
`,
})
const wrapper = mount(
defineComponent(() => {
const el = ref()
const forwardedRef = computed(() => el.value?.$el)
return () =>
h('div', { test: forwardedRef.value }, [h(comp, { ref: el })])
}),
)
await flushPromises()
expect(wrapper.attributes('test')).toBe('[object HTMLSpanElement]')
})
it('should forward plain DOM element ref - fragment', async () => {
const comp = defineComponent({
setup() {
const { forwardRef } = useForwardExpose()
return { forwardRef }
},
template: `
multiple node root
inner element
`,
})
const wrapper = mount(
defineComponent(() => {
const el = ref()
const forwardedRef = computed(() => el.value?.$el)
return () =>
h('div', { test: forwardedRef.value }, [h(comp, { ref: el })])
}),
)
await flushPromises()
expect(wrapper.attributes('test')).toBe('[object HTMLSpanElement]')
})
it('should forward plain DOM element ref - fragment - 2', async () => {
const Frag = defineComponent(
(props, { slots }) =>
() =>
h(Fragment, {}, [slots.default?.()]),
)
const comp = defineComponent({
components: { Frag },
setup() {
const { forwardRef } = useForwardExpose()
return { forwardRef }
},
template: `
inner element
`,
})
const wrapper = mount(
defineComponent(() => {
const el = ref()
const forwardedRef = computed(() => el.value?.$el)
return () =>
h('div', { test: forwardedRef.value }, [h(comp, { ref: el })])
}),
)
await flushPromises()
expect(wrapper.attributes('test')).toBe('[object HTMLSpanElement]')
})
it('should forward plain DOM element ref - fragment - 3', async () => {
const comp = defineComponent({
setup() {
const { forwardRef } = useForwardExpose()
return { forwardRef }
},
template: `
`,
})
const wrapper = mount(
defineComponent(() => {
const el = ref()
const forwardedRef = computed(() => el.value?.$el)
return () =>
h('div', { test: forwardedRef.value }, [h(comp, { ref: el })])
}),
)
await flushPromises()
expect(wrapper.attributes('test')).toBe('[object HTMLSpanElement]')
})
it('should forward component instance for component', async () => {
const InnerComp = defineComponent(() => {
return () => h('span', {}, 'inner component')
})
const comp = defineComponent({
setup() {
const { forwardRef } = useForwardExpose()
return { forwardRef }
},
components: { InnerComp },
template: `
`,
})
const wrapper = mount(
defineComponent(() => {
const el = ref()
const forwardedRef = computed(() => el.value?.$el)
return () =>
h('div', { test: forwardedRef.value }, [h(comp, { ref: el })])
}),
)
await flushPromises()
expect(wrapper.attributes('test')).toBe('[object HTMLSpanElement]')
})
})