react-router 6.3.0 → 6.4.0-pre.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +12 -0
- package/CHANGELOG.md +8 -0
- package/__tests__/.eslintrc +8 -0
- package/__tests__/DataMemoryRouter-test.tsx +1902 -0
- package/__tests__/Route-test.tsx +45 -0
- package/__tests__/Router-basename-test.tsx +110 -0
- package/__tests__/Router-test.tsx +62 -0
- package/__tests__/Routes-location-test.tsx +69 -0
- package/__tests__/Routes-test.tsx +148 -0
- package/__tests__/__snapshots__/route-matching-test.tsx.snap +197 -0
- package/__tests__/absolute-path-matching-test.tsx +61 -0
- package/__tests__/createRoutesFromChildren-test.tsx +189 -0
- package/__tests__/descendant-routes-params-test.tsx +67 -0
- package/__tests__/descendant-routes-splat-matching-test.tsx +241 -0
- package/__tests__/descendant-routes-warning-test.tsx +140 -0
- package/__tests__/generatePath-test.tsx +45 -0
- package/__tests__/gh-issue-8127-test.tsx +32 -0
- package/__tests__/gh-issue-8165-test.tsx +97 -0
- package/__tests__/greedy-matching-test.tsx +89 -0
- package/__tests__/index-routes-test.tsx +24 -0
- package/__tests__/layout-routes-test.tsx +283 -0
- package/__tests__/matchPath-test.tsx +335 -0
- package/__tests__/matchRoutes-test.tsx +144 -0
- package/__tests__/navigate-test.tsx +49 -0
- package/__tests__/params-decode-test.tsx +36 -0
- package/__tests__/path-matching-test.tsx +270 -0
- package/__tests__/resolvePath-test.tsx +50 -0
- package/__tests__/route-depth-order-matching-test.tsx +135 -0
- package/__tests__/route-matching-test.tsx +164 -0
- package/__tests__/same-component-lifecycle-test.tsx +57 -0
- package/__tests__/setup.ts +15 -0
- package/__tests__/useHref-basename-test.tsx +351 -0
- package/__tests__/useHref-test.tsx +287 -0
- package/__tests__/useLocation-test.tsx +29 -0
- package/__tests__/useMatch-test.tsx +137 -0
- package/__tests__/useNavigate-test.tsx +100 -0
- package/__tests__/useOutlet-test.tsx +355 -0
- package/__tests__/useParams-test.tsx +212 -0
- package/__tests__/useResolvedPath-test.tsx +109 -0
- package/__tests__/useRoutes-test.tsx +122 -0
- package/__tests__/utils/renderStrict.tsx +21 -0
- package/__tests__/utils/waitForRedirect.tsx +5 -0
- package/index.ts +187 -0
- package/jest-transformer.js +10 -0
- package/jest.config.js +10 -0
- package/lib/components.tsx +491 -0
- package/lib/context.ts +96 -0
- package/lib/hooks.tsx +689 -0
- package/lib/use-sync-external-store-shim/index.ts +31 -0
- package/lib/use-sync-external-store-shim/useSyncExternalStoreShimClient.ts +153 -0
- package/lib/use-sync-external-store-shim/useSyncExternalStoreShimServer.ts +20 -0
- package/node-main.js +7 -0
- package/package.json +7 -4
- package/tsconfig.json +20 -0
- package/LICENSE.md +0 -22
- package/index.d.ts +0 -14
- package/index.js +0 -941
- package/index.js.map +0 -1
- package/lib/components.d.ts +0 -110
- package/lib/context.d.ts +0 -31
- package/lib/hooks.d.ts +0 -99
- package/lib/router.d.ts +0 -120
- package/main.js +0 -19
- package/react-router.development.js +0 -895
- package/react-router.development.js.map +0 -1
- package/react-router.production.min.js +0 -12
- package/react-router.production.min.js.map +0 -1
- package/umd/react-router.development.js +0 -990
- package/umd/react-router.development.js.map +0 -1
- package/umd/react-router.production.min.js +0 -12
- package/umd/react-router.production.min.js.map +0 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as TestRenderer from "react-test-renderer";
|
|
3
|
+
import { MemoryRouter, PathMatch, Routes, Route, useMatch } from "react-router";
|
|
4
|
+
|
|
5
|
+
function ShowMatch({ pattern }: { pattern: string }) {
|
|
6
|
+
return <pre>{JSON.stringify(useMatch(pattern), null, 2)}</pre>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
describe("useMatch", () => {
|
|
10
|
+
describe("when the path matches the current URL", () => {
|
|
11
|
+
it("returns the match", () => {
|
|
12
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
13
|
+
TestRenderer.act(() => {
|
|
14
|
+
renderer = TestRenderer.create(
|
|
15
|
+
<MemoryRouter initialEntries={["/home"]}>
|
|
16
|
+
<Routes>
|
|
17
|
+
<Route path="/" element={<ShowMatch pattern="home" />}>
|
|
18
|
+
<Route path="/home" element={<h1>Home</h1>} />
|
|
19
|
+
</Route>
|
|
20
|
+
</Routes>
|
|
21
|
+
</MemoryRouter>
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
26
|
+
<pre>
|
|
27
|
+
{
|
|
28
|
+
"params": {},
|
|
29
|
+
"pathname": "/home",
|
|
30
|
+
"pathnameBase": "/home",
|
|
31
|
+
"pattern": {
|
|
32
|
+
"path": "home",
|
|
33
|
+
"caseSensitive": false,
|
|
34
|
+
"end": true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
</pre>
|
|
38
|
+
`);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("when the current URL ends with a slash", () => {
|
|
43
|
+
it("returns the match.pathname with the trailing slash", () => {
|
|
44
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
45
|
+
TestRenderer.act(() => {
|
|
46
|
+
renderer = TestRenderer.create(
|
|
47
|
+
<MemoryRouter initialEntries={["/home/"]}>
|
|
48
|
+
<Routes>
|
|
49
|
+
<Route path="/" element={<ShowMatch pattern="home" />}>
|
|
50
|
+
<Route path="/home" element={<h1>Home</h1>} />
|
|
51
|
+
</Route>
|
|
52
|
+
</Routes>
|
|
53
|
+
</MemoryRouter>
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
58
|
+
<pre>
|
|
59
|
+
{
|
|
60
|
+
"params": {},
|
|
61
|
+
"pathname": "/home/",
|
|
62
|
+
"pathnameBase": "/home",
|
|
63
|
+
"pattern": {
|
|
64
|
+
"path": "home",
|
|
65
|
+
"caseSensitive": false,
|
|
66
|
+
"end": true
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
</pre>
|
|
70
|
+
`);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe("when the path does not match the current URL", () => {
|
|
75
|
+
it("returns null", () => {
|
|
76
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
77
|
+
TestRenderer.act(() => {
|
|
78
|
+
renderer = TestRenderer.create(
|
|
79
|
+
<MemoryRouter initialEntries={["/home"]}>
|
|
80
|
+
<Routes>
|
|
81
|
+
<Route path="/" element={<ShowMatch pattern="about" />}>
|
|
82
|
+
<Route path="/home" element={<h1>Home</h1>} />
|
|
83
|
+
</Route>
|
|
84
|
+
</Routes>
|
|
85
|
+
</MemoryRouter>
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
90
|
+
<pre>
|
|
91
|
+
null
|
|
92
|
+
</pre>
|
|
93
|
+
`);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe("when re-rendered with the same URL", () => {
|
|
98
|
+
it("returns the memoized match", () => {
|
|
99
|
+
let path = "/home";
|
|
100
|
+
let match: PathMatch<string>;
|
|
101
|
+
let firstMatch: PathMatch<string>;
|
|
102
|
+
|
|
103
|
+
function HomePage() {
|
|
104
|
+
match = useMatch(path);
|
|
105
|
+
|
|
106
|
+
if (!firstMatch) {
|
|
107
|
+
firstMatch = match;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
114
|
+
TestRenderer.act(() => {
|
|
115
|
+
renderer = TestRenderer.create(
|
|
116
|
+
<MemoryRouter initialEntries={[path]}>
|
|
117
|
+
<Routes>
|
|
118
|
+
<Route path={path} element={<HomePage />} />
|
|
119
|
+
</Routes>
|
|
120
|
+
</MemoryRouter>
|
|
121
|
+
);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
TestRenderer.act(() => {
|
|
125
|
+
renderer.update(
|
|
126
|
+
<MemoryRouter initialEntries={[path]}>
|
|
127
|
+
<Routes>
|
|
128
|
+
<Route path={path} element={<HomePage />} />
|
|
129
|
+
</Routes>
|
|
130
|
+
</MemoryRouter>
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
expect(match).toBe(firstMatch);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as TestRenderer from "react-test-renderer";
|
|
3
|
+
import {
|
|
4
|
+
MemoryRouter,
|
|
5
|
+
Routes,
|
|
6
|
+
Route,
|
|
7
|
+
useNavigate,
|
|
8
|
+
useLocation,
|
|
9
|
+
} from "react-router";
|
|
10
|
+
|
|
11
|
+
describe("useNavigate", () => {
|
|
12
|
+
it("navigates to the new location", () => {
|
|
13
|
+
function Home() {
|
|
14
|
+
let navigate = useNavigate();
|
|
15
|
+
|
|
16
|
+
function handleClick() {
|
|
17
|
+
navigate("/about");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div>
|
|
22
|
+
<h1>Home</h1>
|
|
23
|
+
<button onClick={handleClick}>click me</button>
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
29
|
+
TestRenderer.act(() => {
|
|
30
|
+
renderer = TestRenderer.create(
|
|
31
|
+
<MemoryRouter initialEntries={["/home"]}>
|
|
32
|
+
<Routes>
|
|
33
|
+
<Route path="home" element={<Home />} />
|
|
34
|
+
<Route path="about" element={<h1>About</h1>} />
|
|
35
|
+
</Routes>
|
|
36
|
+
</MemoryRouter>
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
let button = renderer.root.findByType("button");
|
|
41
|
+
|
|
42
|
+
TestRenderer.act(() => {
|
|
43
|
+
button.props.onClick();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
47
|
+
<h1>
|
|
48
|
+
About
|
|
49
|
+
</h1>
|
|
50
|
+
`);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe("with state", () => {
|
|
54
|
+
it("adds the state to location.state", () => {
|
|
55
|
+
function Home() {
|
|
56
|
+
let navigate = useNavigate();
|
|
57
|
+
|
|
58
|
+
function handleClick() {
|
|
59
|
+
navigate("/about", { state: { from: "home" } });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div>
|
|
64
|
+
<h1>Home</h1>
|
|
65
|
+
<button onClick={handleClick}>click me</button>
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function ShowLocationState() {
|
|
71
|
+
return <p>location.state: {JSON.stringify(useLocation().state)}</p>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
75
|
+
TestRenderer.act(() => {
|
|
76
|
+
renderer = TestRenderer.create(
|
|
77
|
+
<MemoryRouter initialEntries={["/home"]}>
|
|
78
|
+
<Routes>
|
|
79
|
+
<Route path="home" element={<Home />} />
|
|
80
|
+
<Route path="about" element={<ShowLocationState />} />
|
|
81
|
+
</Routes>
|
|
82
|
+
</MemoryRouter>
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
let button = renderer.root.findByType("button");
|
|
87
|
+
|
|
88
|
+
TestRenderer.act(() => {
|
|
89
|
+
button.props.onClick();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
93
|
+
<p>
|
|
94
|
+
location.state:
|
|
95
|
+
{"from":"home"}
|
|
96
|
+
</p>
|
|
97
|
+
`);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as TestRenderer from "react-test-renderer";
|
|
3
|
+
import {
|
|
4
|
+
MemoryRouter,
|
|
5
|
+
Routes,
|
|
6
|
+
Route,
|
|
7
|
+
useOutlet,
|
|
8
|
+
useOutletContext,
|
|
9
|
+
} from "react-router";
|
|
10
|
+
|
|
11
|
+
describe("useOutlet", () => {
|
|
12
|
+
describe("when there is no child route", () => {
|
|
13
|
+
it("returns null", () => {
|
|
14
|
+
function Home() {
|
|
15
|
+
return useOutlet();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
19
|
+
TestRenderer.act(() => {
|
|
20
|
+
renderer = TestRenderer.create(
|
|
21
|
+
<MemoryRouter initialEntries={["/home"]}>
|
|
22
|
+
<Routes>
|
|
23
|
+
<Route path="/home" element={<Home />} />
|
|
24
|
+
</Routes>
|
|
25
|
+
</MemoryRouter>
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
expect(renderer.toJSON()).toBeNull();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("renders the fallback", () => {
|
|
33
|
+
function Home() {
|
|
34
|
+
let outlet = useOutlet();
|
|
35
|
+
return <div>{outlet ? "outlet" : "no outlet"}</div>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
39
|
+
TestRenderer.act(() => {
|
|
40
|
+
renderer = TestRenderer.create(
|
|
41
|
+
<MemoryRouter initialEntries={["/home"]}>
|
|
42
|
+
<Routes>
|
|
43
|
+
<Route path="/home" element={<Home />} />
|
|
44
|
+
</Routes>
|
|
45
|
+
</MemoryRouter>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
50
|
+
<div>
|
|
51
|
+
no outlet
|
|
52
|
+
</div>
|
|
53
|
+
`);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("renders the fallback with context provided", () => {
|
|
57
|
+
function Home() {
|
|
58
|
+
let outlet = useOutlet({ some: "context" });
|
|
59
|
+
return <div>{outlet ? "outlet" : "no outlet"}</div>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
63
|
+
TestRenderer.act(() => {
|
|
64
|
+
renderer = TestRenderer.create(
|
|
65
|
+
<MemoryRouter initialEntries={["/home"]}>
|
|
66
|
+
<Routes>
|
|
67
|
+
<Route path="/home" element={<Home />} />
|
|
68
|
+
</Routes>
|
|
69
|
+
</MemoryRouter>
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
74
|
+
<div>
|
|
75
|
+
no outlet
|
|
76
|
+
</div>
|
|
77
|
+
`);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("when there is a child route", () => {
|
|
82
|
+
it("returns an element", () => {
|
|
83
|
+
function Users() {
|
|
84
|
+
return useOutlet();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
88
|
+
TestRenderer.act(() => {
|
|
89
|
+
renderer = TestRenderer.create(
|
|
90
|
+
<MemoryRouter initialEntries={["/users/profile"]}>
|
|
91
|
+
<Routes>
|
|
92
|
+
<Route path="users" element={<Users />}>
|
|
93
|
+
<Route path="profile" element={<h1>Profile</h1>} />
|
|
94
|
+
</Route>
|
|
95
|
+
</Routes>
|
|
96
|
+
</MemoryRouter>
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
101
|
+
<h1>
|
|
102
|
+
Profile
|
|
103
|
+
</h1>
|
|
104
|
+
`);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("returns an element when no context", () => {
|
|
108
|
+
function Home() {
|
|
109
|
+
let outlet = useOutlet();
|
|
110
|
+
return <div>{outlet ? "outlet" : "no outlet"}</div>;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
114
|
+
TestRenderer.act(() => {
|
|
115
|
+
renderer = TestRenderer.create(
|
|
116
|
+
<MemoryRouter initialEntries={["/home"]}>
|
|
117
|
+
<Routes>
|
|
118
|
+
<Route path="/home" element={<Home />}>
|
|
119
|
+
<Route index element={<div>index</div>} />
|
|
120
|
+
</Route>
|
|
121
|
+
</Routes>
|
|
122
|
+
</MemoryRouter>
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
127
|
+
<div>
|
|
128
|
+
outlet
|
|
129
|
+
</div>
|
|
130
|
+
`);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("returns an element when context", () => {
|
|
134
|
+
function Home() {
|
|
135
|
+
let outlet = useOutlet({ some: "context" });
|
|
136
|
+
return <div>{outlet ? "outlet" : "no outlet"}</div>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
140
|
+
TestRenderer.act(() => {
|
|
141
|
+
renderer = TestRenderer.create(
|
|
142
|
+
<MemoryRouter initialEntries={["/home"]}>
|
|
143
|
+
<Routes>
|
|
144
|
+
<Route path="/home" element={<Home />}>
|
|
145
|
+
<Route index element={<div>index</div>} />
|
|
146
|
+
</Route>
|
|
147
|
+
</Routes>
|
|
148
|
+
</MemoryRouter>
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
153
|
+
<div>
|
|
154
|
+
outlet
|
|
155
|
+
</div>
|
|
156
|
+
`);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe("OutletContext when there is no context", () => {
|
|
161
|
+
it("returns null", () => {
|
|
162
|
+
function Users() {
|
|
163
|
+
return useOutlet();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function Profile() {
|
|
167
|
+
let outletContext = useOutletContext();
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<div>
|
|
171
|
+
<h1>Profile</h1>
|
|
172
|
+
<pre>{outletContext}</pre>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
178
|
+
TestRenderer.act(() => {
|
|
179
|
+
renderer = TestRenderer.create(
|
|
180
|
+
<MemoryRouter initialEntries={["/users/profile"]}>
|
|
181
|
+
<Routes>
|
|
182
|
+
<Route path="users" element={<Users />}>
|
|
183
|
+
<Route path="profile" element={<Profile />} />
|
|
184
|
+
</Route>
|
|
185
|
+
</Routes>
|
|
186
|
+
</MemoryRouter>
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
191
|
+
<div>
|
|
192
|
+
<h1>
|
|
193
|
+
Profile
|
|
194
|
+
</h1>
|
|
195
|
+
<pre />
|
|
196
|
+
</div>
|
|
197
|
+
`);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
describe("OutletContext when there is context", () => {
|
|
202
|
+
it("returns the context", () => {
|
|
203
|
+
function Users() {
|
|
204
|
+
return useOutlet([
|
|
205
|
+
"Mary",
|
|
206
|
+
"Jane",
|
|
207
|
+
"Michael",
|
|
208
|
+
"Bert",
|
|
209
|
+
"Winifred",
|
|
210
|
+
"George",
|
|
211
|
+
]);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function Profile() {
|
|
215
|
+
let outletContext = useOutletContext<string[]>();
|
|
216
|
+
|
|
217
|
+
return (
|
|
218
|
+
<div>
|
|
219
|
+
<h1>Profile</h1>
|
|
220
|
+
<ul>
|
|
221
|
+
{outletContext.map((name) => (
|
|
222
|
+
<li key={name}>{name}</li>
|
|
223
|
+
))}
|
|
224
|
+
</ul>
|
|
225
|
+
</div>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
230
|
+
TestRenderer.act(() => {
|
|
231
|
+
renderer = TestRenderer.create(
|
|
232
|
+
<MemoryRouter initialEntries={["/users/profile"]}>
|
|
233
|
+
<Routes>
|
|
234
|
+
<Route path="users" element={<Users />}>
|
|
235
|
+
<Route path="profile" element={<Profile />} />
|
|
236
|
+
</Route>
|
|
237
|
+
</Routes>
|
|
238
|
+
</MemoryRouter>
|
|
239
|
+
);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
243
|
+
<div>
|
|
244
|
+
<h1>
|
|
245
|
+
Profile
|
|
246
|
+
</h1>
|
|
247
|
+
<ul>
|
|
248
|
+
<li>
|
|
249
|
+
Mary
|
|
250
|
+
</li>
|
|
251
|
+
<li>
|
|
252
|
+
Jane
|
|
253
|
+
</li>
|
|
254
|
+
<li>
|
|
255
|
+
Michael
|
|
256
|
+
</li>
|
|
257
|
+
<li>
|
|
258
|
+
Bert
|
|
259
|
+
</li>
|
|
260
|
+
<li>
|
|
261
|
+
Winifred
|
|
262
|
+
</li>
|
|
263
|
+
<li>
|
|
264
|
+
George
|
|
265
|
+
</li>
|
|
266
|
+
</ul>
|
|
267
|
+
</div>
|
|
268
|
+
`);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
describe("when child route without element prop", () => {
|
|
273
|
+
it("returns nested route element", () => {
|
|
274
|
+
function Layout() {
|
|
275
|
+
return useOutlet();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
279
|
+
TestRenderer.act(() => {
|
|
280
|
+
renderer = TestRenderer.create(
|
|
281
|
+
<MemoryRouter initialEntries={["/users/profile"]}>
|
|
282
|
+
<Routes>
|
|
283
|
+
<Route path="/" element={<Layout />}>
|
|
284
|
+
<Route path="users">
|
|
285
|
+
<Route path="profile" element={<h1>Profile</h1>} />
|
|
286
|
+
</Route>
|
|
287
|
+
</Route>
|
|
288
|
+
</Routes>
|
|
289
|
+
</MemoryRouter>
|
|
290
|
+
);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
294
|
+
<h1>
|
|
295
|
+
Profile
|
|
296
|
+
</h1>
|
|
297
|
+
`);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it("returns the context", () => {
|
|
301
|
+
function Layout() {
|
|
302
|
+
return useOutlet(["Mary", "Jane", "Michael"]);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function Profile() {
|
|
306
|
+
let outletContext = useOutletContext<string[]>();
|
|
307
|
+
|
|
308
|
+
return (
|
|
309
|
+
<div>
|
|
310
|
+
<h1>Profile</h1>
|
|
311
|
+
<ul>
|
|
312
|
+
{outletContext.map((name) => (
|
|
313
|
+
<li key={name}>{name}</li>
|
|
314
|
+
))}
|
|
315
|
+
</ul>
|
|
316
|
+
</div>
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
let renderer: TestRenderer.ReactTestRenderer;
|
|
321
|
+
TestRenderer.act(() => {
|
|
322
|
+
renderer = TestRenderer.create(
|
|
323
|
+
<MemoryRouter initialEntries={["/users/profile"]}>
|
|
324
|
+
<Routes>
|
|
325
|
+
<Route path="/" element={<Layout />}>
|
|
326
|
+
<Route path="users">
|
|
327
|
+
<Route path="profile" element={<Profile />} />
|
|
328
|
+
</Route>
|
|
329
|
+
</Route>
|
|
330
|
+
</Routes>
|
|
331
|
+
</MemoryRouter>
|
|
332
|
+
);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
expect(renderer.toJSON()).toMatchInlineSnapshot(`
|
|
336
|
+
<div>
|
|
337
|
+
<h1>
|
|
338
|
+
Profile
|
|
339
|
+
</h1>
|
|
340
|
+
<ul>
|
|
341
|
+
<li>
|
|
342
|
+
Mary
|
|
343
|
+
</li>
|
|
344
|
+
<li>
|
|
345
|
+
Jane
|
|
346
|
+
</li>
|
|
347
|
+
<li>
|
|
348
|
+
Michael
|
|
349
|
+
</li>
|
|
350
|
+
</ul>
|
|
351
|
+
</div>
|
|
352
|
+
`);
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
});
|