diff --git a/examples/app-vitest-full/components/ExportDefaultComponent.vue b/examples/app-vitest-full/components/ExportDefaultComponent.vue index 34820af7b..06b0c1648 100644 --- a/examples/app-vitest-full/components/ExportDefaultComponent.vue +++ b/examples/app-vitest-full/components/ExportDefaultComponent.vue @@ -3,6 +3,11 @@

ExportDefaultComponent

{{ myProp }}
{{ setupMyProp }}
+ {{ item }} + @@ -22,6 +27,10 @@ export default { type: String, required: true, }, + myArrayProp: { + type: Array as PropType, + default: () => ([]), + }, }, setup(props) { return { diff --git a/examples/app-vitest-full/components/ExportDefaultReturnsRenderComponent.vue b/examples/app-vitest-full/components/ExportDefaultReturnsRenderComponent.vue index 23650a482..a1347acee 100644 --- a/examples/app-vitest-full/components/ExportDefaultReturnsRenderComponent.vue +++ b/examples/app-vitest-full/components/ExportDefaultReturnsRenderComponent.vue @@ -5,6 +5,10 @@ export default { type: String, required: true, }, + myArrayProp: { + type: Array as PropType, + default: () => ([]), + }, }, setup(props) { const pre = 'X' + props.myProp @@ -12,6 +16,7 @@ export default { h('h1', 'ExportDefaultReturnsRenderComponent'), h('pre', props.myProp), h('pre', pre), + props.myArrayProp.map(item => h('span', item)), ]) }, } diff --git a/examples/app-vitest-full/components/ExportDefaultWithRenderComponent.vue b/examples/app-vitest-full/components/ExportDefaultWithRenderComponent.vue index 45ac1fb51..57d3a469c 100644 --- a/examples/app-vitest-full/components/ExportDefaultWithRenderComponent.vue +++ b/examples/app-vitest-full/components/ExportDefaultWithRenderComponent.vue @@ -5,6 +5,10 @@ export default { type: String, required: true, }, + myArrayProp: { + type: Array as PropType, + default: () => ([]), + }, }, setup(props) { return { @@ -16,6 +20,7 @@ export default { h('h1', 'ExportDefaultWithRenderComponent'), h('pre', this.myProp), h('pre', this.setupMyProp), + this.myArrayProp.map(item => h('span', item)), ]) }, } diff --git a/examples/app-vitest-full/components/ExportDefineComponent.vue b/examples/app-vitest-full/components/ExportDefineComponent.vue index d1802358f..2f3978c93 100644 --- a/examples/app-vitest-full/components/ExportDefineComponent.vue +++ b/examples/app-vitest-full/components/ExportDefineComponent.vue @@ -3,6 +3,10 @@

ExportDefineComponent

{{ myProp }}
{{ setupMyProp }}
+ {{ item }} @@ -22,6 +26,10 @@ export default defineComponent({ type: String, required: true, }, + myArrayProp: { + type: Array as PropType, + default: () => ([]), + }, }, setup(props) { return { diff --git a/examples/app-vitest-full/tests/nuxt/mount-suspended.spec.ts b/examples/app-vitest-full/tests/nuxt/mount-suspended.spec.ts index 5e119d11f..28538d439 100644 --- a/examples/app-vitest-full/tests/nuxt/mount-suspended.spec.ts +++ b/examples/app-vitest-full/tests/nuxt/mount-suspended.spec.ts @@ -126,6 +126,7 @@ describe.each(Object.entries(formats))(`%s`, (name, component) => { wrapper = await mountSuspended(component, { props: { myProp: 'Hello nuxt-vitest', + myArrayProp: ['hello', 'nuxt', 'vitest'], }, }) }) @@ -133,7 +134,7 @@ describe.each(Object.entries(formats))(`%s`, (name, component) => { it('mounts with props', () => { expect(wrapper.html()).toEqual(`
-

${name}

Hello nuxt-vitest
XHello nuxt-vitest
+

${name}

Hello nuxt-vitest
XHello nuxt-vitest
hellonuxtvitest
`.trim()) }) @@ -144,7 +145,19 @@ describe.each(Object.entries(formats))(`%s`, (name, component) => { }) expect(wrapper.html()).toEqual(`
-

${name}

updated title
XHello nuxt-vitest
+

${name}

updated title
XHello nuxt-vitest
hellonuxtvitest +
+ `.trim()) + }) + + it('can be updated array with setProps', async () => { + await wrapper.setProps({ + myProp: 'updated title', + myArrayProp: ['updated', 'prop'], + }) + expect(wrapper.html()).toEqual(` +
+

${name}

updated title
XHello nuxt-vitest
updatedprop
`.trim()) }) diff --git a/src/runtime-utils/mount.ts b/src/runtime-utils/mount.ts index c67e34024..12b8c9ee9 100644 --- a/src/runtime-utils/mount.ts +++ b/src/runtime-utils/mount.ts @@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils' import type { ComponentMountingOptions } from '@vue/test-utils' import { Suspense, h, isReadonly, nextTick, reactive, unref } from 'vue' import type { DefineComponent, SetupContext } from 'vue' -import { defu } from 'defu' +import { defu, createDefu } from 'defu' import type { RouteLocationRaw } from 'vue-router' import { RouterLink } from './components/RouterLink' @@ -134,7 +134,7 @@ export async function mountSuspended( setup: setup ? (props: Record) => wrappedSetup(props, setupContext) : undefined, } - return () => h(clonedComponent, { ...defu(setProps, props) as typeof props, ...attrs }, slots) + return () => h(clonedComponent, { ...defuReplaceArray(setProps, props) as typeof props, ...attrs }, slots) }, }), }, @@ -167,3 +167,10 @@ interface AugmentedVueInstance { setupState?: Record __setProps?: (props: Record) => void } + +const defuReplaceArray = createDefu((obj, key, value) => { + if (Array.isArray(obj[key])) { + obj[key] = value + return true + } +})