Skip to content

Commit c6e4b78

Browse files
authored
fix(runtime-utils): avoid missing render warn on reject render + suspend helpers (#1520)
1 parent c8f881b commit c6e4b78

File tree

4 files changed

+66
-1
lines changed

4 files changed

+66
-1
lines changed

examples/app-vitest-full/tests/nuxt/mount-suspended-error.spec.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
import { describe, expect, it, vi } from 'vitest'
1+
import { afterEach, describe, expect, it, vi } from 'vitest'
22

33
import { Suspense } from 'vue'
44
import { mount } from '@vue/test-utils'
55
import { mountSuspended } from '@nuxt/test-utils/runtime'
66
import { NuxtErrorBoundary } from '#components'
77

88
describe('mountSuspended handle error', () => {
9+
afterEach(() => {
10+
vi.restoreAllMocks()
11+
})
12+
913
describe('vue/test-utils compatibility', () => {
1014
it('throws on mounted', async () => {
1115
const TestComponent = defineComponent({
@@ -288,5 +292,33 @@ describe('mountSuspended handle error', () => {
288292

289293
expect((await mountSuspended(TestComponent)).text()).toBe('error')
290294
})
295+
296+
it('throws on router', async () => {
297+
const setupFn = vi.fn()
298+
const consoleWarn = vi.spyOn(console, 'warn')
299+
300+
useRouter().addRoute({
301+
path: '/throws-on-router',
302+
component: h('div', 'hello'),
303+
meta: {
304+
middleware: [
305+
() => abortNavigation({ message: 'throws on router' }),
306+
],
307+
},
308+
})
309+
310+
const TestComponent = defineComponent({
311+
template: '<div></div>',
312+
setup: setupFn,
313+
})
314+
315+
await expect(() => mountSuspended(TestComponent, { route: 'throws-on-router' })).rejects.toThrow('throws on router')
316+
await nextTick()
317+
318+
expect(setupFn).not.toBeCalled()
319+
expect(
320+
consoleWarn.mock.calls.flat().map(String).join('\n'),
321+
).not.toContain('[Vue warn]: Component is missing template or render function')
322+
})
291323
})
292324
})

examples/app-vitest-full/tests/nuxt/render-suspended-error.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ function testWrapHtml(html: string) {
1616
describe('renderSuspended handle error', () => {
1717
afterEach(() => {
1818
cleanup()
19+
vi.restoreAllMocks()
1920
})
2021

2122
describe('@testing-library/vue compatibility', () => {
@@ -302,5 +303,33 @@ describe('renderSuspended handle error', () => {
302303

303304
expect((await renderSuspended(TestComponent)).container.textContent).toBe('error')
304305
})
306+
307+
it('throws on router', async () => {
308+
const setupFn = vi.fn()
309+
const consoleWarn = vi.spyOn(console, 'warn')
310+
311+
useRouter().addRoute({
312+
path: '/throws-on-router',
313+
component: h('div', 'hello'),
314+
meta: {
315+
middleware: [
316+
() => abortNavigation({ message: 'throws on router' }),
317+
],
318+
},
319+
})
320+
321+
const TestComponent = defineComponent({
322+
template: '<div></div>',
323+
setup: setupFn,
324+
})
325+
326+
await expect(() => renderSuspended(TestComponent, { route: 'throws-on-router' })).rejects.toThrow('throws on router')
327+
await nextTick()
328+
329+
expect(setupFn).not.toBeCalled()
330+
expect(
331+
consoleWarn.mock.calls.flat().map(String).join('\n'),
332+
).not.toContain('[Vue warn]: Component is missing template or render function')
333+
})
305334
})
306335
})

src/runtime-utils/mount.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ export async function mountSuspended<T>(
180180
{
181181
onResolve: () =>
182182
nextTick().then(() => {
183+
if (isMountSettled) return
183184
isMountSettled = true;
184185
(vm as unknown as AugmentedVueInstance).setupState = setupState;
185186
(vm as unknown as AugmentedVueInstance).__setProps = (props: Record<string, unknown>) => {
@@ -192,6 +193,7 @@ export async function mountSuspended<T>(
192193
default: () =>
193194
h({
194195
name: 'MountSuspendedHelper',
196+
render: () => '',
195197
async setup() {
196198
const router = useRouter()
197199
await router.replace(route)

src/runtime-utils/render.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export async function renderSuspended<T>(component: T, options?: RenderSuspendeO
168168
{
169169
onResolve: () =>
170170
nextTick().then(() => {
171+
if (isMountSettled) return
171172
isMountSettled = true;
172173
(utils as unknown as AugmentedVueInstance).setupState = setupState
173174
utils.rerender = async (props) => {
@@ -181,6 +182,7 @@ export async function renderSuspended<T>(component: T, options?: RenderSuspendeO
181182
default: () =>
182183
h({
183184
name: 'RenderHelper',
185+
render: () => '',
184186
async setup() {
185187
const router = useRouter()
186188
await router.replace(route)

0 commit comments

Comments
 (0)