Skip to content

Commit

Permalink
wip: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
OzakIOne committed Nov 20, 2023
1 parent 76a3a55 commit 2ec4092
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 105 deletions.
1 change: 1 addition & 0 deletions packages/docusaurus-module-type-aliases/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ declare module '@docusaurus/useAnchor' {
getCollectedAnchors: () => string[];
};

// useAnchorCollector
export default function useAnchor(): [
AnchorsCollector,
() => StatefulAnchorsCollector,
Expand Down
7 changes: 3 additions & 4 deletions packages/docusaurus-theme-classic/src/theme/Heading/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@ export default function Heading({as: As, id, ...props}: Props): JSX.Element {

const list = createAnchorList();

// ! should not be called 2 times, not a problem because we use
// Set<string> but still must be removed
anchorsCollector.collectAnchor(id);
// console.log('Heading id:');
// console.log(id);

list.collectAnchor(id);
// console.log('Heading anchor list:');
// console.log(list.getCollectedAnchors());

const anchorTitle = translate(
{
Expand Down
7 changes: 7 additions & 0 deletions packages/docusaurus-types/src/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ export type DocusaurusConfig = {
* @default "throw"
*/
onBrokenLinks: ReportingSeverity;
/**
* The behavior of Docusaurus when it detects any broken link.
*
* @see // TODO
* @default "warn"
*/
onBrokenAnchors: ReportingSeverity;
/**
* The behavior of Docusaurus when it detects any broken markdown link.
*
Expand Down
26 changes: 0 additions & 26 deletions packages/docusaurus/src/client/serverEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,32 +126,6 @@ async function doRender(locals: Locals & {path: string}) {
anchorsCollector.getCollectedAnchors(),
);

// console.log('Collected anchors');
// console.log(anchorsCollector.getCollectedAnchors());
// fs.writeFile(
// 'anchors.json',
// JSON.stringify(anchorsCollector.getCollectedAnchors()),
// (err) => {
// if (err) {
// throw err;
// }
// console.log('Saved!');
// },
// );

// console.log('Collected links');
// console.log(linksCollector.getCollectedLinks());
// fs.writeFile(
// 'links.json',
// JSON.stringify(linksCollector.getCollectedLinks()),
// (err) => {
// if (err) {
// throw err;
// }
// console.log('Saved!');
// },
// );

const {helmet} = helmetContext as FilledContext;
const htmlAttributes = helmet.htmlAttributes.toString();
const bodyAttributes = helmet.bodyAttributes.toString();
Expand Down
2 changes: 2 additions & 0 deletions packages/docusaurus/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ async function buildLocale({
siteConfig: {
baseUrl,
onBrokenLinks,
onBrokenAnchors,
staticDirectories: staticDirectoriesOption,
},
routes,
Expand Down Expand Up @@ -293,6 +294,7 @@ async function buildLocale({
allCollectedLinks,
routes,
onBrokenLinks,
onBrokenAnchors,
outDir,
baseUrl,
});
Expand Down
165 changes: 98 additions & 67 deletions packages/docusaurus/src/server/__tests__/brokenLinks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,93 +50,121 @@ describe('handleBrokenLinks', () => {
const linkToEmptyFolder1 = '/emptyFolder';
const linkToEmptyFolder2 = '/emptyFolder/';
const allCollectedLinks = {
'/docs/good doc with space': [
// Good - valid file with spaces in name
'./another%20good%20doc%20with%20space',
// Good - valid file with percent-20 in its name
'./weird%20but%20good',
// Bad - non-existent file with spaces in name
'./some%20other%20non-existent%20doc1',
// Evil - trying to use ../../ but '/' won't get decoded
// cSpell:ignore Fout
'./break%2F..%2F..%2Fout2',
],
'/docs/goodDoc': [
// Good links
'./anotherGoodDoc#someHash',
'/docs/anotherGoodDoc?someQueryString=true#someHash',
'../docs/anotherGoodDoc?someQueryString=true',
'../docs/anotherGoodDoc#someHash',
// Bad links
'../anotherGoodDoc#reported-because-of-bad-relative-path1',
'./docThatDoesNotExist2',
'./badRelativeLink3',
'../badRelativeLink4',
],
'/community': [
// Good links
'/docs/goodDoc',
'/docs/anotherGoodDoc#someHash',
'./docs/goodDoc#someHash',
'./docs/anotherGoodDoc',
// Bad links
'/someNonExistentDoc1',
'/badLink2',
'./badLink3',
],
'/page1': [
link1,
linkToHtmlFile1,
linkToJavadoc1,
linkToHtmlFile2,
linkToJavadoc3,
linkToJavadoc4,
linkToEmptyFolder1, // Not filtered!
],
'/page2': [
link2,
linkToEmptyFolder2, // Not filtered!
linkToJavadoc2,
link3,
linkToJavadoc3,
linkToZipFile,
],
};

const outDir = path.resolve(__dirname, '__fixtures__/brokenLinks/outDir');

it('do not report anything for correct paths', async () => {
const consoleMock = jest
.spyOn(console, 'warn')
.mockImplementation(() => {});
const allCollectedCorrectLinks = {
'/docs/good doc with space': [
'/docs/good doc with space': {
links: [
// Good - valid file with spaces in name
'./another%20good%20doc%20with%20space',
// Good - valid file with percent-20 in its name
'./weird%20but%20good',
// Bad - non-existent file with spaces in name
'./some%20other%20non-existent%20doc1',
// Evil - trying to use ../../ but '/' won't get decoded
// cSpell:ignore Fout
'./break%2F..%2F..%2Fout2',
],
'/docs/goodDoc': [
anchors: [],
},
'/docs/goodDoc': {
links: [
// Good links
'./anotherGoodDoc#someHash',
'/docs/anotherGoodDoc?someQueryString=true#someHash',
'../docs/anotherGoodDoc?someQueryString=true',
'../docs/anotherGoodDoc#someHash',
// Bad links
'../anotherGoodDoc#reported-because-of-bad-relative-path1',
'./docThatDoesNotExist2',
'./badRelativeLink3',
'../badRelativeLink4',
],
'/community': [
anchors: [],
},
'/community': {
links: [
// Good links
'/docs/goodDoc',
'/docs/anotherGoodDoc#someHash',
'./docs/goodDoc#someHash',
'./docs/anotherGoodDoc',
// Bad links
'/someNonExistentDoc1',
'/badLink2',
'./badLink3',
],
'/page1': [
anchors: [],
},
'/page1': {
links: [
link1,
linkToHtmlFile1,
linkToJavadoc1,
linkToHtmlFile2,
linkToJavadoc3,
linkToJavadoc4,
linkToEmptyFolder1, // Not filtered!
],
anchors: [],
},
'/page2': {
links: [
link2,
linkToEmptyFolder2, // Not filtered!
linkToJavadoc2,
link3,
linkToJavadoc3,
linkToZipFile,
],
anchors: [],
},
};

const outDir = path.resolve(__dirname, '__fixtures__/brokenLinks/outDir');

it('do not report anything for correct paths', async () => {
const consoleMock = jest
.spyOn(console, 'warn')
.mockImplementation(() => {});
const allCollectedCorrectLinks = {
'/docs/good doc with space': {
links: [
'./another%20good%20doc%20with%20space',
'./weird%20but%20good',
],
anchors: [],
},
'/docs/goodDoc': {
links: [
'./anotherGoodDoc#someHash',
'/docs/anotherGoodDoc?someQueryString=true#someHash',
'../docs/anotherGoodDoc?someQueryString=true',
'../docs/anotherGoodDoc#someHash',
],
anchors: ['someHash'],
},
'/community': {
links: [
'/docs/goodDoc',
'/docs/anotherGoodDoc#someHash',
'./docs/goodDoc#someHash',
'./docs/anotherGoodDoc',
],
anchors: [],
},
'/page1': {
links: [
linkToHtmlFile1,
linkToJavadoc1,
linkToHtmlFile2,
linkToJavadoc3,
linkToJavadoc4,
],
anchors: [],
},
};
await handleBrokenLinks({
allCollectedLinks: allCollectedCorrectLinks,
onBrokenLinks: 'warn',
onBrokenAnchors: 'throw',
routes,
baseUrl: '/',
outDir,
Expand All @@ -149,6 +177,7 @@ describe('handleBrokenLinks', () => {
handleBrokenLinks({
allCollectedLinks,
onBrokenLinks: 'throw',
onBrokenAnchors: 'throw',
routes,
baseUrl: '/',
outDir,
Expand All @@ -163,6 +192,7 @@ describe('handleBrokenLinks', () => {
await handleBrokenLinks({
allCollectedLinks,
onBrokenLinks: 'ignore',
onBrokenAnchors: 'throw',
routes,
baseUrl: '/',
outDir,
Expand All @@ -172,20 +202,21 @@ describe('handleBrokenLinks', () => {
});

it('reports frequent broken links', async () => {
Object.values(allCollectedLinks).forEach((links) =>
Object.values(allCollectedLinks).forEach(({links}) => {
links.push(
'/frequent',
// This is in the gray area of what should be reported. Relative paths
// may be resolved to different slugs on different locations. But if
// this comes from a layout link, it should be reported anyways
'./maybe-not',
),
);
);
});

await expect(() =>
handleBrokenLinks({
allCollectedLinks,
onBrokenLinks: 'throw',
onBrokenAnchors: 'throw',
routes,
baseUrl: '/',
outDir,
Expand Down
Loading

0 comments on commit 2ec4092

Please sign in to comment.