- cardDirs: course/cards only from Module 5 (spec 6.2a); fixture modules 04/05 and tests - coupling-audit: noun words match as UPPERCASE, PascalCase or a whole string literal; lowercase identifiers like key/flag pass; card names keep every variant - isMain() argv guard replaces import.meta.main in coupling-audit and verify-references; engines.node >=22 - expansion-check: git diff --no-renames so moving engine code into content fails - start-module and other tools: clear error when .course.json is missing - check-links: malformed URLs reported as invalid URL instead of throwing Co-Authored-By: Claude Opus 5.5 <[email protected]>
24 lines
1.0 KiB
JavaScript
24 lines
1.0 KiB
JavaScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { extractUrls, hostOf, classifyUnverifiable } from "../check-links.mjs";
|
|
|
|
test("check_links_extracts_markdown_and_bare_urls", () => {
|
|
const md =
|
|
"See [Rule](https://babaiswiki.fandom.com/wiki/Rule). Also https://example.com/a, and " +
|
|
"(https://en.wikipedia.org/wiki/Foo_(bar)) and `https://x.org/y`.";
|
|
assert.deepEqual(extractUrls(md), [
|
|
"https://babaiswiki.fandom.com/wiki/Rule",
|
|
"https://example.com/a",
|
|
"https://en.wikipedia.org/wiki/Foo_(bar)",
|
|
"https://x.org/y",
|
|
]);
|
|
});
|
|
|
|
test("check_links_reports_malformed_urls_instead_of_throwing", () => {
|
|
// `new URL()` throws on these; the checker must still finish and exit 0.
|
|
assert.equal(hostOf("http://[bad"), null);
|
|
assert.equal(classifyUnverifiable("http://[bad"), "invalid URL");
|
|
assert.equal(classifyUnverifiable("https://www.reddit.com/r/x").startsWith("unverifiable"), true);
|
|
assert.equal(classifyUnverifiable("https://example.com/a"), null);
|
|
});
|