feat: stricter validation of heading fragments by being Case sensitive

Fixes #8

BREAKING CHANGE: Heading fragments is now Case sensitive.
For example "#ExistIng-Heading" is invalid as it should be "#existing-heading".
This commit is contained in:
Théo LUDWIG 2024-05-27 22:50:43 +02:00
parent 450cdb84f0
commit 85f465306f
Signed by: theoludwig
GPG Key ID: ADFE5A563D718F3B
6 changed files with 19 additions and 10 deletions

View File

@ -126,7 +126,7 @@ const customRule = {
fragmentsHTML.push(...idOrAnchorNameHTMLFragments) fragmentsHTML.push(...idOrAnchorNameHTMLFragments)
if (!fragmentsHTML.includes(url.hash.toLowerCase())) { if (!fragmentsHTML.includes(url.hash)) {
if (url.hash.startsWith("#L")) { if (url.hash.startsWith("#L")) {
const lineNumberFragmentString = getLineNumberStringFromFragment( const lineNumberFragmentString = getLineNumberStringFromFragment(
url.hash, url.hash,
@ -157,6 +157,8 @@ const customRule = {
}) })
continue continue
} }
continue
} }
onError({ onError({

View File

@ -28,7 +28,7 @@ const convertHeadingToHTMLFragment = (inlineText) => {
"", "",
) )
.replace(/ /gu, "-"), .replace(/ /gu, "-"),
).toLowerCase() )
) )
} }

View File

@ -1,3 +1,3 @@
# Valid # Valid
[Link fragment](./awesome.md#L7) [Link fragment](./awesome.md#l7)

View File

@ -47,6 +47,14 @@ test("ensure the rule validates correctly", async (t) => {
'"./awesome.md#not-an-id-should-be-ignored" should have a valid fragment identifier', '"./awesome.md#not-an-id-should-be-ignored" should have a valid fragment identifier',
], ],
}, },
{
name: "should be invalid with uppercase letters in fragment (case sensitive)",
fixturePath:
"test/fixtures/invalid/invalid-heading-case-sensitive/invalid-heading-case-sensitive.md",
errors: [
'"./awesome.md#ExistIng-Heading" should have a valid fragment identifier',
],
},
{ {
name: "should be invalid with invalid heading with #L fragment", name: "should be invalid with invalid heading with #L fragment",
fixturePath: fixturePath:
@ -148,7 +156,11 @@ test("ensure the rule validates correctly", async (t) => {
) )
return result.errorDetail return result.errorDetail
}) })
assert.deepStrictEqual(errorsDetails, errors) assert.deepStrictEqual(
errorsDetails,
errors,
`${fixturePath}: Expected errors`,
)
}) })
} }
}) })
@ -165,11 +177,6 @@ test("ensure the rule validates correctly", async (t) => {
fixturePath: fixturePath:
"test/fixtures/valid/existing-element-id-fragment/existing-element-id-fragment.md", "test/fixtures/valid/existing-element-id-fragment/existing-element-id-fragment.md",
}, },
{
name: "should be valid with an existing heading fragment (case insensitive)",
fixturePath:
"test/fixtures/valid/existing-heading-case-insensitive/existing-heading-case-insensitive.md",
},
{ {
name: "should be valid with an existing heading fragment", name: "should be valid with an existing heading fragment",
fixturePath: fixturePath:
@ -232,7 +239,7 @@ test("ensure the rule validates correctly", async (t) => {
assert.equal( assert.equal(
errorsDetails.length, errorsDetails.length,
0, 0,
`Expected no errors, got ${errorsDetails.join(", ")}`, `${fixturePath}: Expected no errors, got ${errorsDetails.join(", ")}`,
) )
}) })
} }