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.
Files changed (71) hide show
  1. package/.eslintrc +12 -0
  2. package/CHANGELOG.md +8 -0
  3. package/__tests__/.eslintrc +8 -0
  4. package/__tests__/DataMemoryRouter-test.tsx +1902 -0
  5. package/__tests__/Route-test.tsx +45 -0
  6. package/__tests__/Router-basename-test.tsx +110 -0
  7. package/__tests__/Router-test.tsx +62 -0
  8. package/__tests__/Routes-location-test.tsx +69 -0
  9. package/__tests__/Routes-test.tsx +148 -0
  10. package/__tests__/__snapshots__/route-matching-test.tsx.snap +197 -0
  11. package/__tests__/absolute-path-matching-test.tsx +61 -0
  12. package/__tests__/createRoutesFromChildren-test.tsx +189 -0
  13. package/__tests__/descendant-routes-params-test.tsx +67 -0
  14. package/__tests__/descendant-routes-splat-matching-test.tsx +241 -0
  15. package/__tests__/descendant-routes-warning-test.tsx +140 -0
  16. package/__tests__/generatePath-test.tsx +45 -0
  17. package/__tests__/gh-issue-8127-test.tsx +32 -0
  18. package/__tests__/gh-issue-8165-test.tsx +97 -0
  19. package/__tests__/greedy-matching-test.tsx +89 -0
  20. package/__tests__/index-routes-test.tsx +24 -0
  21. package/__tests__/layout-routes-test.tsx +283 -0
  22. package/__tests__/matchPath-test.tsx +335 -0
  23. package/__tests__/matchRoutes-test.tsx +144 -0
  24. package/__tests__/navigate-test.tsx +49 -0
  25. package/__tests__/params-decode-test.tsx +36 -0
  26. package/__tests__/path-matching-test.tsx +270 -0
  27. package/__tests__/resolvePath-test.tsx +50 -0
  28. package/__tests__/route-depth-order-matching-test.tsx +135 -0
  29. package/__tests__/route-matching-test.tsx +164 -0
  30. package/__tests__/same-component-lifecycle-test.tsx +57 -0
  31. package/__tests__/setup.ts +15 -0
  32. package/__tests__/useHref-basename-test.tsx +351 -0
  33. package/__tests__/useHref-test.tsx +287 -0
  34. package/__tests__/useLocation-test.tsx +29 -0
  35. package/__tests__/useMatch-test.tsx +137 -0
  36. package/__tests__/useNavigate-test.tsx +100 -0
  37. package/__tests__/useOutlet-test.tsx +355 -0
  38. package/__tests__/useParams-test.tsx +212 -0
  39. package/__tests__/useResolvedPath-test.tsx +109 -0
  40. package/__tests__/useRoutes-test.tsx +122 -0
  41. package/__tests__/utils/renderStrict.tsx +21 -0
  42. package/__tests__/utils/waitForRedirect.tsx +5 -0
  43. package/index.ts +187 -0
  44. package/jest-transformer.js +10 -0
  45. package/jest.config.js +10 -0
  46. package/lib/components.tsx +491 -0
  47. package/lib/context.ts +96 -0
  48. package/lib/hooks.tsx +689 -0
  49. package/lib/use-sync-external-store-shim/index.ts +31 -0
  50. package/lib/use-sync-external-store-shim/useSyncExternalStoreShimClient.ts +153 -0
  51. package/lib/use-sync-external-store-shim/useSyncExternalStoreShimServer.ts +20 -0
  52. package/node-main.js +7 -0
  53. package/package.json +7 -4
  54. package/tsconfig.json +20 -0
  55. package/LICENSE.md +0 -22
  56. package/index.d.ts +0 -14
  57. package/index.js +0 -941
  58. package/index.js.map +0 -1
  59. package/lib/components.d.ts +0 -110
  60. package/lib/context.d.ts +0 -31
  61. package/lib/hooks.d.ts +0 -99
  62. package/lib/router.d.ts +0 -120
  63. package/main.js +0 -19
  64. package/react-router.development.js +0 -895
  65. package/react-router.development.js.map +0 -1
  66. package/react-router.production.min.js +0 -12
  67. package/react-router.production.min.js.map +0 -1
  68. package/umd/react-router.development.js +0 -990
  69. package/umd/react-router.development.js.map +0 -1
  70. package/umd/react-router.production.min.js +0 -12
  71. package/umd/react-router.production.min.js.map +0 -1
