diff --git a/packages/core-app-api/src/routing/collectors.beta.test.tsx b/packages/core-app-api/src/routing/collectors.beta.test.tsx
index 1c5bc8c639..bb67966fbd 100644
--- a/packages/core-app-api/src/routing/collectors.beta.test.tsx
+++ b/packages/core-app-api/src/routing/collectors.beta.test.tsx
@@ -109,7 +109,7 @@ function routeObj(
routeRefs: new Set(refs),
children: [
{
- path: '/*',
+ path: '*',
caseSensitive: false,
element: 'match-all',
routeRefs: new Set(),
diff --git a/packages/core-app-api/src/routing/collectors.compat.test.tsx b/packages/core-app-api/src/routing/collectors.compat.test.tsx
index 276cc380da..8566f22a0c 100644
--- a/packages/core-app-api/src/routing/collectors.compat.test.tsx
+++ b/packages/core-app-api/src/routing/collectors.compat.test.tsx
@@ -18,7 +18,6 @@ import React from 'react';
import type { PropsWithChildren } from 'react';
import {
RouteRef,
- BackstagePlugin,
createPlugin,
createRouteRef,
createRoutableExtension,
@@ -124,9 +123,8 @@ describe.each(['beta', 'stable'])('react-router %s', rrVersion => {
refs: RouteRef[],
children: any[] = [],
type: 'mounted' | 'gathered' = 'mounted',
- backstagePlugin?: BackstagePlugin,
) {
- return {
+ return expect.objectContaining({
path: path,
caseSensitive: false,
element: type,
@@ -140,8 +138,7 @@ describe.each(['beta', 'stable'])('react-router %s', rrVersion => {
},
...children,
],
- plugin: backstagePlugin,
- };
+ });
}
describe(`routing with ${rrVersion}`, () => {
@@ -158,10 +155,7 @@ describe.each(['beta', 'stable'])('react-router %s', rrVersion => {
} = requireDeps();
traversalOptions = {
- discoverers:
- rrVersion === 'beta'
- ? [childDiscoverer, routeElementDiscoverer]
- : [childDiscoverer],
+ discoverers: [childDiscoverer, routeElementDiscoverer],
collectors: {
routing:
rrVersion === 'beta' ? routingV1Collector : routingV2Collector,
@@ -176,33 +170,34 @@ describe.each(['beta', 'stable'])('react-router %s', rrVersion => {
,
,
-
+ } />
,
];
const root = (
-
+ } />
+ }>
-
+ }>
Some text here shouldn't be a problem
{null}
-
+
} />
-
+
{false}
{list}
{true}
{0}
-
+
- } />
+ } />
@@ -214,11 +209,11 @@ describe.each(['beta', 'stable'])('react-router %s', rrVersion => {
});
expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/bar/:id'],
- [ref3, '/baz'],
- [ref4, '/divsoup'],
- [ref5, '/blop'],
+ [ref1, 'foo'],
+ [ref2, 'bar/:id'],
+ [ref3, 'baz'],
+ [ref4, 'divsoup'],
+ [ref5, 'blop'],
]);
expect(sortedEntries(routing.parents)).toEqual([
[ref1, undefined],
@@ -229,97 +224,52 @@ describe.each(['beta', 'stable'])('react-router %s', rrVersion => {
]);
expect(routing.objects).toEqual([
routeObj(
- '/foo',
+ 'foo',
[ref1],
[
- routeObj('/bar/:id', [ref2], [routeObj('/baz', [ref3])]),
- routeObj('/blop', [ref5]),
+ routeObj('bar/:id', [ref2], [routeObj('baz', [ref3])]),
+ routeObj('blop', [ref5]),
],
),
- routeObj('/divsoup', [ref4], undefined, undefined, plugin),
+ routeObj('divsoup', [ref4]),
]);
});
- it('should handle all react router Route patterns', () => {
+ it('should collect routes with aggregators', () => {
+ const { MemoryRouter, Routes, Route, traverseElementTree } =
+ requireDeps();
const root = (
-
-
-
-
-
- }
- />
- }>
- } />
-
-
-
-
- );
-
- const { routing } = traverseElementTree({
- root,
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV1Collector,
- },
- });
- expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/bar/:id'],
- [ref3, '/baz'],
- [ref4, '/divsoup'],
- [ref5, '/blop'],
- ]);
- expect(sortedEntries(routing.parents)).toEqual([
- [ref1, undefined],
- [ref2, ref1],
- [ref3, undefined],
- [ref4, ref3],
- [ref5, ref3],
- ]);
- });
-
- it('should use the route aggregator key to bind child routes to the same path', () => {
- const root = (
-
-
-
+
HELLO
-
-
+ }>
+
-
+
);
const { routing } = traverseElementTree({
root,
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV1Collector,
- },
+ ...traversalOptions,
});
+
expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/foo'],
- [ref3, '/bar'],
- [ref4, '/baz'],
- [ref5, '/baz'],
+ [ref1, 'foo'],
+ [ref2, 'foo'],
+ [ref3, 'bar'],
+ [ref4, 'baz'],
+ [ref5, 'baz'],
]);
expect(sortedEntries(routing.parents)).toEqual([
[ref1, undefined],
@@ -329,526 +279,11 @@ describe.each(['beta', 'stable'])('react-router %s', rrVersion => {
[ref5, ref3],
]);
expect(routing.objects).toEqual([
- routeObj('/foo', [ref1, ref2], [], 'gathered'),
+ routeObj('foo', [ref1, ref2], [], 'gathered'),
routeObj(
- '/bar',
+ 'bar',
[ref3],
- [routeObj('/baz', [ref4, ref5], [], 'gathered')],
- ),
- ]);
- });
-
- it('should use the route aggregator but stop when encountering explicit path', () => {
- const root = (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-
- const { routing } = traverseElementTree({
- root,
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV1Collector,
- },
- });
- expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/bar'],
- [ref3, '/baz'],
- [ref4, '/blop'],
- [ref5, '/bar'],
- ]);
- expect(sortedEntries(routing.parents)).toEqual([
- [ref1, undefined],
- [ref2, ref1],
- [ref3, ref1],
- [ref4, ref3],
- [ref5, ref1],
- ]);
- expect(routing.objects).toEqual([
- routeObj(
- '/foo',
- [ref1],
- [
- routeObj(
- '/bar',
- [ref2, ref5],
- [routeObj('/baz', [ref3], [routeObj('/blop', [ref4])])],
- 'gathered',
- ),
- ],
- ),
- ]);
- });
-
- it('should stop gathering mount points after encountering explicit path', () => {
- const root = (
-
-
-
-
-
-
-
-
-
-
-
- );
-
- expect(() => {
- traverseElementTree({
- root,
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV1Collector,
- },
- });
- }).toThrow('Mounted routable extension must have a path');
- });
- });
-
- describe('routingV2Collector', () => {
- function routeRoot(element: JSX.Element) {
- return (
-
- {element}
-
- );
- }
-
- it('should associate path with extension in element prop', () => {
- const { routing } = traverseElementTree({
- root: routeRoot(} />),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
-
- expect(sortedEntries(routing.paths)).toEqual([[ref1, '/foo']]);
- expect(sortedEntries(routing.parents)).toEqual([[ref1, undefined]]);
- expect(routing.objects).toEqual([
- routeObj('/foo', [ref1], [], undefined, plugin),
- ]);
- });
-
- it('should not allow multiple extensions within the same element prop', () => {
- expect(() =>
- traverseElementTree({
- root: routeRoot(
-
-
-
- >
- }
- />,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- }),
- ).toThrow('Route element may not contain multiple routable extensions');
- });
-
- it('should not support inline path', () => {
- expect(() =>
- traverseElementTree({
- root: routeRoot(),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- }),
- ).toThrow(
- 'Path property may not be set directly on a routable extension',
- );
- });
-
- it('should associate the path with extensions deep in the element prop', () => {
- const { routing } = traverseElementTree({
- root: routeRoot(
-
-
-
- {[
- undefined,
- null,
-
-
- ,
- ]}
-
- >
- }
- />,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
-
- expect(sortedEntries(routing.paths)).toEqual([[ref1, '/foo']]);
- expect(sortedEntries(routing.parents)).toEqual([[ref1, undefined]]);
- expect(routing.objects).toEqual([
- routeObj('/foo', [ref1], [], undefined, plugin),
- ]);
- });
-
- it('should not associate path with extension in children prop', () => {
- expect(() =>
- traverseElementTree({
- root: routeRoot(
-
-
- ,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- }),
- ).toThrow('Routable extension must be assigned a path');
- });
-
- it('should assign parent for extension in element prop', () => {
- const { routing } = traverseElementTree({
- root: routeRoot(
- }>
- } />
- ,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
-
- expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/bar'],
- ]);
- expect(sortedEntries(routing.parents)).toEqual([
- [ref1, undefined],
- [ref2, ref1],
- ]);
- expect(routing.objects).toEqual([
- routeObj(
- '/foo',
- [ref1],
- [routeObj('/bar', [ref2], [], undefined, plugin)],
- undefined,
- plugin,
- ),
- ]);
- });
-
- it('should not allow paths within element props', () => {
- expect(() => {
- traverseElementTree({
- root: routeRoot(
- } />}
- />,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
- }).toThrow('Elements within the element prop tree may not contain paths');
- });
-
- it('should not allow extensions within the element prop to have path props either', () => {
- expect(() => {
- traverseElementTree({
- root: routeRoot(
- } />,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
- }).toThrow('Elements within the element prop tree may not contain paths');
- });
-
- it('should gather extension', () => {
- const { routing } = traverseElementTree({
- root: routeRoot(
-
-
- ,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
-
- expect(sortedEntries(routing.paths)).toEqual([[ref1, '/foo']]);
- expect(sortedEntries(routing.parents)).toEqual([[ref1, undefined]]);
- expect(routing.objects).toEqual([
- routeObj('/foo', [ref1], [], 'gathered'),
- ]);
- });
-
- it('should reset gathering if path prop is encountered', () => {
- const { routing } = traverseElementTree({
- root: routeRoot(
-
-
- } />
-
- ,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
-
- expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/bar'],
- ]);
- expect(sortedEntries(routing.parents)).toEqual([
- [ref1, undefined],
- [ref2, ref1],
- ]);
- expect(routing.objects).toEqual([
- routeObj(
- '/foo',
- [ref1],
- [routeObj('/bar', [ref2], [], undefined, plugin)],
- 'gathered',
- ),
- ]);
- });
-
- it('should collect routes defined with different patterns', () => {
- const list = [
- ,
- ,
-
- } />
-
,
- ];
-
- const { routing } = traverseElementTree({
- root: routeRoot(
- <>
- }>
-
-
}>
-
-
- Some text here shouldn't be a problem
-
- {null}
-
-
} />
-
-
- {false}
- {list}
- {true}
- {0}
-
-
-
- } />
-
- >,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
- expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/bar/:id'],
- [ref3, '/baz'],
- [ref4, '/divsoup'],
- [ref5, '/blop'],
- ]);
- expect(sortedEntries(routing.parents)).toEqual([
- [ref1, undefined],
- [ref2, ref1],
- [ref3, ref2],
- [ref4, undefined],
- [ref5, ref1],
- ]);
- expect(routing.objects).toEqual([
- routeObj(
- '/foo',
- [ref1],
- [
- routeObj(
- '/bar/:id',
- [ref2],
- [routeObj('/baz', [ref3], [], undefined, plugin)],
- undefined,
- plugin,
- ),
- routeObj('/blop', [ref5], [], undefined, plugin),
- ],
- undefined,
- plugin,
- ),
- routeObj('/divsoup', [ref4], undefined, undefined, plugin),
- ]);
- });
-
- it('should handle a subset of react router Route patterns', () => {
- const { routing } = traverseElementTree({
- root: routeRoot(
- <>
- } />
-
-
-
- }
- >
- } />
-
-
-
-
- >,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
- expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/baz'],
- [ref3, '/child'],
- [ref4, '/collected'],
- ]);
- expect(sortedEntries(routing.parents)).toEqual([
- [ref1, undefined],
- [ref2, undefined],
- [ref3, ref2],
- [ref4, ref2],
- ]);
- });
-
- it('should bind child routes to the same path with a gatherer flag', () => {
- const { routing } = traverseElementTree({
- root: routeRoot(
- <>
-
-
-
-
-
- HELLO
-
- >,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
- expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/foo'],
- ]);
- expect(sortedEntries(routing.parents)).toEqual([
- [ref1, undefined],
- [ref2, undefined],
- ]);
- expect(routing.objects).toEqual([
- routeObj('/foo', [ref1, ref2], [], 'gathered'),
- ]);
- });
-
- it('should gather routes but stop when encountering explicit path', () => {
- const { routing } = traverseElementTree({
- root: routeRoot(
- }>
-
-
- }>
-
-
-
-
-
-
-
- ,
- ),
- discoverers: [childDiscoverer, routeElementDiscoverer],
- collectors: {
- routing: routingV2Collector,
- },
- });
- expect(sortedEntries(routing.paths)).toEqual([
- [ref1, '/foo'],
- [ref2, '/bar'],
- [ref3, '/baz'],
- [ref4, '/blop'],
- [ref5, '/bar'],
- ]);
- expect(sortedEntries(routing.parents)).toEqual([
- [ref1, undefined],
- [ref2, ref1],
- [ref3, ref2],
- [ref4, ref3],
- [ref5, ref1],
- ]);
- expect(routing.objects).toEqual([
- routeObj(
- '/foo',
- [ref1],
- [
- routeObj(
- '/bar',
- [ref2, ref5],
- [
- routeObj(
- '/baz',
- [ref3],
- [routeObj('/blop', [ref4], [], 'gathered')],
- undefined,
- plugin,
- ),
- ],
- 'gathered',
- ),
- ],
- undefined,
- plugin,
+ [routeObj('baz', [ref4, ref5], [], 'gathered')],
),
]);
});