Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<div>
<div id="s1">
{{ $pluginProvidedValues.value }}
</div>
<div id="s2">
{{ $pluginProvidedValues.func('value') }}
</div>
<div id="s3">
{{ $pluginProvidedValues.object.value }}
</div>
</div>
</template>
11 changes: 11 additions & 0 deletions examples/app-vitest-full/plugins/provided-values.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default defineNuxtPlugin(() => {
return {
provide: {
pluginProvidedValues: {
value: 'pluginProvided.value',
func: (value: string) => `pluginProvided.func(${value})`,
object: { value: 'pluginProvided.object.value' },
},
},
}
})
8 changes: 8 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 @@ -26,6 +26,7 @@ import ComponentWithReservedProp from '~/components/ComponentWithReservedProp.vu
import ComponentWithReservedState from '~/components/ComponentWithReservedState.vue'
import ComponentWithImports from '~/components/ComponentWithImports.vue'
import ComponentWithCssVar from '~/components/ComponentWithCssVar.vue'
import ComponentWithPluginProvidedValue from '~/components/ComponentWithPluginProvidedValue.vue'
import GenericStateComponent from '~/components/GenericStateComponent.vue'

import { BoundAttrs } from '#components'
Expand Down Expand Up @@ -284,6 +285,13 @@ describe('mountSuspended', () => {
expect(component.find('#s3').classes()).toHaveLength(0)
})

it('can mount components with use plugin provided value in template', async () => {
const component = await mountSuspended(ComponentWithPluginProvidedValue)
expect(component.find('#s1').text()).toBe('pluginProvided.value')
expect(component.find('#s2').text()).toBe('pluginProvided.func(value)')
expect(component.find('#s3').text()).toBe('pluginProvided.object.value')
})

describe('Options API', () => {
beforeEach(() => {
vi.spyOn(console, 'error').mockImplementation((message) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import ExportDefaultComponent from '~/components/ExportDefaultComponent.vue'
import ExportDefineComponent from '~/components/ExportDefineComponent.vue'
import ComponentWithAttrs from '~/components/ComponentWithAttrs.vue'
import ComponentWithCssVar from '~/components/ComponentWithCssVar.vue'
import ComponentWithPluginProvidedValue from '~/components/ComponentWithPluginProvidedValue.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 @@ -179,6 +180,13 @@ describe('renderSuspended', () => {
expect(container.querySelector('#s3')?.classList).toHaveLength(0)
})

it('can render components with use plugin provided value in template', async () => {
const { container } = await renderSuspended(ComponentWithPluginProvidedValue)
expect(container.querySelector('#s1')?.textContent).toBe('pluginProvided.value')
expect(container.querySelector('#s2')?.textContent).toBe('pluginProvided.func(value)')
expect(container.querySelector('#s3')?.textContent).toBe('pluginProvided.object.value')
})

describe('Options API', () => {
beforeEach(() => {
vi.spyOn(console, 'error').mockImplementation((message) => {
Expand Down
13 changes: 10 additions & 3 deletions src/runtime-utils/mount.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { mount } from '@vue/test-utils'
import type { ComponentMountingOptions } from '@vue/test-utils'
import { Suspense, h, isReadonly, nextTick, reactive, unref, getCurrentInstance, effectScope, isRef } from 'vue'
import type { ComponentInternalInstance, DefineComponent, SetupContext } from 'vue'
import type { App, ComponentInternalInstance, DefineComponent, SetupContext } from 'vue'
import { defu } from 'defu'
import type { RouteLocationRaw } from 'vue-router'

Expand Down Expand Up @@ -63,7 +63,7 @@ export async function mountSuspended<T>(
cleanupFunction()
}

const vueApp = tryUseNuxtApp()?.vueApp
const vueApp: App<Element> & Record<string, unknown> = tryUseNuxtApp()?.vueApp
// @ts-expect-error untyped global __unctx__
|| globalThis.__unctx__.get('nuxt-app').tryUse().vueApp
const { render, setup, data, computed, methods, ...componentRest } = component as DefineComponent<Record<string, unknown>, Record<string, unknown>>
Expand Down Expand Up @@ -261,7 +261,14 @@ export async function mountSuspended<T>(
attrs,
global: {
config: {
globalProperties: vueApp.config.globalProperties,
globalProperties: {
...vueApp.config.globalProperties,
// make all properties/keys enumerable.
...Object.fromEntries(
Object.getOwnPropertyNames(vueApp.config.globalProperties)
.map(key => [key, vueApp.config.globalProperties[key]]),
),
},
},
directives: vueApp._context.directives,
provide: vueApp._context.provides,
Expand Down
13 changes: 10 additions & 3 deletions src/runtime-utils/render.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Suspense, effectScope, h, nextTick, isReadonly, reactive, unref, defineComponent, getCurrentInstance } from 'vue'
import type { ComponentInternalInstance, DefineComponent, SetupContext } from 'vue'
import type { App, ComponentInternalInstance, DefineComponent, SetupContext } from 'vue'
import type { RenderOptions as TestingLibraryRenderOptions } from '@testing-library/vue'
import { defu } from 'defu'
import type { RouteLocationRaw } from 'vue-router'
Expand Down Expand Up @@ -59,7 +59,7 @@ export async function renderSuspended<T>(component: T, options?: RenderOptions<T

const { render: renderFromTestingLibrary } = await import('@testing-library/vue')

const vueApp = tryUseNuxtApp()?.vueApp
const vueApp: App<Element> & Record<string, unknown> = tryUseNuxtApp()?.vueApp
// @ts-expect-error untyped global __unctx__
|| globalThis.__unctx__.get('nuxt-app').tryUse().vueApp
const { render, setup, data, computed, methods, ...componentRest } = component as DefineComponent<Record<string, unknown>, Record<string, unknown>>
Expand Down Expand Up @@ -251,7 +251,14 @@ export async function renderSuspended<T>(component: T, options?: RenderOptions<T
attrs,
global: {
config: {
globalProperties: vueApp.config.globalProperties,
globalProperties: {
...vueApp.config.globalProperties,
// make all properties/keys enumerable.
...Object.fromEntries(
Object.getOwnPropertyNames(vueApp.config.globalProperties)
.map(key => [key, vueApp.config.globalProperties[key]]),
),
},
},
directives: vueApp._context.directives,
provide: vueApp._context.provides,
Expand Down
Loading