@@ -0,0 +1,351 @@
1
+ import * as React from "react";
2
+ import * as TestRenderer from "react-test-renderer";
3
+ import { MemoryRouter, Routes, Route, useHref } from "react-router";
4
+
5
+ function ShowHref({ to }: { to: string }) {
6
+ return <p>{useHref(to)}</p>;
7
+ }
8
+
9
+ describe("useHref under a basename", () => {
10
+ describe("to an absolute route", () => {
11
+ it("returns the correct href", () => {
12
+ let renderer: TestRenderer.ReactTestRenderer;
13
+ TestRenderer.act(() => {
14
+ renderer = TestRenderer.create(
15
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
16
+ <Routes>
17
+ <Route path="admin" element={<ShowHref to="/invoices" />} />
18
+ </Routes>
19
+ </MemoryRouter>
20
+ );
21
+ });
22
+
23
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
24
+ <p>
25
+ /app/invoices
26
+ </p>
27
+ `);
28
+ });
29
+ });
30
+
31
+ describe("to a child route", () => {
32
+ it("returns the correct href", () => {
33
+ let renderer: TestRenderer.ReactTestRenderer;
34
+ TestRenderer.act(() => {
35
+ renderer = TestRenderer.create(
36
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
37
+ <Routes>
38
+ <Route path="admin" element={<ShowHref to="invoices" />} />
39
+ </Routes>
40
+ </MemoryRouter>
41
+ );
42
+ });
43
+
44
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
45
+ <p>
46
+ /app/admin/invoices
47
+ </p>
48
+ `);
49
+ });
50
+
51
+ describe("when the URL has a trailing slash", () => {
52
+ it("returns the correct href", () => {
53
+ let renderer: TestRenderer.ReactTestRenderer;
54
+ TestRenderer.act(() => {
55
+ renderer = TestRenderer.create(
56
+ <MemoryRouter basename="/app" initialEntries={["/app/admin/"]}>
57
+ <Routes>
58
+ <Route path="admin" element={<ShowHref to="invoices" />} />
59
+ </Routes>
60
+ </MemoryRouter>
61
+ );
62
+ });
63
+
64
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
65
+ <p>
66
+ /app/admin/invoices
67
+ </p>
68
+ `);
69
+ });
70
+ });
71
+
72
+ describe("when the href has a trailing slash", () => {
73
+ it("returns the correct href", () => {
74
+ let renderer: TestRenderer.ReactTestRenderer;
75
+ TestRenderer.act(() => {
76
+ renderer = TestRenderer.create(
77
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
78
+ <Routes>
79
+ <Route path="admin" element={<ShowHref to="invoices/" />} />
80
+ </Routes>
81
+ </MemoryRouter>
82
+ );
83
+ });
84
+
85
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
86
+ <p>
87
+ /app/admin/invoices/
88
+ </p>
89
+ `);
90
+ });
91
+ });
92
+ });
93
+
94
+ describe("to a sibling route", () => {
95
+ it("returns the correct href", () => {
96
+ let renderer: TestRenderer.ReactTestRenderer;
97
+ TestRenderer.act(() => {
98
+ renderer = TestRenderer.create(
99
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
100
+ <Routes>
101
+ <Route path="admin" element={<ShowHref to="../dashboard" />} />
102
+ </Routes>
103
+ </MemoryRouter>
104
+ );
105
+ });
106
+
107
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
108
+ <p>
109
+ /app/dashboard
110
+ </p>
111
+ `);
112
+ });
113
+
114
+ describe("when the URL has a trailing slash", () => {
115
+ it("returns the correct href", () => {
116
+ let renderer: TestRenderer.ReactTestRenderer;
117
+ TestRenderer.act(() => {
118
+ renderer = TestRenderer.create(
119
+ <MemoryRouter basename="/app" initialEntries={["/app/admin/"]}>
120
+ <Routes>
121
+ <Route path="admin" element={<ShowHref to="../dashboard" />} />
122
+ </Routes>
123
+ </MemoryRouter>
124
+ );
125
+ });
126
+
127
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
128
+ <p>
129
+ /app/dashboard
130
+ </p>
131
+ `);
132
+ });
133
+ });
134
+
135
+ describe("when the href has a trailing slash", () => {
136
+ it("returns the correct href", () => {
137
+ let renderer: TestRenderer.ReactTestRenderer;
138
+ TestRenderer.act(() => {
139
+ renderer = TestRenderer.create(
140
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
141
+ <Routes>
142
+ <Route path="admin" element={<ShowHref to="../dashboard/" />} />
143
+ </Routes>
144
+ </MemoryRouter>
145
+ );
146
+ });
147
+
148
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
149
+ <p>
150
+ /app/dashboard/
151
+ </p>
152
+ `);
153
+ });
154
+ });
155
+ });
156
+
157
+ describe("to a parent route", () => {
158
+ it("returns the correct href", () => {
159
+ let renderer: TestRenderer.ReactTestRenderer;
160
+ TestRenderer.act(() => {
161
+ renderer = TestRenderer.create(
162
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
163
+ <Routes>
164
+ <Route path="admin" element={<ShowHref to=".." />} />
165
+ </Routes>
166
+ </MemoryRouter>
167
+ );
168
+ });
169
+
170
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
171
+ <p>
172
+ /app
173
+ </p>
174
+ `);
175
+ });
176
+
177
+ describe("when the URL has a trailing slash", () => {
178
+ it("returns the correct href", () => {
179
+ let renderer: TestRenderer.ReactTestRenderer;
180
+ TestRenderer.act(() => {
181
+ renderer = TestRenderer.create(
182
+ <MemoryRouter basename="/app" initialEntries={["/app/admin/"]}>
183
+ <Routes>
184
+ <Route path="admin" element={<ShowHref to=".." />} />
185
+ </Routes>
186
+ </MemoryRouter>
187
+ );
188
+ });
189
+
190
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
191
+ <p>
192
+ /app
193
+ </p>
194
+ `);
195
+ });
196
+ });
197
+
198
+ describe("when the href has a trailing slash", () => {
199
+ it("returns the correct href", () => {
200
+ let renderer: TestRenderer.ReactTestRenderer;
201
+ TestRenderer.act(() => {
202
+ renderer = TestRenderer.create(
203
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
204
+ <Routes>
205
+ <Route path="admin" element={<ShowHref to="../" />} />
206
+ </Routes>
207
+ </MemoryRouter>
208
+ );
209
+ });
210
+
211
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
212
+ <p>
213
+ /app/
214
+ </p>
215
+ `);
216
+ });
217
+ });
218
+ });
219
+
220
+ describe("with a to value that has more .. segments than the current URL", () => {
221
+ it("returns the correct href", () => {
222
+ let renderer: TestRenderer.ReactTestRenderer;
223
+ TestRenderer.act(() => {
224
+ renderer = TestRenderer.create(
225
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
226
+ <Routes>
227
+ <Route
228
+ path="admin"
229
+ element={<ShowHref to="../../../dashboard" />}
230
+ />
231
+ </Routes>
232
+ </MemoryRouter>
233
+ );
234
+ });
235
+
236
+ // This is correct because the basename works like a chroot "jail".
237
+ // Relative <Link to> values cannot "escape" into a higher level URL since
238
+ // they would be linking to a URL that the <Router> cannot render. To link
239
+ // to a higher URL path, use a plain <a>.
240
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
241
+ <p>
242
+ /app/dashboard
243
+ </p>
244
+ `);
245
+ });
246
+
247
+ describe("and no additional segments", () => {
248
+ it("returns the correct href", () => {
249
+ let renderer: TestRenderer.ReactTestRenderer;
250
+ TestRenderer.act(() => {
251
+ renderer = TestRenderer.create(
252
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
253
+ <Routes>
254
+ <Route path="admin" element={<ShowHref to="../../.." />} />
255
+ </Routes>
256
+ </MemoryRouter>
257
+ );
258
+ });
259
+
260
+ // This is correct because the basename works like a chroot "jail".
261
+ // Relative <Link to> values cannot "escape" into a higher level URL
262
+ // since they would be linking to a URL that the <Router> cannot render.
263
+ // To link to a higher URL path, use a plain <a>.
264
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
265
+ <p>
266
+ /app
267
+ </p>
268
+ `);
269
+ });
270
+ });
271
+
272
+ describe("when the URL has a trailing slash", () => {
273
+ it("returns the correct href", () => {
274
+ let renderer: TestRenderer.ReactTestRenderer;
275
+ TestRenderer.act(() => {
276
+ renderer = TestRenderer.create(
277
+ <MemoryRouter basename="/app" initialEntries={["/app/admin/"]}>
278
+ <Routes>
279
+ <Route
280
+ path="admin"
281
+ element={<ShowHref to="../../../dashboard" />}
282
+ />
283
+ </Routes>
284
+ </MemoryRouter>
285
+ );
286
+ });
287
+
288
+ // This is correct because the basename works like a chroot "jail".
289
+ // Relative <Link to> values cannot "escape" into a higher level URL
290
+ // since they would be linking to a URL that the <Router> cannot render.
291
+ // To link to a higher URL path, use a plain <a>.
292
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
293
+ <p>
294
+ /app/dashboard
295
+ </p>
296
+ `);
297
+ });
298
+ });
299
+
300
+ describe("when the href has a trailing slash", () => {
301
+ it("returns the correct href", () => {
302
+ let renderer: TestRenderer.ReactTestRenderer;
303
+ TestRenderer.act(() => {
304
+ renderer = TestRenderer.create(
305
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
306
+ <Routes>
307
+ <Route
308
+ path="admin"
309
+ element={<ShowHref to="../../../dashboard/" />}
310
+ />
311
+ </Routes>
312
+ </MemoryRouter>
313
+ );
314
+ });
315
+
316
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
317
+ <p>
318
+ /app/dashboard/
319
+ </p>
320
+ `);
321
+ });
322
+ });
323
+ });
324
+
325
+ describe("after an update", () => {
326
+ it("does not change", () => {
327
+ let element = (
328
+ <MemoryRouter basename="/app" initialEntries={["/app/admin"]}>
329
+ <Routes>
330
+ <Route path="admin" element={<ShowHref to="/invoices" />} />
331
+ </Routes>
332
+ </MemoryRouter>
333
+ );
334
+
335
+ let renderer: TestRenderer.ReactTestRenderer;
336
+ TestRenderer.act(() => {
337
+ renderer = TestRenderer.create(element);
338
+ });
339
+
340
+ TestRenderer.act(() => {
341
+ renderer.update(element);
342
+ });
343
+
344
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
345
+ <p>
346
+ /app/invoices
347
+ </p>
348
+ `);
349
+ });
350
+ });
351
+ });
@@ -0,0 +1,287 @@
1
+ import * as React from "react";
2
+ import * as TestRenderer from "react-test-renderer";
3
+ import { MemoryRouter, Routes, Route, useHref } from "react-router";
4
+
5
+ function ShowHref({ to }: { to: string }) {
6
+ return <pre>{useHref(to)}</pre>;
7
+ }
8
+
9
+ describe("useHref", () => {
10
+ describe("to a child route", () => {
11
+ it("returns the correct href", () => {
12
+ let renderer: TestRenderer.ReactTestRenderer;
13
+ TestRenderer.act(() => {
14
+ renderer = TestRenderer.create(
15
+ <MemoryRouter initialEntries={["/courses"]}>
16
+ <Routes>
17
+ <Route
18
+ path="courses"
19
+ element={<ShowHref to="advanced-react" />}
20
+ />
21
+ </Routes>
22
+ </MemoryRouter>
23
+ );
24
+ });
25
+
26
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
27
+ <pre>
28
+ /courses/advanced-react
29
+ </pre>
30
+ `);
31
+ });
32
+
33
+ describe("when the URL has a trailing slash", () => {
34
+ it("returns the correct href", () => {
35
+ let renderer: TestRenderer.ReactTestRenderer;
36
+ TestRenderer.act(() => {
37
+ renderer = TestRenderer.create(
38
+ <MemoryRouter initialEntries={["/courses/"]}>
39
+ <Routes>
40
+ <Route
41
+ path="courses"
42
+ element={<ShowHref to="advanced-react" />}
43
+ />
44
+ </Routes>
45
+ </MemoryRouter>
46
+ );
47
+ });
48
+
49
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
50
+ <pre>
51
+ /courses/advanced-react
52
+ </pre>
53
+ `);
54
+ });
55
+ });
56
+
57
+ describe("when the href has a trailing slash", () => {
58
+ it("returns the correct href", () => {
59
+ let renderer: TestRenderer.ReactTestRenderer;
60
+ TestRenderer.act(() => {
61
+ renderer = TestRenderer.create(
62
+ <MemoryRouter initialEntries={["/courses"]}>
63
+ <Routes>
64
+ <Route
65
+ path="courses"
66
+ element={<ShowHref to="advanced-react/" />}
67
+ />
68
+ </Routes>
69
+ </MemoryRouter>
70
+ );
71
+ });
72
+
73
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
74
+ <pre>
75
+ /courses/advanced-react/
76
+ </pre>
77
+ `);
78
+ });
79
+ });
80
+ });
81
+
82
+ describe("to a sibling route", () => {
83
+ it("returns the correct href", () => {
84
+ let renderer: TestRenderer.ReactTestRenderer;
85
+ TestRenderer.act(() => {
86
+ renderer = TestRenderer.create(
87
+ <MemoryRouter initialEntries={["/courses"]}>
88
+ <Routes>
89
+ <Route path="courses" element={<ShowHref to="../about" />} />
90
+ </Routes>
91
+ </MemoryRouter>
92
+ );
93
+ });
94
+
95
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
96
+ <pre>
97
+ /about
98
+ </pre>
99
+ `);
100
+ });
101
+
102
+ describe("when the URL has a trailing slash", () => {
103
+ it("returns the correct href", () => {
104
+ let renderer: TestRenderer.ReactTestRenderer;
105
+ TestRenderer.act(() => {
106
+ renderer = TestRenderer.create(
107
+ <MemoryRouter initialEntries={["/courses/"]}>
108
+ <Routes>
109
+ <Route path="/courses/" element={<ShowHref to="../about" />} />
110
+ </Routes>
111
+ </MemoryRouter>
112
+ );
113
+ });
114
+
115
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
116
+ <pre>
117
+ /about
118
+ </pre>
119
+ `);
120
+ });
121
+ });
122
+
123
+ describe("when the href has a trailing slash", () => {
124
+ it("returns the correct href", () => {
125
+ let renderer: TestRenderer.ReactTestRenderer;
126
+ TestRenderer.act(() => {
127
+ renderer = TestRenderer.create(
128
+ <MemoryRouter initialEntries={["/courses"]}>
129
+ <Routes>
130
+ <Route path="courses" element={<ShowHref to="../about/" />} />
131
+ </Routes>
132
+ </MemoryRouter>
133
+ );
134
+ });
135
+
136
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
137
+ <pre>
138
+ /about/
139
+ </pre>
140
+ `);
141
+ });
142
+ });
143
+ });
144
+
145
+ describe("to a parent route", () => {
146
+ it("returns the correct href", () => {
147
+ let renderer: TestRenderer.ReactTestRenderer;
148
+ TestRenderer.act(() => {
149
+ renderer = TestRenderer.create(
150
+ <MemoryRouter initialEntries={["/courses/advanced-react"]}>
151
+ <Routes>
152
+ <Route path="courses">
153
+ <Route path="advanced-react" element={<ShowHref to=".." />} />
154
+ </Route>
155
+ </Routes>
156
+ </MemoryRouter>
157
+ );
158
+ });
159
+
160
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
161
+ <pre>
162
+ /courses
163
+ </pre>
164
+ `);
165
+ });
166
+
167
+ describe("when the URL has a trailing slash", () => {
168
+ it("returns the correct href", () => {
169
+ let renderer: TestRenderer.ReactTestRenderer;
170
+ TestRenderer.act(() => {
171
+ renderer = TestRenderer.create(
172
+ <MemoryRouter initialEntries={["/courses/advanced-react/"]}>
173
+ <Routes>
174
+ <Route path="courses">
175
+ <Route path="advanced-react" element={<ShowHref to=".." />} />
176
+ </Route>
177
+ </Routes>
178
+ </MemoryRouter>
179
+ );
180
+ });
181
+
182
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
183
+ <pre>
184
+ /courses
185
+ </pre>
186
+ `);
187
+ });
188
+ });
189
+
190
+ describe("when the href has a trailing slash", () => {
191
+ it("returns the correct href", () => {
192
+ let renderer: TestRenderer.ReactTestRenderer;
193
+ TestRenderer.act(() => {
194
+ renderer = TestRenderer.create(
195
+ <MemoryRouter initialEntries={["/courses/advanced-react"]}>
196
+ <Routes>
197
+ <Route path="courses">
198
+ <Route
199
+ path="advanced-react"
200
+ element={<ShowHref to="../" />}
201
+ />
202
+ </Route>
203
+ </Routes>
204
+ </MemoryRouter>
205
+ );
206
+ });
207
+
208
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
209
+ <pre>
210
+ /courses/
211
+ </pre>
212
+ `);
213
+ });
214
+ });
215
+ });
216
+
217
+ describe("to an absolute route", () => {
218
+ it("returns the correct href", () => {
219
+ let renderer: TestRenderer.ReactTestRenderer;
220
+ TestRenderer.act(() => {
221
+ renderer = TestRenderer.create(
222
+ <MemoryRouter initialEntries={["/courses/advanced-react"]}>
223
+ <Routes>
224
+ <Route
225
+ path="courses/advanced-react"
226
+ element={<ShowHref to="/users" />}
227
+ />
228
+ </Routes>
229
+ </MemoryRouter>
230
+ );
231
+ });
232
+
233
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
234
+ <pre>
235
+ /users
236
+ </pre>
237
+ `);
238
+ });
239
+ });
240
+
241
+ describe("with a to value that has more .. segments than are in the URL", () => {
242
+ it("returns the correct href", () => {
243
+ let renderer: TestRenderer.ReactTestRenderer;
244
+ TestRenderer.act(() => {
245
+ renderer = TestRenderer.create(
246
+ <MemoryRouter initialEntries={["/courses/react-fundamentals"]}>
247
+ <Routes>
248
+ <Route path="courses">
249
+ <Route
250
+ path="react-fundamentals"
251
+ element={<ShowHref to="../../../courses" />}
252
+ />
253
+ </Route>
254
+ </Routes>
255
+ </MemoryRouter>
256
+ );
257
+ });
258
+
259
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
260
+ <pre>
261
+ /courses
262
+ </pre>
263
+ `);
264
+ });
265
+
266
+ describe("and no additional segments", () => {
267
+ it("links to the root /", () => {
268
+ let renderer: TestRenderer.ReactTestRenderer;
269
+ TestRenderer.act(() => {
270
+ renderer = TestRenderer.create(
271
+ <MemoryRouter initialEntries={["/home"]}>
272
+ <Routes>
273
+ <Route path="/home" element={<ShowHref to="../../.." />} />
274
+ </Routes>
275
+ </MemoryRouter>
276
+ );
277
+ });
278
+
279
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
280
+ <pre>
281
+ /
282
+ </pre>
283
+ `);
284
+ });
285
+ });
286
+ });
287
+ });
@@ -0,0 +1,29 @@
1
+ import * as React from "react";
2
+ import * as TestRenderer from "react-test-renderer";
3
+ import { MemoryRouter, Routes, Route, useLocation } from "react-router";
4
+
5
+ function ShowPath() {
6
+ let { pathname, search, hash } = useLocation();
7
+ return <pre>{JSON.stringify({ pathname, search, hash })}</pre>;
8
+ }
9
+
10
+ describe("useLocation", () => {
11
+ it("returns the current location object", () => {
12
+ let renderer: TestRenderer.ReactTestRenderer;
13
+ TestRenderer.act(() => {
14
+ renderer = TestRenderer.create(
15
+ <MemoryRouter initialEntries={["/home?the=search#the-hash"]}>
16
+ <Routes>
17
+ <Route path="/home" element={<ShowPath />} />
18
+ </Routes>
19
+ </MemoryRouter>
20
+ );
21
+ });
22
+
23
+ expect(renderer.toJSON()).toMatchInlineSnapshot(`
24
+ <pre>
25
+ {"pathname":"/home","search":"?the=search","hash":"#the-hash"}
26
+ </pre>
27
+ `);
28
+ });
29
+ });