diff --git a/src/runtime/shared/inspect.ts b/src/runtime/shared/inspect.ts index c5eb0c9..10a9397 100644 --- a/src/runtime/shared/inspect.ts +++ b/src/runtime/shared/inspect.ts @@ -10,6 +10,7 @@ import RuleNoErrorResponse from './inspections/no-error-response-status' import RuleNoJavascript from './inspections/no-javascript' import RuleNoMissingHref from './inspections/no-missing-href' import RuleNoNonAsciiChars from './inspections/no-non-ascii-chars' +import RuleNoUppercaseChars from './inspections/no-uppercase-chars' import RuleNoWhitespace from './inspections/no-whitespace' import RuleTrailingSlash from './inspections/trailing-slash' import RuleRedirects from './redirects' @@ -25,6 +26,7 @@ export const AllInspections = [ RuleNoDocumentRelative(), RuleNoJavascript(), RuleTrailingSlash(), + RuleNoUppercaseChars(), RuleAbsoluteSiteUrls(), RuleRedirects(), RuleDescriptiveLinkText(), diff --git a/src/runtime/shared/inspections/no-uppercase-chars.ts b/src/runtime/shared/inspections/no-uppercase-chars.ts new file mode 100644 index 0000000..0b829cf --- /dev/null +++ b/src/runtime/shared/inspections/no-uppercase-chars.ts @@ -0,0 +1,18 @@ +import { defineRule } from './util' + +export default function RuleNoUppercaseChars() { + return defineRule({ + id: 'no-uppercase-chars', + test({ report, link }) { + if (link.match(/[A-Z]/)) { + report({ + name: 'no-uppercase-chars', + scope: 'warning', + message: 'Links should not contain uppercase characters.', + fix: link.toLowerCase(), + fixDescription: 'Convert to lowercase.', + }) + } + }, + }) +} diff --git a/test/unit/rules/no-uppercase-chars.test.ts b/test/unit/rules/no-uppercase-chars.test.ts new file mode 100644 index 0000000..7d83e18 --- /dev/null +++ b/test/unit/rules/no-uppercase-chars.test.ts @@ -0,0 +1,46 @@ +import type { RuleTestContext } from '../../../src/runtime/types' +import { describe, expect, it } from 'vitest' +import RuleNoUppercaseChars from '../../../src/runtime/shared/inspections/no-uppercase-chars' +import { runRule } from './util' + +describe('rule no-uppercase-chars', () => { + it('works', () => { + expect(runRule({ link: 'https://example.com/PAGE' } as RuleTestContext, RuleNoUppercaseChars())).toMatchInlineSnapshot(` + { + "error": [], + "fix": "https://example.com/page", + "link": "https://example.com/PAGE", + "passes": false, + "textContent": undefined, + "warning": [ + { + "fix": "https://example.com/page", + "fixDescription": "Convert to lowercase.", + "message": "Links should not contain uppercase characters.", + "name": "no-uppercase-chars", + "scope": "warning", + }, + ], + } + `) + + expect(runRule({ link: '/this/IS/a/TEEST' } as RuleTestContext, RuleNoUppercaseChars())).toMatchInlineSnapshot(` + { + "error": [], + "fix": "/this/is/a/teest", + "link": "/this/IS/a/TEEST", + "passes": false, + "textContent": undefined, + "warning": [ + { + "fix": "/this/is/a/teest", + "fixDescription": "Convert to lowercase.", + "message": "Links should not contain uppercase characters.", + "name": "no-uppercase-chars", + "scope": "warning", + }, + ], + } + `) + }) +})