Skip to content

Commit

Permalink
added tests for check_url plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
oscarotero committed Oct 15, 2024
1 parent 98821e5 commit b34cdc0
Show file tree
Hide file tree
Showing 6 changed files with 656 additions and 27 deletions.
94 changes: 67 additions & 27 deletions plugins/check_urls.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { merge } from "../core/utils/object.ts";
import { parseSrcset, searchLinks } from "../core/utils/dom_links.ts";
import { gray, green, red } from "../deps/colors.ts";
import { Page } from "../core/file.ts";

import type Site from "../core/site.ts";

export interface Options {
/** The list of extensions this plugin applies to */
extensions?: string[];

/** Whether distinguish the trailing slash or not (only for internal links) */
/** True to distinguish trailing slashes and oldUrl values (only for internal links) */
strict?: boolean;

/** The list of URLs to ignore */
ignore?: string[];

/** To output the list to a json file */
output?: string;
}

/** Default options */
export const defaults: Options = {
extensions: [".html"],
strict: true,
strict: false,
ignore: [],
};

Expand All @@ -43,16 +47,19 @@ export default function (userOptions?: Options) {
}

return (site: Site) => {
const urls = new Set<string>(); // Set is more performant than arrays
const notFound = new Map<string, string[]>();
const urls = new Set<string>(); // All valid URLs
const redirects = new Set<string>(); // All URLs that are redirects
const notFound = new Map<string, Set<string>>();

function findPath(path: string): boolean {
if (options.strict) {
return urls.has(path);
}

const cleaned = path === "/" ? path : path.replace(/\/$/, "");
return urls.has(cleaned) || urls.has(cleaned + "/");

return urls.has(cleaned) || urls.has(cleaned + "/") ||
redirects.has(cleaned) || redirects.has(cleaned + "/");
}

function scan(url: string, pageUrl: URL): void {
Expand All @@ -68,8 +75,8 @@ export default function (userOptions?: Options) {
}

if (!findPath(fullUrl.pathname)) {
const ref = notFound.get(fullUrl.pathname) || [];
ref.push(pageUrl.pathname);
const ref = notFound.get(fullUrl.pathname) || new Set();
ref.add(pageUrl.pathname);
notFound.set(fullUrl.pathname, ref);
}
}
Expand All @@ -81,7 +88,18 @@ export default function (userOptions?: Options) {

for (const page of pages) {
urls.add(page.data.url);

if (page.data.oldUrl) {
if (Array.isArray(page.data.oldUrl)) {
for (const oldUrl of page.data.oldUrl) {
redirects.add(oldUrl);
}
} else {
redirects.add(page.data.oldUrl);
}
}
}

for (const file of site.files) {
urls.add(file.outputPath);
}
Expand Down Expand Up @@ -113,26 +131,48 @@ export default function (userOptions?: Options) {
},
);

function showResults() {
if (notFound.size === 0) {
console.log(green("All links are OK!"));
return;
}

console.log("");
console.log(`⛓️‍💥 ${notFound.size} Broken links:`);
for (const [url, refs] of notFound) {
console.log("");
console.log(red(url));
console.log(" In the page(s):");
for (const ref of refs) {
console.log(` ${gray(ref)}`);
}
}
console.log("");
if (options.output) {
site.addEventListener(
"beforeSave",
() => outputResults(notFound, options.output, site),
);
} else {
site.addEventListener("afterUpdate", () => showResults(notFound));
site.addEventListener("afterBuild", () => showResults(notFound));
}

site.addEventListener("afterUpdate", showResults);
site.addEventListener("afterBuild", showResults);
};
}

function outputResults(
notFound: Map<string, Set<string>>,
url: string,
site: Site,
) {
const content = JSON.stringify(
Object.fromEntries(
notFound.entries().map(([url, refs]) => [url, Array.from(refs)]),
),
null,
2,
);
site.pages.push(Page.create({ content, url }));
}

function showResults(notFound: Map<string, Set<string>>) {
if (notFound.size === 0) {
console.log(green("All links are OK!"));
return;
}

console.log("");
console.log(`${notFound.size} Broken links:`);
for (const [url, refs] of notFound) {
console.log("");
console.log("⛓️‍💥", red(url));
console.log(" In the page(s):");
for (const ref of refs) {
console.log(` ${gray(ref)}`);
}
}
console.log("");
}
Loading

0 comments on commit b34cdc0

Please sign in to comment.