From e09aef53b50767d3fd7ca3897b264c308d8732ec Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 13 Jul 2022 14:24:06 +0200 Subject: [PATCH] core-app-api: beta and compat tests for route collection Co-authored-by: blam Signed-off-by: Patrik Oldsberg --- .../src/routing/collectors.beta.test.tsx | 2 +- .../src/routing/collectors.compat.test.tsx | 639 +----------------- 2 files changed, 38 insertions(+), 603 deletions(-) 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')], ), ]); });