From 32a92f867a32241bf38172a87fa1c07a8b3d7708 Mon Sep 17 00:00:00 2001 From: HiDeoo <494699+HiDeoo@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:45:19 +0200 Subject: [PATCH] feat: adds a new `errorOnInvalidHashes` option defaulting to `true` to disable hash validation --- docs/src/content/docs/configuration.md | 24 ++++++++++ docs/src/content/docs/getting-started.mdx | 4 +- packages/starlight-links-validator/README.md | 4 +- packages/starlight-links-validator/index.ts | 8 ++++ .../libs/validation.ts | 16 ++++--- .../tests/base-path.test.ts | 4 +- .../tests/basics.test.ts | 20 ++++---- .../tests/custom-ids.test.ts | 2 +- .../tests/fallback.test.ts | 16 +++---- .../src/content/docs/guides/example.mdx | 12 ++--- .../src/content/docs/test.md | 12 ++--- .../src/content/docs/guides/example.mdx | 10 ++-- .../src/content/docs/index.md | 14 +++--- .../astro.config.ts | 13 +++++ .../src/content/docs/guides/example.mdx | 46 ++++++++++++++++++ .../src/content/docs/test.md | 48 +++++++++++++++++++ .../astro.config.ts | 13 +++++ .../src/content/docs/guides/example.mdx | 47 ++++++++++++++++++ .../src/content/docs/index.md | 38 +++++++++++++++ .../src/content/docs/test.md | 27 +++++++++++ .../tests/invalid-hashes.test.ts | 42 ++++++++++++++++ .../tests/relative.test.ts | 4 +- .../tests/src-dir.test.ts | 4 +- .../tests/trailing.test.ts | 8 ++-- 24 files changed, 373 insertions(+), 63 deletions(-) create mode 100644 packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/astro.config.ts create mode 100644 packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/guides/example.mdx create mode 100644 packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/test.md create mode 100644 packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/astro.config.ts create mode 100644 packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/guides/example.mdx create mode 100644 packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/index.md create mode 100644 packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/test.md create mode 100644 packages/starlight-links-validator/tests/invalid-hashes.test.ts diff --git a/docs/src/content/docs/configuration.md b/docs/src/content/docs/configuration.md index 9b10fae..f97b527 100644 --- a/docs/src/content/docs/configuration.md +++ b/docs/src/content/docs/configuration.md @@ -101,6 +101,30 @@ export default defineConfig({ }) ``` +### `errorOnInvalidHashes` + +**Type:** `boolean` +**Default:** `true` + +By default, the Starlight Links Validator plugin will error if an internal link points to an [hash](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash) that does not exist in the target page. +If you want to only validate that pages exist but ignore hashes, you can set this option to `false`. + +This option should be used with caution but can be useful in large documentation with many contributors where hashes always being up-to-date can be difficult to maintain and validated on a different schedule, e.g. once a week. + +```js {6} +export default defineConfig({ + integrations: [ + starlight({ + plugins: [ + starlightLinksValidator({ + errorOnInvalidHashes: false, + }), + ], + }), + ], +}) +``` + ### `exclude` **Type:** `string[]` diff --git a/docs/src/content/docs/getting-started.mdx b/docs/src/content/docs/getting-started.mdx index 88071d4..37b90c6 100644 --- a/docs/src/content/docs/getting-started.mdx +++ b/docs/src/content/docs/getting-started.mdx @@ -5,8 +5,8 @@ title: Getting Started A [Starlight](https://starlight.astro.build) plugin to validate **_internal_** links in Markdown and MDX files. - Validate internal links to other pages -- Validate internal links to anchors in other pages -- Validate internal links to anchors in the same page +- Validate internal links to hashes in other pages +- Validate internal links to hashes in the same page - Ignore external links - Run only during a production build diff --git a/packages/starlight-links-validator/README.md b/packages/starlight-links-validator/README.md index f61dd63..db11b44 100644 --- a/packages/starlight-links-validator/README.md +++ b/packages/starlight-links-validator/README.md @@ -27,8 +27,8 @@ Want to get started immediately? Check out the [getting started guide](https://s A [Starlight](https://starlight.astro.build) plugin to validate **_internal_** links in Markdown and MDX files. - Validate internal links to other pages -- Validate internal links to anchors in other pages -- Validate internal links to anchors in the same page +- Validate internal links to hashes in other pages +- Validate internal links to hashes in the same page - Ignore external links - Run only during a production build diff --git a/packages/starlight-links-validator/index.ts b/packages/starlight-links-validator/index.ts index 2c9480f..0298fa1 100644 --- a/packages/starlight-links-validator/index.ts +++ b/packages/starlight-links-validator/index.ts @@ -33,6 +33,14 @@ const starlightLinksValidatorOptionsSchema = z * @default true */ errorOnRelativeLinks: z.boolean().default(true), + /** + * Defines whether the plugin should error on invalid hashes. + * + * When set to `false`, the plugin will only validate link pages and ignore hashes. + * + * @default true + */ + errorOnInvalidHashes: z.boolean().default(true), /** * Defines a list of links or glob patterns that should be excluded from validation. * diff --git a/packages/starlight-links-validator/libs/validation.ts b/packages/starlight-links-validator/libs/validation.ts index a1754ab..cbc08bf 100644 --- a/packages/starlight-links-validator/libs/validation.ts +++ b/packages/starlight-links-validator/libs/validation.ts @@ -15,7 +15,7 @@ import { getValidationData, type Headings } from './remark' export const ValidationErrorType = { InconsistentLocale: 'inconsistent locale', - InvalidAnchor: 'invalid anchor', + InvalidHash: 'invalid hash', InvalidLink: 'invalid link', RelativeLink: 'relative link', TrailingSlash: 'trailing slash', @@ -59,7 +59,9 @@ export function validateLinks( } if (link.startsWith('#')) { - validateSelfAnchor(validationContext) + if (options.errorOnInvalidHashes) { + validateSelfHash(validationContext) + } } else { validateLink(validationContext) } @@ -151,7 +153,9 @@ function validateLink(context: ValidationContext) { } if (hash && !fileHeadings.includes(hash)) { - addError(errors, filePath, link, ValidationErrorType.InvalidAnchor) + if (options.errorOnInvalidHashes) { + addError(errors, filePath, link, ValidationErrorType.InvalidHash) + } return } @@ -176,9 +180,9 @@ function getFileHeadings(path: string, { headings, localeConfig, options }: Vali } /** - * Validate a link to an anchor in the same page. + * Validate a link to an hash in the same page. */ -function validateSelfAnchor({ errors, link, filePath, headings }: ValidationContext) { +function validateSelfHash({ errors, link, filePath, headings }: ValidationContext) { const sanitizedHash = link.replace(/^#/, '') const fileHeadings = headings.get(filePath) @@ -187,7 +191,7 @@ function validateSelfAnchor({ errors, link, filePath, headings }: ValidationCont } if (!fileHeadings.includes(sanitizedHash)) { - addError(errors, filePath, link, 'invalid anchor') + addError(errors, filePath, link, ValidationErrorType.InvalidHash) } } diff --git a/packages/starlight-links-validator/tests/base-path.test.ts b/packages/starlight-links-validator/tests/base-path.test.ts index d37059d..b766117 100644 --- a/packages/starlight-links-validator/tests/base-path.test.ts +++ b/packages/starlight-links-validator/tests/base-path.test.ts @@ -19,8 +19,8 @@ test('should validate links when the `base` Astro option is set', async () => { ['/guides/example/#description', ValidationErrorType.InvalidLink], ['/unknown', ValidationErrorType.InvalidLink], ['/unknown/', ValidationErrorType.InvalidLink], - ['/test/guides/example#unknown', ValidationErrorType.InvalidAnchor], - ['/test/guides/example/#unknown', ValidationErrorType.InvalidAnchor], + ['/test/guides/example#unknown', ValidationErrorType.InvalidHash], + ['/test/guides/example/#unknown', ValidationErrorType.InvalidHash], ['/favicon.svg', ValidationErrorType.InvalidLink], ['/guidelines/dummy.pdf', ValidationErrorType.InvalidLink], ]) diff --git a/packages/starlight-links-validator/tests/basics.test.ts b/packages/starlight-links-validator/tests/basics.test.ts index 177c2ff..6c8cbba 100644 --- a/packages/starlight-links-validator/tests/basics.test.ts +++ b/packages/starlight-links-validator/tests/basics.test.ts @@ -27,35 +27,35 @@ test('should not build with invalid links', async () => { ['/unknown/', ValidationErrorType.InvalidLink], ['/unknown#title', ValidationErrorType.InvalidLink], ['/unknown/#title', ValidationErrorType.InvalidLink], - ['#links', ValidationErrorType.InvalidAnchor], - ['/guides/example/#links', ValidationErrorType.InvalidAnchor], + ['#links', ValidationErrorType.InvalidHash], + ['/guides/example/#links', ValidationErrorType.InvalidHash], ['/icon.svg', ValidationErrorType.InvalidLink], ['/guidelines/ui.pdf', ValidationErrorType.InvalidLink], ['/unknown-ref', ValidationErrorType.InvalidLink], - ['#unknown-ref', ValidationErrorType.InvalidAnchor], - ['#anotherDiv', ValidationErrorType.InvalidAnchor], + ['#unknown-ref', ValidationErrorType.InvalidHash], + ['#anotherDiv', ValidationErrorType.InvalidHash], ['/guides/page-with-custom-slug', ValidationErrorType.InvalidLink], ['/release/@pkg/v0.2.0', ValidationErrorType.InvalidLink], ]) expectValidationErrors(error, 'guides/example/', [ - ['#links', ValidationErrorType.InvalidAnchor], + ['#links', ValidationErrorType.InvalidHash], ['/unknown/#links', ValidationErrorType.InvalidLink], ['/unknown', ValidationErrorType.InvalidLink], - ['#anotherBlock', ValidationErrorType.InvalidAnchor], + ['#anotherBlock', ValidationErrorType.InvalidHash], ['/icon.svg', ValidationErrorType.InvalidLink], ['/guidelines/ui.pdf', ValidationErrorType.InvalidLink], ['/linkcard/', ValidationErrorType.InvalidLink], ['/linkcard/#links', ValidationErrorType.InvalidLink], - ['#linkcard', ValidationErrorType.InvalidAnchor], + ['#linkcard', ValidationErrorType.InvalidHash], ['/linkbutton/', ValidationErrorType.InvalidLink], ['/linkbutton/#links', ValidationErrorType.InvalidLink], - ['#linkbutton', ValidationErrorType.InvalidAnchor], + ['#linkbutton', ValidationErrorType.InvalidHash], ]) expectValidationErrors(error, 'guides/namespacetest/', [ - ['#some-other-content', ValidationErrorType.InvalidAnchor], - ['/guides/namespacetest/#another-content', ValidationErrorType.InvalidAnchor], + ['#some-other-content', ValidationErrorType.InvalidHash], + ['/guides/namespacetest/#another-content', ValidationErrorType.InvalidHash], ]) expectValidationErrors(error, 'relative/', [ diff --git a/packages/starlight-links-validator/tests/custom-ids.test.ts b/packages/starlight-links-validator/tests/custom-ids.test.ts index 9fb6f74..7578879 100644 --- a/packages/starlight-links-validator/tests/custom-ids.test.ts +++ b/packages/starlight-links-validator/tests/custom-ids.test.ts @@ -12,6 +12,6 @@ test('should validate links with custom IDs', async () => { } catch (error) { expectValidationErrorCount(error, 1, 1) - expectValidationErrors(error, 'test/', [['#heading-with-custom-id', ValidationErrorType.InvalidAnchor]]) + expectValidationErrors(error, 'test/', [['#heading-with-custom-id', ValidationErrorType.InvalidHash]]) } }) diff --git a/packages/starlight-links-validator/tests/fallback.test.ts b/packages/starlight-links-validator/tests/fallback.test.ts index 0f5b90d..686ffdb 100644 --- a/packages/starlight-links-validator/tests/fallback.test.ts +++ b/packages/starlight-links-validator/tests/fallback.test.ts @@ -36,8 +36,8 @@ test('should not build with invalid fallback links', async () => { expectValidationErrors(error, 'en/', [ ['/en/guides/unknown', ValidationErrorType.InvalidLink], ['/en/guides/unknown/', ValidationErrorType.InvalidLink], - ['/en/guides/example#unknown', ValidationErrorType.InvalidAnchor], - ['/en/guides/example/#unknown', ValidationErrorType.InvalidAnchor], + ['/en/guides/example#unknown', ValidationErrorType.InvalidHash], + ['/en/guides/example/#unknown', ValidationErrorType.InvalidHash], ['/es/guides/example', ValidationErrorType.InvalidLink], ['/es/guides/example/', ValidationErrorType.InvalidLink], ]) @@ -45,8 +45,8 @@ test('should not build with invalid fallback links', async () => { expectValidationErrors(error, 'fr/', [ ['/fr/guides/unknown', ValidationErrorType.InvalidLink], ['/fr/guides/unknown/', ValidationErrorType.InvalidLink], - ['/fr/guides/example#unknown', ValidationErrorType.InvalidAnchor], - ['/fr/guides/example/#unknown', ValidationErrorType.InvalidAnchor], + ['/fr/guides/example#unknown', ValidationErrorType.InvalidHash], + ['/fr/guides/example/#unknown', ValidationErrorType.InvalidHash], ]) expectValidationErrors(error, 'fr/guides/test/', [['/', ValidationErrorType.InvalidLink]]) @@ -68,8 +68,8 @@ test('should not build with a root locale and invalid fallback links', async () expectValidationErrors(error, '/', [ ['/guides/unknown', ValidationErrorType.InvalidLink], ['/guides/unknown/', ValidationErrorType.InvalidLink], - ['/guides/example#unknown', ValidationErrorType.InvalidAnchor], - ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor], + ['/guides/example#unknown', ValidationErrorType.InvalidHash], + ['/guides/example/#unknown', ValidationErrorType.InvalidHash], ['/es/guides/example', ValidationErrorType.InvalidLink], ['/es/guides/example/', ValidationErrorType.InvalidLink], ]) @@ -77,8 +77,8 @@ test('should not build with a root locale and invalid fallback links', async () expectValidationErrors(error, 'fr/', [ ['/fr/guides/unknown', ValidationErrorType.InvalidLink], ['/fr/guides/unknown/', ValidationErrorType.InvalidLink], - ['/fr/guides/example#unknown', ValidationErrorType.InvalidAnchor], - ['/fr/guides/example/#unknown', ValidationErrorType.InvalidAnchor], + ['/fr/guides/example#unknown', ValidationErrorType.InvalidHash], + ['/fr/guides/example/#unknown', ValidationErrorType.InvalidHash], ]) expectValidationErrors(error, 'guides/test/', [['/en', ValidationErrorType.InvalidLink]]) diff --git a/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/guides/example.mdx b/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/guides/example.mdx index 5cff26e..972f2b1 100644 --- a/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/guides/example.mdx +++ b/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/guides/example.mdx @@ -13,8 +13,8 @@ import { Card, CardGrid, LinkCard, LinkButton } from '@astrojs/starlight/compone ## Some links -- [Link to invalid anchor in the same page](#links) -- [Link to invalid anchor in another page](/unknown/#links) +- [Link to invalid hash in the same page](#links) +- [Link to invalid hash in another page](/unknown/#links) HTML link to unknown page @@ -37,10 +37,10 @@ some content - - + + LinkButton: unknown page -LinkButton: unknown page and anchor -LinkButton: unknown anchor +LinkButton: unknown page and hash +LinkButton: unknown hash diff --git a/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/test.md b/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/test.md index 6c63e25..5150ea5 100644 --- a/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/test.md +++ b/packages/starlight-links-validator/tests/fixtures/basics-invalid-links/src/content/docs/test.md @@ -18,20 +18,20 @@ title: Test # More links -- [Link to valid anchor in this page](#some-links) -- [Link to invalid anchor in this page](#links) -- [Link to valid anchor in another MDX page](/guides/example/#some-links) -- [Link to invalid anchor in another MDX page](/guides/example/#links) +- [Link to valid hash in this page](#some-links) +- [Link to invalid hash in this page](#links) +- [Link to valid hash in another MDX page](/guides/example/#some-links) +- [Link to invalid hash in another MDX page](/guides/example/#links) - [Link to invalid asset](/icon.svg) - [Link to another invalid asset](/guidelines/ui.pdf) ## Links with references - [Link reference to unknwon page][ref-unknown-page] -- [Link reference to invalid anchor][ref-invalid-anchor] +- [Link reference to invalid hash][ref-invalid-hash] [ref-unknown-page]: /unknown-ref -[ref-invalid-anchor]: #unknown-ref +[ref-invalid-hash]: #unknown-ref
some content diff --git a/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/guides/example.mdx b/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/guides/example.mdx index 861927c..9e670f9 100644 --- a/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/guides/example.mdx +++ b/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/guides/example.mdx @@ -13,7 +13,7 @@ import { Card, CardGrid, LinkCard, LinkButton } from '@astrojs/starlight/compone ## Some links -- [Link to anchor in the same page](#some-links) +- [Link to hash in the same page](#some-links) HTML link to another page @@ -40,10 +40,10 @@ some content - - + + LinkCard: unknown page -LinkCard: unknown page and anchor -LinkCard: unknown anchor +LinkCard: unknown page and hash +LinkCard: unknown hash diff --git a/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/index.md b/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/index.md index 96cc519..06af854 100644 --- a/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/index.md +++ b/packages/starlight-links-validator/tests/fixtures/basics-valid-links/src/content/docs/index.md @@ -21,25 +21,25 @@ title: Index # More links -- [Link to anchor in this page](#some-links) -- [Link to anchor in another MDX page](/guides/example/#some-links) +- [Link to hash in this page](#some-links) +- [Link to hash in another MDX page](/guides/example/#some-links) - [Link to an asset](/favicon.svg) - [Link to another asset](/guidelines/dummy.pdf) ## A more `complex` heading -- [Link to more complex anchor](#a-more-complex-heading) +- [Link to more complex hash](#a-more-complex-heading) ## Links with references - [ref] - [Link reference][ref] -- [Link reference with anchor in this page][ref-with-anchor-internal] -- [Link reference with anchor in another page][ref-with-anchor-external] +- [Link reference with hash in this page][ref-with-hash-internal] +- [Link reference with hash in another page][ref-with-hash-external] [ref]: /test -[ref-with-anchor-internal]: #some-links -[ref-with-anchor-external]: /test#title +[ref-with-hash-internal]: #some-links +[ref-with-hash-external]: /test#title ## Link to page with custom slug diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/astro.config.ts b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/astro.config.ts new file mode 100644 index 0000000..3ffc24f --- /dev/null +++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/astro.config.ts @@ -0,0 +1,13 @@ +import starlight from '@astrojs/starlight' +import { defineConfig } from 'astro/config' + +import starlightLinksValidator from '../..' + +export default defineConfig({ + integrations: [ + starlight({ + plugins: [starlightLinksValidator({ errorOnInvalidHashes: false })], + title: 'Starlight Links Validator Tests - invalid hashes invalid links', + }), + ], +}) diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/guides/example.mdx b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/guides/example.mdx new file mode 100644 index 0000000..972f2b1 --- /dev/null +++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/guides/example.mdx @@ -0,0 +1,46 @@ +--- +title: Example +--- + +import { Card, CardGrid, LinkCard, LinkButton } from '@astrojs/starlight/components' + +## Steps + + + Do something + Do something else + + +## Some links + +- [Link to invalid hash in the same page](#links) +- [Link to invalid hash in another page](/unknown/#links) + +HTML link to unknown page + +
+some content + +some content + +some content + +some content + + + test + +
+ +Link to invalid asset +Link to another invalid asset + + + + + + + +LinkButton: unknown page +LinkButton: unknown page and hash +LinkButton: unknown hash diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/test.md b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/test.md new file mode 100644 index 0000000..c01041e --- /dev/null +++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-invalid-links/src/content/docs/test.md @@ -0,0 +1,48 @@ +--- +title: Test +--- + +# Some links + +- [External link](https://starlight.astro.build/) + +- [External link prefixed with a slash](/https://starlight.astro.build/) + +- [Home page](/) + +- [Unknown page](/unknown) +- [Unknown page](/unknown/) + +- [Unknown page with hash](/unknown#title) +- [Unknown page with hash](/unknown/#title) + +# More links + +- [Link to valid hash in this page](#some-links) +- [Link to invalid hash in this page](#links) +- [Link to valid hash in another MDX page](/guides/example/#some-links) +- [Link to invalid hash in another MDX page](/guides/example/#links) +- [Link to invalid asset](/icon.svg) +- [Link to another invalid asset](/guidelines/ui.pdf) + +## Links with references + +- [Link reference to unknown page][ref-unknown-page] +- [Link reference to invalid hash][ref-invalid-hash] + +[ref-unknown-page]: /unknown-ref +[ref-invalid-hash]: #unknown-ref + +
+some content + +some content + +some content + +some content + + + test + +
diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/astro.config.ts b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/astro.config.ts new file mode 100644 index 0000000..3b15f9f --- /dev/null +++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/astro.config.ts @@ -0,0 +1,13 @@ +import starlight from '@astrojs/starlight' +import { defineConfig } from 'astro/config' + +import starlightLinksValidator from '../..' + +export default defineConfig({ + integrations: [ + starlight({ + plugins: [starlightLinksValidator({ errorOnInvalidHashes: false })], + title: 'Starlight Links Validator Tests - invalid hashes valid links', + }), + ], +}) diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/guides/example.mdx b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/guides/example.mdx new file mode 100644 index 0000000..3dcc264 --- /dev/null +++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/guides/example.mdx @@ -0,0 +1,47 @@ +--- +title: Example +--- + +import { Card, CardGrid, LinkCard, LinkButton } from '@astrojs/starlight/components' + +## Steps + + + Do something + Do something else + + +## Some links + +- [Link to valid hash in the same page](#some-links) +- [Link to invalid hash in the same page](#unknown) + +
+some content + +some content + +some other content + +some content + +unknown block + +some content + + + test text + +
+ + + + + + + + +LinkCard: unknown page and valid hash +LinkCard: unknown page and invalid hash +LinkCard: valid hash +LinkCard: invalid hash diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/index.md b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/index.md new file mode 100644 index 0000000..0ec4cd7 --- /dev/null +++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/index.md @@ -0,0 +1,38 @@ +--- +title: Index +--- + +# Some links + +- [External link](https://starlight.astro.build/) + +- [Home page](/) + +- [Test page](/test) +- [Test page](/test/) + +- [Test page with valid hash](/test#title) +- [Test page with valid hash](/test/#title) + +- [Test page with invalid hash](/test#unknown) +- [Test page with invalid hash](/test/#unknown) + +# More links + +- [Link to valid hash in this page](#some-links) +- [Link to invalid hash in this page](#unknown) +- [Link to valid hash in another MDX page](/guides/example/#some-links) +- [Link to invalid hash in another MDX page](/guides/example/#unknown) + +## Links with references + +- [Link reference with valid hash in this page][ref-with-valid-hash-internal] +- [Link reference with valid hash in another page][ref-with-valid-hash-external] + +- [Link reference with invalid hash in this page][ref-with-invalid-hash-internal] +- [Link reference with invalid hash in another page][ref-with-invalid-hash-external] + +[ref-with-valid-hash-internal]: #some-links +[ref-with-valid-hash-external]: /test#title +[ref-with-invalid-hash-internal]: #unknown +[ref-with-invalid-hash-external]: /test#unknown diff --git a/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/test.md b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/test.md new file mode 100644 index 0000000..1bba7cc --- /dev/null +++ b/packages/starlight-links-validator/tests/fixtures/invalid-hashes-valid-links/src/content/docs/test.md @@ -0,0 +1,27 @@ +--- +title: Test +--- + +## Title + +Some content. + +- [Link to same page](/test) + +
+some content + +some content + +some content + +some content + + + test + +
+ +## Title + +More content. diff --git a/packages/starlight-links-validator/tests/invalid-hashes.test.ts b/packages/starlight-links-validator/tests/invalid-hashes.test.ts new file mode 100644 index 0000000..8f5a11f --- /dev/null +++ b/packages/starlight-links-validator/tests/invalid-hashes.test.ts @@ -0,0 +1,42 @@ +import { expect, test } from 'vitest' + +import { ValidationErrorType } from '../libs/validation' + +import { expectValidationErrorCount, expectValidationErrors, loadFixture } from './utils' + +test('should build with invalid hashes', async () => { + await expect(loadFixture('invalid-hashes-valid-links')).resolves.not.toThrow() +}) + +test('should not build with invalid links but ignore invalid hashes', async () => { + expect.assertions(3) + + try { + await loadFixture('invalid-hashes-invalid-links') + } catch (error) { + expectValidationErrorCount(error, 17, 2) + + expectValidationErrors(error, 'test/', [ + ['/https://starlight.astro.build/', ValidationErrorType.InvalidLink], + ['/', ValidationErrorType.InvalidLink], + ['/unknown', ValidationErrorType.InvalidLink], + ['/unknown/', ValidationErrorType.InvalidLink], + ['/unknown#title', ValidationErrorType.InvalidLink], + ['/unknown/#title', ValidationErrorType.InvalidLink], + ['/icon.svg', ValidationErrorType.InvalidLink], + ['/guidelines/ui.pdf', ValidationErrorType.InvalidLink], + ['/unknown-ref', ValidationErrorType.InvalidLink], + ]) + + expectValidationErrors(error, 'guides/example/', [ + ['/unknown/#links', ValidationErrorType.InvalidLink], + ['/unknown', ValidationErrorType.InvalidLink], + ['/icon.svg', ValidationErrorType.InvalidLink], + ['/guidelines/ui.pdf', ValidationErrorType.InvalidLink], + ['/linkcard/', ValidationErrorType.InvalidLink], + ['/linkcard/#links', ValidationErrorType.InvalidLink], + ['/linkbutton/', ValidationErrorType.InvalidLink], + ['/linkbutton/#links', ValidationErrorType.InvalidLink], + ]) + } +}) diff --git a/packages/starlight-links-validator/tests/relative.test.ts b/packages/starlight-links-validator/tests/relative.test.ts index 871d381..6b7f173 100644 --- a/packages/starlight-links-validator/tests/relative.test.ts +++ b/packages/starlight-links-validator/tests/relative.test.ts @@ -15,8 +15,8 @@ test('should ignore relative links when the `errorOnRelativeLinks` option is set expectValidationErrors(error, 'test/', [ ['/unknown', ValidationErrorType.InvalidLink], ['/unknown/', ValidationErrorType.InvalidLink], - ['/guides/example#unknown', ValidationErrorType.InvalidAnchor], - ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor], + ['/guides/example#unknown', ValidationErrorType.InvalidHash], + ['/guides/example/#unknown', ValidationErrorType.InvalidHash], ]) } }) diff --git a/packages/starlight-links-validator/tests/src-dir.test.ts b/packages/starlight-links-validator/tests/src-dir.test.ts index a00d240..a7fafcf 100644 --- a/packages/starlight-links-validator/tests/src-dir.test.ts +++ b/packages/starlight-links-validator/tests/src-dir.test.ts @@ -15,8 +15,8 @@ test('should validate links when the `srcDir` Astro option is set', async () => expectValidationErrors(error, 'test/', [ ['/unknown', ValidationErrorType.InvalidLink], ['/unknown/', ValidationErrorType.InvalidLink], - ['/guides/example#unknown', ValidationErrorType.InvalidAnchor], - ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor], + ['/guides/example#unknown', ValidationErrorType.InvalidHash], + ['/guides/example/#unknown', ValidationErrorType.InvalidHash], ]) } }) diff --git a/packages/starlight-links-validator/tests/trailing.test.ts b/packages/starlight-links-validator/tests/trailing.test.ts index 9c343c5..f3e4b90 100644 --- a/packages/starlight-links-validator/tests/trailing.test.ts +++ b/packages/starlight-links-validator/tests/trailing.test.ts @@ -17,8 +17,8 @@ test('should validate links when the `trailingSlash` Astro option is set to `nev ['/guides/example/#description', ValidationErrorType.TrailingSlash], ['/unknown', ValidationErrorType.InvalidLink], ['/unknown/', ValidationErrorType.InvalidLink], - ['/guides/example#unknown', ValidationErrorType.InvalidAnchor], - ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor], + ['/guides/example#unknown', ValidationErrorType.InvalidHash], + ['/guides/example/#unknown', ValidationErrorType.InvalidHash], ]) } }) @@ -36,8 +36,8 @@ test('should validate links when the `trailingSlash` Astro option is set to `alw ['/guides/example#description', ValidationErrorType.TrailingSlash], ['/unknown', ValidationErrorType.InvalidLink], ['/unknown/', ValidationErrorType.InvalidLink], - ['/guides/example#unknown', ValidationErrorType.InvalidAnchor], - ['/guides/example/#unknown', ValidationErrorType.InvalidAnchor], + ['/guides/example#unknown', ValidationErrorType.InvalidHash], + ['/guides/example/#unknown', ValidationErrorType.InvalidHash], ]) } })