Skip to content

Commit 7b9faae

Browse files
authored
test: cover lazy errorComponent behavior across frameworks (#7068)
1 parent 9368c5f commit 7b9faae

File tree

3 files changed

+374
-296
lines changed

3 files changed

+374
-296
lines changed

packages/react-router/tests/errorComponent.test.tsx

Lines changed: 126 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Link,
66
RouterProvider,
77
createBrowserHistory,
8+
createLazyRoute,
89
createRootRoute,
910
createRoute,
1011
createRouter,
@@ -38,110 +39,135 @@ afterEach(() => {
3839
cleanup()
3940
})
4041

41-
describe.each([{ preload: false }, { preload: 'intent' }] as const)(
42-
'errorComponent is rendered when the preload=$preload',
43-
(options) => {
44-
describe.each([true, false])('with async=%s', (isAsync) => {
45-
const throwableFn = isAsync ? asyncToThrowFn : throwFn
46-
47-
const callers = [
48-
{ caller: 'beforeLoad', testFn: throwableFn },
49-
{ caller: 'loader', testFn: throwableFn },
50-
]
51-
52-
test.each(callers)(
53-
'an Error is thrown on navigate in the route $caller function',
54-
async ({ caller, testFn }) => {
55-
const rootRoute = createRootRoute()
56-
const indexRoute = createRoute({
57-
getParentRoute: () => rootRoute,
58-
path: '/',
59-
component: function Home() {
60-
return (
61-
<div>
62-
<Link to="/about">link to about</Link>
63-
</div>
42+
describe.each([true, false])(
43+
'with lazy errorComponent=%s',
44+
(isUsingLazyError) => {
45+
describe.each([{ preload: false }, { preload: 'intent' }] as const)(
46+
'errorComponent is rendered when the preload=$preload',
47+
(options) => {
48+
describe.each([true, false])('with async=%s', (isAsync) => {
49+
const throwableFn = isAsync ? asyncToThrowFn : throwFn
50+
51+
const callers = [
52+
{ caller: 'beforeLoad', testFn: throwableFn },
53+
{ caller: 'loader', testFn: throwableFn },
54+
]
55+
56+
test.each(callers)(
57+
'an Error is thrown on navigate in the route $caller function',
58+
async ({ caller, testFn }) => {
59+
const rootRoute = createRootRoute()
60+
const indexRoute = createRoute({
61+
getParentRoute: () => rootRoute,
62+
path: '/',
63+
component: function Home() {
64+
return (
65+
<div>
66+
<Link to="/about">link to about</Link>
67+
</div>
68+
)
69+
},
70+
})
71+
const aboutRoute = createRoute({
72+
getParentRoute: () => rootRoute,
73+
path: '/about',
74+
beforeLoad: caller === 'beforeLoad' ? testFn : undefined,
75+
loader: caller === 'loader' ? testFn : undefined,
76+
component: function Home() {
77+
return <div>About route content</div>
78+
},
79+
errorComponent: isUsingLazyError ? undefined : MyErrorComponent,
80+
})
81+
82+
if (isUsingLazyError) {
83+
aboutRoute.lazy(() =>
84+
Promise.resolve(
85+
createLazyRoute('/about')({
86+
errorComponent: MyErrorComponent,
87+
}),
88+
),
89+
)
90+
}
91+
92+
const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])
93+
94+
const router = createRouter({
95+
routeTree,
96+
defaultPreload: options.preload,
97+
history,
98+
})
99+
100+
render(<RouterProvider router={router} />)
101+
102+
const linkToAbout = await screen.findByRole('link', {
103+
name: 'link to about',
104+
})
105+
106+
expect(linkToAbout).toBeInTheDocument()
107+
fireEvent.mouseOver(linkToAbout)
108+
fireEvent.focus(linkToAbout)
109+
fireEvent.click(linkToAbout)
110+
111+
const errorComponent = await screen.findByText(
112+
`Error: error thrown`,
113+
undefined,
114+
{ timeout: 1500 },
64115
)
116+
await expect(
117+
screen.findByText('About route content'),
118+
).rejects.toThrow()
119+
expect(errorComponent).toBeInTheDocument()
65120
},
66-
})
67-
const aboutRoute = createRoute({
68-
getParentRoute: () => rootRoute,
69-
path: '/about',
70-
beforeLoad: caller === 'beforeLoad' ? testFn : undefined,
71-
loader: caller === 'loader' ? testFn : undefined,
72-
component: function Home() {
73-
return <div>About route content</div>
74-
},
75-
errorComponent: MyErrorComponent,
76-
})
77-
78-
const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])
79-
80-
const router = createRouter({
81-
routeTree,
82-
defaultPreload: options.preload,
83-
history,
84-
})
85-
86-
render(<RouterProvider router={router} />)
87-
88-
const linkToAbout = await screen.findByRole('link', {
89-
name: 'link to about',
90-
})
91-
92-
expect(linkToAbout).toBeInTheDocument()
93-
fireEvent.mouseOver(linkToAbout)
94-
fireEvent.focus(linkToAbout)
95-
fireEvent.click(linkToAbout)
96-
97-
const errorComponent = await screen.findByText(
98-
`Error: error thrown`,
99-
undefined,
100-
{ timeout: 1500 },
101121
)
102-
await expect(
103-
screen.findByText('About route content'),
104-
).rejects.toThrow()
105-
expect(errorComponent).toBeInTheDocument()
106-
},
107-
)
108-
109-
test.each(callers)(
110-
'an Error is thrown on first load in the route $caller function',
111-
async ({ caller, testFn }) => {
112-
const rootRoute = createRootRoute()
113-
const indexRoute = createRoute({
114-
getParentRoute: () => rootRoute,
115-
path: '/',
116-
beforeLoad: caller === 'beforeLoad' ? testFn : undefined,
117-
loader: caller === 'loader' ? testFn : undefined,
118-
component: function Home() {
119-
return <div>Index route content</div>
120-
},
121-
errorComponent: MyErrorComponent,
122-
})
123-
124-
const routeTree = rootRoute.addChildren([indexRoute])
125-
126-
const router = createRouter({
127-
routeTree,
128-
defaultPreload: options.preload,
129-
history,
130-
})
131122

132-
render(<RouterProvider router={router} />)
133-
134-
const errorComponent = await screen.findByText(
135-
`Error: error thrown`,
136-
undefined,
137-
{ timeout: 750 },
123+
test.each(callers)(
124+
'an Error is thrown on first load in the route $caller function',
125+
async ({ caller, testFn }) => {
126+
const rootRoute = createRootRoute()
127+
const indexRoute = createRoute({
128+
getParentRoute: () => rootRoute,
129+
path: '/',
130+
beforeLoad: caller === 'beforeLoad' ? testFn : undefined,
131+
loader: caller === 'loader' ? testFn : undefined,
132+
component: function Home() {
133+
return <div>Index route content</div>
134+
},
135+
errorComponent: isUsingLazyError ? undefined : MyErrorComponent,
136+
})
137+
138+
if (isUsingLazyError) {
139+
indexRoute.lazy(() =>
140+
Promise.resolve(
141+
createLazyRoute('/')({
142+
errorComponent: MyErrorComponent,
143+
}),
144+
),
145+
)
146+
}
147+
148+
const routeTree = rootRoute.addChildren([indexRoute])
149+
150+
const router = createRouter({
151+
routeTree,
152+
defaultPreload: options.preload,
153+
history,
154+
})
155+
156+
render(<RouterProvider router={router} />)
157+
158+
const errorComponent = await screen.findByText(
159+
`Error: error thrown`,
160+
undefined,
161+
{ timeout: 750 },
162+
)
163+
await expect(
164+
screen.findByText('Index route content'),
165+
).rejects.toThrow()
166+
expect(errorComponent).toBeInTheDocument()
167+
},
138168
)
139-
await expect(
140-
screen.findByText('Index route content'),
141-
).rejects.toThrow()
142-
expect(errorComponent).toBeInTheDocument()
143-
},
144-
)
145-
})
169+
})
170+
},
171+
)
146172
},
147173
)

0 commit comments

Comments
 (0)