Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

fix anchors rule not correctly apply 4 chars rule #305

Merged
merged 1 commit into from
Oct 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions src/reactA11yAnchorsRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@ import {ErrorTolerantWalker} from './utils/ErrorTolerantWalker';
import {ExtendedMetadata} from './utils/ExtendedMetadata';
import {SyntaxKind} from './utils/SyntaxKind';
import {Utils} from './utils/Utils';
import {getImplicitRole} from './utils/getImplicitRole';
import {
getJsxAttributesFromJsxElement,
getStringLiteral
} from './utils/JsxAttribute';

const ROLE_STRING: string = 'role';

const NO_HASH_FAILURE_STRING: string =
'Do not use # as anchor href.';
const LINK_TEXT_TOO_SHORT_FAILURE_STRING: string =
'Link text should be at least 4 characters long.';
'Link text should be at least 4 characters long. If you are not using <a> ' +
'element as anchor, please specify explicit role, e.g. role=\'button\'';
const UNIQUE_ALT_FAILURE_STRING: string =
'Links with images and text content, the alt attribute should be unique to the text content or empty.';
const SAME_HREF_SAME_TEXT_FAILURE_STRING: string =
Expand Down Expand Up @@ -117,7 +125,7 @@ class ReactA11yAnchorsRuleWalker extends ErrorTolerantWalker {
this.addFailure(this.createFailure(anchorInfo.start, anchorInfo.width, NO_HASH_FAILURE_STRING));
}

if (!anchorInfo.text || anchorInfo.text.length < 4) {
if (this.imageRole(openingElement) === 'link' && (!anchorInfo.text || anchorInfo.text.length < 4)) {
this.addFailure(this.createFailure(anchorInfo.start, anchorInfo.width, LINK_TEXT_TOO_SHORT_FAILURE_STRING));
}

Expand Down Expand Up @@ -202,6 +210,14 @@ class ReactA11yAnchorsRuleWalker extends ErrorTolerantWalker {

return altText;
}

private imageRole(root: ts.Node): string {
const attributesInElement: { [propName: string]: ts.JsxAttribute } = getJsxAttributesFromJsxElement(root);
const roleProp: ts.JsxAttribute = attributesInElement[ROLE_STRING];

// If role attribute is specified, get the role value. Otherwise get the implicit role from tag name.
return roleProp ? getStringLiteral(roleProp) : getImplicitRole(root);
}
}

class AnchorInfo {
Expand Down
24 changes: 20 additions & 4 deletions src/tests/ReactA11yAnchorsRuleTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ describe('reactA11yAnchorsRule', () : void => {

TestHelper.assertViolations(ruleName, script, [
{
"failure": "Link text should be at least 4 characters long.",
"failure": 'Link text should be at least 4 characters long. If you are not using <a> ' +
'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 28, "line": 3 }
Expand Down Expand Up @@ -73,7 +74,8 @@ describe('reactA11yAnchorsRule', () : void => {
"startPosition": { "character": 28, "line": 3 }
},
{
"failure": "Link text should be at least 4 characters long.",
"failure": 'Link text should be at least 4 characters long. If you are not using <a> ' +
'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 28, "line": 3 }
Expand All @@ -93,6 +95,18 @@ describe('reactA11yAnchorsRule', () : void => {
TestHelper.assertViolations(ruleName, script, []);
});

it('should pass when role is not link and length of text less than 4', () => {
// Anchor without 'href' attribute has no corresponding role.
const script: string = `
import React = require('react');
const anchor1 = <a role='button'>add</a>;
const anchor2 = <a role='button'><span className='iconClass'></span></a>;
const anchor3 = <a><img src='someURL' alt='someAlt' /></a>;
`;

TestHelper.assertNoViolation(ruleName, script);
});

it('should fail when length of text less than 4', (): void => {
const script: string = `
import React = require('react');
Expand All @@ -102,13 +116,15 @@ describe('reactA11yAnchorsRule', () : void => {

TestHelper.assertViolations(ruleName, script, [
{
"failure": "Link text should be at least 4 characters long.",
"failure": 'Link text should be at least 4 characters long. If you are not using <a> ' +
'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 33, "line": 3 }
},
{
"failure": "Link text should be at least 4 characters long.",
"failure": 'Link text should be at least 4 characters long. If you are not using <a> ' +
'element as anchor, please specify explicit role, e.g. role=\'button\'',
"name": "file.tsx",
"ruleName": "react-a11y-anchors",
"startPosition": { "character": 33, "line": 4 }
Expand Down