From ef937e402c4af8eb412567e51b2df59ebed4a940 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sat, 11 Jun 2022 17:43:17 +0800 Subject: [PATCH] fix test --- .../src/server/__tests__/brokenLinks.test.ts | 50 ++++++++++++------- packages/docusaurus/src/server/brokenLinks.ts | 27 +++++----- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/packages/docusaurus/src/server/__tests__/brokenLinks.test.ts b/packages/docusaurus/src/server/__tests__/brokenLinks.test.ts index 1226142f97..341953c635 100644 --- a/packages/docusaurus/src/server/__tests__/brokenLinks.test.ts +++ b/packages/docusaurus/src/server/__tests__/brokenLinks.test.ts @@ -9,7 +9,7 @@ import {jest} from '@jest/globals'; import path from 'path'; import _ from 'lodash'; import {handleBrokenLinks} from '../brokenLinks'; -import type {RouteConfig} from '@docusaurus/types'; +import type {DocusaurusConfig, Props, RouteConfig} from '@docusaurus/types'; describe('handleBrokenLinks', () => { const routes: RouteConfig[] = [ @@ -136,10 +136,14 @@ describe('handleBrokenLinks', () => { }; await handleBrokenLinks({ allCollectedLinks: allCollectedCorrectLinks, - onBrokenLinks: 'error', - routes, - baseUrl: '/', - outDir, + props: { + routes, + baseUrl: '/', + outDir, + siteConfig: { + onBrokenLinks: 'error', + } as DocusaurusConfig, + } as Props, }); expect(consoleMock).toBeCalledTimes(0); }); @@ -148,10 +152,14 @@ describe('handleBrokenLinks', () => { await expect(() => handleBrokenLinks({ allCollectedLinks, - onBrokenLinks: 'throw', - routes, - baseUrl: '/', - outDir, + props: { + routes, + baseUrl: '/', + outDir, + siteConfig: { + onBrokenLinks: 'throw', + } as DocusaurusConfig, + } as Props, }), ).rejects.toThrowErrorMatchingSnapshot(); }); @@ -162,10 +170,14 @@ describe('handleBrokenLinks', () => { const lodashMock = jest.spyOn(_, 'mapValues'); await handleBrokenLinks({ allCollectedLinks, - onBrokenLinks: 'ignore', - routes, - baseUrl: '/', - outDir, + props: { + routes, + baseUrl: '/', + outDir, + siteConfig: { + onBrokenLinks: 'ignore', + } as DocusaurusConfig, + } as Props, }); expect(lodashMock).toBeCalledTimes(0); lodashMock.mockRestore(); @@ -185,10 +197,14 @@ describe('handleBrokenLinks', () => { await expect(() => handleBrokenLinks({ allCollectedLinks, - onBrokenLinks: 'throw', - routes, - baseUrl: '/', - outDir, + props: { + routes, + baseUrl: '/', + outDir, + siteConfig: { + onBrokenLinks: 'throw', + } as DocusaurusConfig, + } as Props, }), ).rejects.toThrowErrorMatchingSnapshot(); }); diff --git a/packages/docusaurus/src/server/brokenLinks.ts b/packages/docusaurus/src/server/brokenLinks.ts index 3a0ce7eb2b..113e449e01 100644 --- a/packages/docusaurus/src/server/brokenLinks.ts +++ b/packages/docusaurus/src/server/brokenLinks.ts @@ -52,8 +52,7 @@ function getPageBrokenLinks({ // @ts-expect-error: React router types RouteConfig with an actual React // component, but we load route components with string paths. // We don't actually access component here, so it's fine. - .map((l) => matchRoutes(routes, l)) - .flat(); + .flatMap((l) => matchRoutes(routes, l)); return matchedRoutes.length === 0; } @@ -78,10 +77,8 @@ function getAllBrokenLinks({ allCollectedLinks: {[location: string]: string[]}; routes: RouteConfig[]; }): {[location: string]: BrokenLink[]} { - const filteredRoutes = filterIntermediateRoutes(routes); - const allBrokenLinks = _.mapValues(allCollectedLinks, (pageLinks, pagePath) => - getPageBrokenLinks({pageLinks, pagePath, routes: filteredRoutes}), + getPageBrokenLinks({pageLinks, pagePath, routes}), ); return _.pickBy(allBrokenLinks, (brokenLinks) => brokenLinks.length > 0); @@ -217,24 +214,29 @@ async function filterExistingFileLinks({ function findOrphanLinks({ allCollectedLinks, orphanPages, + routes, }: { allCollectedLinks: {[location: string]: string[]}; orphanPages: DocusaurusConfig['orphanPages']; + routes: RouteConfig[]; }) { if (!orphanPages || orphanPages.onOrphanPage === 'ignore') { return; } const visited = new Set(); function dfs(link: string) { - if (visited.has(link)) { + // @ts-expect-error: see comment above + const normalLink = matchRoutes(routes, link)[0]?.match.path; + if (!normalLink || visited.has(normalLink)) { return; } - visited.add(link); - allCollectedLinks[link]?.forEach((l) => dfs(resolvePathname(l, link))); + visited.add(normalLink); + allCollectedLinks[normalLink]?.forEach((l) => + dfs(resolvePathname(l, link)), + ); } orphanPages.entryPoints.forEach(dfs); - const orphaned = new Set(Object.keys(allCollectedLinks)); - visited.forEach((l) => orphaned.delete(l)); + const orphaned = routes.map((r) => r.path).filter((l) => !visited.has(l)); reportMessage( logger.interpolate`Orphan pages found: url=${Array.from(orphaned)}`, orphanPages.onOrphanPage, @@ -244,7 +246,7 @@ function findOrphanLinks({ export async function handleBrokenLinks({ allCollectedLinks, props: { - routes, + routes: allRoutes, baseUrl, outDir, siteConfig: {onBrokenLinks, orphanPages}, @@ -253,7 +255,8 @@ export async function handleBrokenLinks({ allCollectedLinks: {[location: string]: string[]}; props: Props; }): Promise { - findOrphanLinks({allCollectedLinks, orphanPages}); + const routes = filterIntermediateRoutes(allRoutes); + findOrphanLinks({allCollectedLinks, orphanPages, routes}); if (onBrokenLinks === 'ignore') { return;