Skip to content

Commit

Permalink
add more tests + simple template literal handling
Browse files Browse the repository at this point in the history
  • Loading branch information
slorber committed Dec 14, 2022
1 parent 41ef7a5 commit bf39059
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
20 changes: 20 additions & 0 deletions packages/eslint-plugin/src/rules/__tests__/no-html-links.test.ts
Expand Up @@ -31,6 +31,10 @@ ruleTester.run('prefer-docusaurus-link', rule, {
code: '<a href="https://twitter.com/docusaurus">Twitter</a>',
options: [{ignoreFullyResolved: true}],
},
{
code: '<a href={`https://twitter.com/docusaurus`}>Twitter</a>',
options: [{ignoreFullyResolved: true}],
},
{
code: '<a href="mailto:viktor@malmedal.dev">Contact</a> ',
options: [{ignoreFullyResolved: true}],
Expand Down Expand Up @@ -61,10 +65,26 @@ ruleTester.run('prefer-docusaurus-link', rule, {
code: '<a href="tel:123456789">Call</a>',
errors: errorsJSX,
},
{
code: '<a href={``}>Twitter</a>',
errors: errorsJSX,
},
{
code: '<a href={`https://www.twitter.com/docusaurus`}>Twitter</a>',
errors: errorsJSX,
},
{
code: '<a href="www.twitter.com/docusaurus">Twitter</a>',
options: [{ignoreFullyResolved: true}],
errors: errorsJSX,
},
{
// TODO we might want to make this test pass
// Can template literals be statically pre-evaluated? (Babel can do it)
// eslint-disable-next-line no-template-curly-in-string
code: '<a href={`https://twitter.com/${"docu" + "saurus"} ${"rex"}`}>Twitter</a>',
options: [{ignoreFullyResolved: true}],
errors: errorsJSX,
},
],
});
33 changes: 28 additions & 5 deletions packages/eslint-plugin/src/rules/no-html-links.ts
Expand Up @@ -18,6 +18,17 @@ type Options = [

type MessageIds = 'link';

function isFullyResolvedUrl(urlString: string): boolean {
try {
// href gets coerced to a string when it gets rendered anyway
const url = new URL(String(urlString));
if (url.protocol) {
return true;
}
} catch (e) {}
return false;
}

export default createRule<Options, MessageIds>({
name: 'no-html-links',
meta: {
Expand Down Expand Up @@ -63,13 +74,25 @@ export default createRule<Options, MessageIds>({
);

if (hrefAttr?.value?.type === 'Literal') {
try {
// href gets coerced to a string when it gets rendered anyway
const url = new URL(String(hrefAttr.value.value));
if (url.protocol) {
if (isFullyResolvedUrl(String(hrefAttr.value.value))) {
return;
}
}
if (hrefAttr?.value?.type === 'JSXExpressionContainer') {
const container: TSESTree.JSXExpressionContainer = hrefAttr.value;
const {expression} = container;
if (expression.type === 'TemplateLiteral') {
// Simple static string template literals
if (
expression.expressions.length === 0 &&
expression.quasis.length === 1 &&
expression.quasis[0]?.type === 'TemplateElement' &&
isFullyResolvedUrl(String(expression.quasis[0].value.raw))
) {
return;
}
} catch (e) {}
// TODO add more complex TemplateLiteral cases here
}
}
}

Expand Down

0 comments on commit bf39059

Please sign in to comment.