diff --git a/examples/app-vitest-full/components/TestButton.vue b/examples/app-vitest-full/components/TestButton.vue
new file mode 100644
index 000000000..e0e58fba1
--- /dev/null
+++ b/examples/app-vitest-full/components/TestButton.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/examples/app-vitest-full/pages/other/options-api.vue b/examples/app-vitest-full/pages/other/options-api.vue
index a759a6352..5fa21eb93 100644
--- a/examples/app-vitest-full/pages/other/options-api.vue
+++ b/examples/app-vitest-full/pages/other/options-api.vue
@@ -1,38 +1,54 @@
- -
+
-
{{ greetingInSetup }}
- -
+
-
{{ greetingInData1 }}
- -
+
-
{{ greetingInData2 }}
- -
+
-
{{ greetingInComputed }}
- -
+
-
{{ computedData1 }}
- -
+
-
{{ computedGreetingInMethods }}
- -
+
-
{{ greetingInMethods() }}
- -
+
-
{{ returnData1() }}
- -
+
-
{{ returnComputedData1() }}
+ -
+
+
+ -
+
+
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 523985163..11503095d 100644
--- a/examples/app-vitest-full/tests/nuxt/mount-suspended.spec.ts
+++ b/examples/app-vitest-full/tests/nuxt/mount-suspended.spec.ts
@@ -1,4 +1,4 @@
-import { beforeEach, describe, expect, it } from 'vitest'
+import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
import { mountSuspended } from '@nuxt/test-utils/runtime'
@@ -82,19 +82,6 @@ describe('mountSuspended', () => {
)
})
- it('should render asyncData and other options api properties within nuxt suspense', async () => {
- const component = await mountSuspended(OptionsApiPage)
- expect(component.find('[data-testid="greetingInSetup"]').text()).toBe('Hello, setup')
- expect(component.find('[data-testid="greetingInData1"]').text()).toBe('Hello, data1')
- expect(component.find('[data-testid="greetingInData2"]').text()).toBe('Hello, overwritten by asyncData')
- expect(component.find('[data-testid="greetingInComputed"]').text()).toBe('Hello, computed property')
- expect(component.find('[data-testid="computedData1"]').text()).toBe('Hello, data1')
- expect(component.find('[data-testid="computedGreetingInMethods"]').text()).toBe('Hello, method')
- expect(component.find('[data-testid="greetingInMethods"]').text()).toBe('Hello, method')
- expect(component.find('[data-testid="returnData1"]').text()).toBe('Hello, data1')
- expect(component.find('[data-testid="returnComputedData1"]').text()).toBe('Hello, data1')
- })
-
it('can receive emitted events from components mounted within nuxt suspense', async () => {
const component = await mountSuspended(WrapperTests)
component.find('button#emitCustomEvent').trigger('click')
@@ -137,6 +124,43 @@ describe('mountSuspended', () => {
const component = await mountSuspended(DirectiveComponent)
expect(component.html()).toMatchInlineSnapshot(`"
"`)
})
+
+ describe('Options API', () => {
+ beforeEach(() => {
+ vi.spyOn(console, 'error').mockImplementation((message) => {
+ console.log('[spy] console.error has been called', message)
+ })
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ it('should render asyncData and other options api properties within nuxt suspense', async () => {
+ const component = await mountSuspended(OptionsApiPage)
+ expect(component.find('[data-testid="greeting-in-setup"]').text()).toBe('Hello, setup')
+ expect(component.find('[data-testid="greeting-in-data1"]').text()).toBe('Hello, data1')
+ expect(component.find('[data-testid="greeting-in-data2"]').text()).toBe('Hello, overwritten by asyncData')
+ expect(component.find('[data-testid="greeting-in-computed"]').text()).toBe('Hello, computed property')
+ expect(component.find('[data-testid="computed-data1"]').text()).toBe('Hello, data1')
+ expect(component.find('[data-testid="computed-greeting-in-methods"]').text()).toBe('Hello, method')
+ expect(component.find('[data-testid="greeting-in-methods"]').text()).toBe('Hello, method')
+ expect(component.find('[data-testid="return-data1"]').text()).toBe('Hello, data1')
+ expect(component.find('[data-testid="return-computed-data1"]').text()).toBe('Hello, data1')
+ })
+
+ it('should not output error when button in page is clicked', async () => {
+ const component = await mountSuspended(OptionsApiPage)
+ await component.find('[data-testid="button-in-page"]').trigger('click')
+ expect(console.error).not.toHaveBeenCalled()
+ })
+
+ it('should not output error when button in component is clicked', async () => {
+ const component = await mountSuspended(OptionsApiPage)
+ await component.find('[data-testid="test-button"]').trigger('click')
+ expect(console.error).not.toHaveBeenCalled()
+ })
+ })
})
describe.each(Object.entries(formats))(`%s`, (name, component) => {
diff --git a/examples/app-vitest-full/tests/nuxt/render-suspended.spec.ts b/examples/app-vitest-full/tests/nuxt/render-suspended.spec.ts
index 4a741c2b0..feb2595e7 100644
--- a/examples/app-vitest-full/tests/nuxt/render-suspended.spec.ts
+++ b/examples/app-vitest-full/tests/nuxt/render-suspended.spec.ts
@@ -1,4 +1,4 @@
-import { afterEach, describe, expect, it } from 'vitest'
+import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
import { renderSuspended } from '@nuxt/test-utils/runtime'
import { cleanup, fireEvent, screen, render } from '@testing-library/vue'
@@ -98,19 +98,6 @@ describe('renderSuspended', () => {
expect(screen.getByText(text)).toBeDefined()
})
- it('should render asyncData and other options api properties within nuxt suspense', async () => {
- const { getByTestId } = await renderSuspended(OptionsApiPage)
- expect(getByTestId('greetingInSetup').textContent).toBe('Hello, setup')
- expect(getByTestId('greetingInData1').textContent).toBe('Hello, data1')
- expect(getByTestId('greetingInData2').textContent).toBe('Hello, overwritten by asyncData')
- expect(getByTestId('greetingInComputed').textContent).toBe('Hello, computed property')
- expect(getByTestId('computedData1').textContent).toBe('Hello, data1')
- expect(getByTestId('computedGreetingInMethods').textContent).toBe('Hello, method')
- expect(getByTestId('greetingInMethods').textContent).toBe('Hello, method')
- expect(getByTestId('returnData1').textContent).toBe('Hello, data1')
- expect(getByTestId('returnComputedData1').textContent).toBe('Hello, data1')
- })
-
it('can receive emitted events from components rendered within nuxt suspense', async () => {
const { emitted } = await renderSuspended(WrapperTests)
const button = screen.getByRole('button', { name: 'Click me!' })
@@ -138,6 +125,43 @@ describe('renderSuspended', () => {
}
`)
})
+
+ describe('Options API', () => {
+ beforeEach(() => {
+ vi.spyOn(console, 'error').mockImplementation((message) => {
+ console.log('[spy] console.error has been called', message)
+ })
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ it('should render asyncData and other options api properties within nuxt suspense', async () => {
+ const { getByTestId } = await renderSuspended(OptionsApiPage)
+ expect(getByTestId('greeting-in-setup').textContent).toBe('Hello, setup')
+ expect(getByTestId('greeting-in-data1').textContent).toBe('Hello, data1')
+ expect(getByTestId('greeting-in-data2').textContent).toBe('Hello, overwritten by asyncData')
+ expect(getByTestId('greeting-in-computed').textContent).toBe('Hello, computed property')
+ expect(getByTestId('computed-data1').textContent).toBe('Hello, data1')
+ expect(getByTestId('computed-greeting-in-methods').textContent).toBe('Hello, method')
+ expect(getByTestId('greeting-in-methods').textContent).toBe('Hello, method')
+ expect(getByTestId('return-data1').textContent).toBe('Hello, data1')
+ expect(getByTestId('return-computed-data1').textContent).toBe('Hello, data1')
+ })
+
+ it('should not output error when button in page is clicked', async () => {
+ const { getByTestId } = await renderSuspended(OptionsApiPage)
+ await fireEvent.click(getByTestId('button-in-page'))
+ expect(console.error).not.toHaveBeenCalled()
+ })
+
+ it('should not output error when button in component is clicked', async () => {
+ const { getByTestId } = await renderSuspended(OptionsApiPage)
+ await fireEvent.click(getByTestId('test-button'))
+ expect(console.error).not.toHaveBeenCalled()
+ })
+ })
})
describe.each(Object.entries(formats))(`%s`, (name, component) => {
diff --git a/src/runtime-utils/mount.ts b/src/runtime-utils/mount.ts
index 548caa87e..d899647b0 100644
--- a/src/runtime-utils/mount.ts
+++ b/src/runtime-utils/mount.ts
@@ -135,7 +135,7 @@ export async function mountSuspended(
}
if (methods && typeof methods === 'object') {
for (const key in methods) {
- renderContext[key] = methods[key]
+ renderContext[key] = methods[key].bind(renderContext)
}
}
if (computed && typeof computed === 'object') {
diff --git a/src/runtime-utils/render.ts b/src/runtime-utils/render.ts
index 203b8190a..b9ec3a5af 100644
--- a/src/runtime-utils/render.ts
+++ b/src/runtime-utils/render.ts
@@ -157,7 +157,7 @@ export async function renderSuspended(
}
if (methods && typeof methods === 'object') {
for (const key in methods) {
- renderContext[key] = methods[key]
+ renderContext[key] = methods[key].bind(renderContext)
}
}
if (computed && typeof computed === 'object') {