Skip to content

Commit

Permalink
fix(runtime): do not assign readonly setup state
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Dec 18, 2023
1 parent 87af917 commit 8d79927
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
23 changes: 23 additions & 0 deletions examples/app-vitest-full/components/BoundAttrs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template>
<button :type="type" v-bind="attrs" />
</template>

<script lang="ts">
import { computed, defineComponent } from 'vue'
export default defineComponent({
props: {
type: {
type: String as () => 'button',
default: 'button'
}
},
setup () {
return {
attrs: computed(() => ({
'data-test': 'true'
}))
}
}
})
</script>
9 changes: 9 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,8 @@ import ExportDefineComponent from '~/components/ExportDefineComponent.vue'
import ExportDefaultWithRenderComponent from '~/components/ExportDefaultWithRenderComponent.vue'
import ExportDefaultReturnsRenderComponent from '~/components/ExportDefaultReturnsRenderComponent.vue'

import { BoundAttrs } from '#components'

const formats = {
ExportDefaultComponent,
ExportDefineComponent,
Expand All @@ -32,6 +34,13 @@ describe('mountSuspended', () => {
`)
})

it('should handle passing setup state and props to template', async () => {
const wrappedComponent = await mountSuspended(BoundAttrs)
const component = mount(BoundAttrs)

expect(component.html()).toEqual(wrappedComponent.html())
})

it('should work with shallow mounting within suspense', async () => {
const component = await mountSuspended(App, { shallow: true })
expect(component.html()).toMatchInlineSnapshot(`
Expand Down
11 changes: 8 additions & 3 deletions src/runtime-utils/mount.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { mount } from '@vue/test-utils'
import type { ComponentMountingOptions } from '@vue/test-utils'
import { Suspense, h, nextTick } from 'vue'
import { Suspense, h, nextTick, isReadonly } from 'vue'
import type { DefineComponent, SetupContext } from 'vue'
import { defu } from 'defu'
import type { RouteLocationRaw } from 'vue-router'
Expand Down Expand Up @@ -60,10 +60,12 @@ export async function mountSuspended<T>(
let setupContext: SetupContext
let setupState: any

let passedProps: Record<string, any>
const wrappedSetup = async (
props: Record<string, any>,
setupContext: SetupContext
) => {
passedProps = props
if (setup) {
setupState = await setup(props, setupContext)
return setupState
Expand Down Expand Up @@ -105,11 +107,14 @@ export async function mountSuspended<T>(
...component,
render: render
? function (this: any, _ctx: any, ...args: any[]) {
for (const key in setupState || {}) {
renderContext[key] = isReadonly(setupState[key]) ? unref(setupState[key]) : setupState[key]
}
for (const key in props || {}) {
renderContext[key] = _ctx[key]
}
for (const key in setupState || {}) {
renderContext[key] = setupState[key]
for (const key in passedProps || {}) {
renderContext[key] = passedProps[key]
}
return render.call(this, renderContext, ...args)
}
Expand Down

0 comments on commit 8d79927

Please sign in to comment.