Skip to content

Commit

Permalink
fix(runtime-utils): define $attrs in component render context (#1108)
Browse files Browse the repository at this point in the history
  • Loading branch information
romhml authored Feb 1, 2025
1 parent 1821325 commit 5fe65ec
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 3 deletions.
9 changes: 9 additions & 0 deletions examples/app-vitest-full/components/ComponentWithAttrs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<span v-bind="$attrs" />
</template>

<script setup lang="ts">
defineOptions({
inheritAttrs: false,
})
</script>
6 changes: 6 additions & 0 deletions examples/app-vitest-full/tests/nuxt/mount-suspended.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import ExportDefineComponent from '~/components/ExportDefineComponent.vue'
import ExportDefaultWithRenderComponent from '~/components/ExportDefaultWithRenderComponent.vue'
import ExportDefaultReturnsRenderComponent from '~/components/ExportDefaultReturnsRenderComponent.vue'
import OptionsApiPage from '~/pages/other/options-api.vue'
import ComponentWithAttrs from '~/components/ComponentWithAttrs.vue'
import ComponentWithReservedProp from '~/components/ComponentWithReservedProp.vue'
import ComponentWithReservedState from '~/components/ComponentWithReservedState.vue'
import ComponentWithImports from '~/components/ComponentWithImports.vue'
Expand Down Expand Up @@ -159,6 +160,11 @@ describe('mountSuspended', () => {
expect(span.text()).toBe('false')
})

it('should define $attrs', async () => {
const component = await mountSuspended(ComponentWithAttrs, { attrs: { foo: 'bar' } })
expect(component.find('[foo="bar"]').exists()).toBe(true)
})

describe('Options API', () => {
beforeEach(() => {
vi.spyOn(console, 'error').mockImplementation((message) => {
Expand Down
8 changes: 8 additions & 0 deletions examples/app-vitest-full/tests/nuxt/render-suspended.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import DirectiveComponent from '~/components/DirectiveComponent.vue'

import ExportDefaultComponent from '~/components/ExportDefaultComponent.vue'
import ExportDefineComponent from '~/components/ExportDefineComponent.vue'
import ComponentWithAttrs from '~/components/ComponentWithAttrs.vue'
import ExportDefaultWithRenderComponent from '~/components/ExportDefaultWithRenderComponent.vue'
import ExportDefaultReturnsRenderComponent from '~/components/ExportDefaultReturnsRenderComponent.vue'
import OptionsApiPage from '~/pages/other/options-api.vue'
Expand Down Expand Up @@ -126,6 +127,13 @@ describe('renderSuspended', () => {
`)
})

it('should define $attrs', async () => {
const { html } = await renderSuspended(ComponentWithAttrs, { attrs: { foo: 'bar' } })
expect(html()).toMatchInlineSnapshot(`
"<div id="test-wrapper"><span foo="bar"></span></div>"
`)
})

describe('Options API', () => {
beforeEach(() => {
vi.spyOn(console, 'error').mockImplementation((message) => {
Expand Down
1 change: 1 addition & 0 deletions src/runtime-utils/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export async function mountSuspended<T>(
_options,
{
slots,
attrs,
global: {
config: {
globalProperties: vueApp.config.globalProperties,
Expand Down
12 changes: 9 additions & 3 deletions src/runtime-utils/render.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Suspense, effectScope, h, nextTick, isReadonly, reactive, unref } from 'vue'
import { Suspense, effectScope, h, nextTick, isReadonly, reactive, unref, defineComponent } from 'vue'
import type { DefineComponent, SetupContext } from 'vue'
import type { RenderOptions as TestingLibraryRenderOptions } from '@testing-library/vue'
import { defu } from 'defu'
Expand Down Expand Up @@ -85,6 +85,12 @@ export async function renderSuspended<T>(component: T, options?: RenderOptions<T
}
}

const WrapperComponent = defineComponent({
inheritAttrs: false,
render() {
return h('div', { id: WRAPPER_EL_ID }, this.$slots.default?.())
},
})
return new Promise<ReturnType<typeof renderFromTestingLibrary> & { setupState: SetupState }>((resolve) => {
const utils = renderFromTestingLibrary(
{
Expand All @@ -108,8 +114,7 @@ export async function renderSuspended<T>(component: T, options?: RenderOptions<T
// we add this additional root element because otherwise testing-library breaks
// because there's no root element while Suspense is resolving
h(
'div',
{ id: WRAPPER_EL_ID },
WrapperComponent,
h(
Suspense,
{
Expand Down Expand Up @@ -190,6 +195,7 @@ export async function renderSuspended<T>(component: T, options?: RenderOptions<T
},
defu(_options, {
slots,
attrs,
global: {
config: {
globalProperties: vueApp.config.globalProperties,
Expand Down

0 comments on commit 5fe65ec

Please sign in to comment.