Socket
Socket
Sign inDemoInstall

eslint-plugin-jsx-a11y

Package Overview
Dependencies
Maintainers
1
Versions
82
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-jsx-a11y - npm Package Compare versions

Comparing version 0.3.1 to 0.4.0

2

.eslintrc.js

@@ -63,3 +63,3 @@ module.exports = {

"jsx-quotes": [ 2, "prefer-double" ],
"max-len": [ 2, 120, 2, {
"max-len": [ 2, 125, 2, {
"ignorePattern": "((^import[^;]+;$)|(^\\s*it\\())",

@@ -66,0 +66,0 @@ "ignoreUrls": true

# img-uses-alt
Enforce that an `img` element contains the `alt` prop. The alt attribute specifies an alternate text for an image, if the image cannot be displayed.
Enforce that an `img` element contains the `alt` prop. The `alt` attribute specifies an alternate text for an image, if the image cannot be displayed.
## Rule details
This rule takes no arguments. However, note that passing props as spread attribute without alt explicitly defined will cause this rule to fail. Explicitly pass down alt prop for rule to pass.
This rule takes one optional argument of type string or an array of strings. These strings determine which JSX elements should be checked for the `alt` prop **including** `img` by default. This is a good use case when you have a wrapper component that simply renders an `img` element (like in React):
```js
// Image.js
const Image = props => {
const {
alt,
...otherProps
} = props;
return (
<img alt={alt} {...otherProps} />
);
}
...
// Header.js (for example)
...
return (
<header>
<Image alt="Logo" src="logo.jpg" />
</header>
);
```
To tell this plugin to also check your `Image` element, specify this in your `.eslintrc` file:
```json
{
"rules": {
"jsx-a11y/img-uses-alt": [ 2, "Image" ], // OR
"jsx-a11y/img-uses-alt": [ 2, [ "Image", "Avatar" ] ]
}
}
```
Note that passing props as spread attribute without `alt` explicitly defined will cause this rule to fail. Explicitly pass down `alt` prop for rule to pass. The prop must have an actual value to pass. Use `Image` component above as a reference for destructuring and applying the prop. **It is a good thing to explicitly pass props that you expect to be passed for self-documentation.**
### Succeed
```jsx
<img src="foo" alt="Foo eating a sandwich." />
<img src="foo" alt={"Foo eating a sandwich."} />
<img src="foo" alt={altText} />
<img src="foo" alt={`${person} smiling`} />
```

@@ -18,2 +58,5 @@

<img {...props} />
<img {...props} alt /> // Has no value
<img {...props} alt={undefined} /> // Has no value
<img {...props} alt={`${undefined}`} /> // Has no value
```

@@ -7,4 +7,30 @@ # no-hash-href

This rule takes no arguments.
This rule takes one optional argument of type string or an array of strings. These strings determine which JSX elements should be checked for the `href` prop **including** `a` by default. This is a good use case when you have a wrapper component that simply renders an `a` element (like in React):
```js
// Link.js
const Link = props => <a {...props}>A link</a>;
...
// NavBar.js (for example)
...
return (
<nav>
<Link href="/home" />
</nav>
);
```
To tell this plugin to also check your `Link` element, specify this in your `.eslintrc` file:
```json
{
"rules": {
"jsx-a11y/no-hash-href": [ 2, "Link" ], // OR
"jsx-a11y/no-hash-href": [ 2, [ "Link", "Anchor" ] ]
}
}
```
### Succeed

@@ -15,2 +41,3 @@ ```jsx

<a href="foo" />
<a href={undefined} /> // This check will pass, but WTF?
```

@@ -23,2 +50,2 @@

<a href={`#`} />
```
```

@@ -13,2 +13,3 @@ # redundant-alt

<img src="bar" aria-hidden alt="Picture of me taking a photo of an image" /> // Will pass because it is hidden.
<img src="baz" alt={`Baz taking a ${photo}`} /> // This is valid since photo is a variable name.
```

@@ -21,2 +22,2 @@

<img src="baz" alt="Picture of baz fixing a bug." />
```
```

@@ -7,4 +7,42 @@ # use-label-for

This rule takes no arguments.
This rule takes one optional argument of type string or array of strings. These strings determine which JSX elements should be checked for the `htmlFor` prop including `label` by default. This is a good use case when you have a wrapper component that simply renders an `label` element (like in React):
```js
// Label.js
const Label = props => {
const {
htmlFor,
...otherProps
} = props;
return (
<label htmlFor={htmlFor} {...otherProps} />
);
}
...
// CreateAccount.js (for example)
...
return (
<form>
<input id="firstName" type="text" />
<Label htmlFor="firstName">First Name</Label>
</form>
);
```
To tell this plugin to also check your `Label` element, specify this in your `.eslintrc` file:
```json
{
"rules": {
"jsx-a11y/use-label-for": [ 2, "Label" ], // OR
"jsx-a11y/use-label-for": [ 2, [ "Label", "InputDescriptor" ] ]
}
}
```
Note that passing props as spread attribute without `htmlFor` explicitly defined will cause this rule to fail. Explicitly pass down `htmlFor` prop for rule to pass. The prop must have an actual value to pass. Use `Label` component above as a reference. **It is a good thing to explicitly pass props that you expect to be passed for self-documentation.**
### Succeed

@@ -20,2 +58,2 @@ ```jsx

<label>First Name</label>
```
```

@@ -20,2 +20,12 @@ 'use strict';

}
},
rules: {
"jsx-a11y/img-uses-alt": 2,
"jsx-a11y/redundant-alt": 2,
"jsx-a11y/onclick-uses-role": 2,
"jsx-a11y/mouse-events-map-to-key-events": 2,
"jsx-a11y/use-onblur-not-onchange": 2,
"jsx-a11y/no-access-key": 2,
"jsx-a11y/use-label-for": 2,
"jsx-a11y/no-hash-href": 2
}

@@ -22,0 +32,0 @@ }

@@ -17,3 +17,5 @@ /**

var errorMessage = 'img elements must have an alt tag.';
var errorMessage = function errorMessage(type) {
return type + ' elements must have an alt tag.';
};

@@ -23,5 +25,7 @@ module.exports = function (context) {

JSXOpeningElement: function JSXOpeningElement(node) {
var type = node.name.name;
// Only check img tags.
if (type !== 'img') {
var typeCheck = ['img'].concat(context.options[0]);
var nodeType = node.name.name;
// Only check 'img' elements and custom types.
if (typeCheck.indexOf(nodeType) === -1) {
return;

@@ -36,3 +40,3 @@ }

node: node,
message: errorMessage
message: errorMessage(nodeType)
});

@@ -44,2 +48,11 @@ }

module.exports.schema = [{ type: 'object' }];
module.exports.schema = [{
"oneOf": [{ "type": "string" }, {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}]
}];

@@ -22,5 +22,7 @@ /**

JSXOpeningElement: function JSXOpeningElement(node) {
var type = node.name.name;
// Only check img tags.
if (type !== 'a') {
var typeCheck = ['a'].concat(context.options[0]);
var nodeType = node.name.name;
// Only check 'a' elements and custom types.
if (typeCheck.indexOf(nodeType) === -1) {
return;

@@ -41,2 +43,11 @@ }

module.exports.schema = [{ type: 'object' }];
module.exports.schema = [{
"oneOf": [{ "type": "string" }, {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}]
}];

@@ -38,3 +38,3 @@ /**

var hasRedundancy = REDUNDANT_WORDS.some(function (word) {
return Boolean(altProp.match(new RegExp(word, 'gi')));
return Boolean(altProp.match(new RegExp('(?!{)' + word + '(?!})', 'gi')));
});

@@ -41,0 +41,0 @@

@@ -22,4 +22,7 @@ /**

JSXOpeningElement: function JSXOpeningElement(node) {
var type = node.name.name;
if (type !== 'label') {
var typeCheck = ['label'].concat(context.options[0]);
var nodeType = node.name.name;
// Only check 'label' elements and custom types.
if (typeCheck.indexOf(nodeType) === -1) {
return;

@@ -40,2 +43,11 @@ }

module.exports.schema = [{ type: 'object' }];
module.exports.schema = [{
"oneOf": [{ "type": "string" }, {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}]
}];

@@ -29,3 +29,3 @@ 'use strict';

} else if (type === 'Identifier') {
return part.name === 'undefined' ? raw : raw + part.name;
return part.name === 'undefined' ? raw : raw + '{' + part.name + '}';
}

@@ -32,0 +32,0 @@

{
"name": "eslint-plugin-jsx-a11y",
"version": "0.3.1",
"version": "0.4.0",
"description": "A static analysis linter of jsx and their accessibility with screen readers.",

@@ -5,0 +5,0 @@ "keywords": [

@@ -24,5 +24,5 @@ <p align="center">

## Why?
Ryan Florence built out this awesome runtime-analysis tool called [react-a11y](https://github.com/reactjs/react-a11y). It is pretty awesome. However, this creates more package-bloat and requries initialization in your code. Since you're probably already using linting in your project, this plugin comes for free and closer to actual development. Pairing this plugin with an editor lint plugin, you can bake accessibility standards into your application in real-time.
Ryan Florence built out this awesome runtime-analysis tool called [react-a11y](https://github.com/reactjs/react-a11y). It is pretty awesome. However, since you're probably already using linting in your project, this plugin comes for free and closer to the actual development process. Pairing this plugin with an editor lint plugin, you can bake accessibility standards into your application in real-time.
Note: This project does not *replace* react-a11y, but can and should be used in conjunction with it. Static analysis tools cannot determine values of variables that are being placed in props before runtime, so linting will not fail if that value is undefined and/or does not pass the lint rule.
**Note**: This project does not *replace* react-a11y, but can and should be used in conjunction with it. Static analysis tools cannot determine values of variables that are being placed in props before runtime, so linting will not fail if that value is undefined and/or does not pass the lint rule.

@@ -29,0 +29,0 @@ ## Installation

@@ -20,2 +20,12 @@ 'use strict';

}
},
rules: {
"jsx-a11y/img-uses-alt": 2,
"jsx-a11y/redundant-alt": 2,
"jsx-a11y/onclick-uses-role": 2,
"jsx-a11y/mouse-events-map-to-key-events": 2,
"jsx-a11y/use-onblur-not-onchange": 2,
"jsx-a11y/no-access-key": 2,
"jsx-a11y/use-label-for": 2,
"jsx-a11y/no-hash-href": 2
}

@@ -22,0 +32,0 @@ }

@@ -13,9 +13,11 @@ /**

const errorMessage = 'img elements must have an alt tag.';
const errorMessage = type => `${type} elements must have an alt tag.`;
module.exports = context => ({
JSXOpeningElement: node => {
const type = node.name.name;
// Only check img tags.
if (type !== 'img') {
const typeCheck = [ 'img' ].concat(context.options[0]);
const nodeType = node.name.name;
// Only check 'img' elements and custom types.
if (typeCheck.indexOf(nodeType) === -1) {
return;

@@ -30,3 +32,3 @@ }

node,
message: errorMessage
message: errorMessage(nodeType)
});

@@ -38,3 +40,15 @@ }

module.exports.schema = [
{ type: 'object' }
{
"oneOf": [
{ "type": "string" },
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
]
}
];

@@ -17,5 +17,7 @@ /**

JSXOpeningElement: node => {
const type = node.name.name;
// Only check img tags.
if (type !== 'a') {
const typeCheck = [ 'a' ].concat(context.options[0]);
const nodeType = node.name.name;
// Only check 'a' elements and custom types.
if (typeCheck.indexOf(nodeType) === -1) {
return;

@@ -36,3 +38,15 @@ }

module.exports.schema = [
{ type: 'object' }
{
"oneOf": [
{ "type": "string" },
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
]
}
];

@@ -34,3 +34,4 @@ /**

if (Boolean(altProp) && typeof altProp === 'string' && isVisible) {
const hasRedundancy = REDUNDANT_WORDS.some(word => Boolean(altProp.match(new RegExp(word, 'gi'))));
const hasRedundancy = REDUNDANT_WORDS
.some(word => Boolean(altProp.match(new RegExp(`(?!{)${word}(?!})`, 'gi'))));

@@ -37,0 +38,0 @@ if (hasRedundancy === true) {

@@ -18,4 +18,7 @@ /**

JSXOpeningElement: node => {
const type = node.name.name;
if (type !== 'label') {
const typeCheck = [ 'label' ].concat(context.options[0]);
const nodeType = node.name.name;
// Only check 'label' elements and custom types.
if (typeCheck.indexOf(nodeType) === -1) {
return;

@@ -36,3 +39,15 @@ }

module.exports.schema = [
{ type: 'object' }
{
"oneOf": [
{ "type": "string" },
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
]
}
];

@@ -25,3 +25,3 @@ 'use strict';

} else if (type === 'Identifier') {
return part.name === 'undefined' ? raw : raw + part.name;
return part.name === 'undefined' ? raw : `${raw}{${part.name}}`;
}

@@ -28,0 +28,0 @@

@@ -24,6 +24,6 @@ /* eslint-env mocha */

// describe('configurations', function() {
// it('should export a \'recommended\' configuration', function() {
// assert(plugin.configs.recommended);
// });
// });
describe('configurations', function() {
it('should export a \'recommended\' configuration', function() {
assert(plugin.configs.recommended);
});
});

@@ -33,4 +33,13 @@ /**

const string = [ 'Avatar' ];
const array = [ [ 'Thumbnail', 'Image' ] ];
const customError = type => ({
message: `${type} elements must have an alt tag.`,
type: 'JSXOpeningElement'
});
ruleTester.run('img-uses-alt', rule, {
valid: [
// DEFAULT ELEMENT 'img' TESTS
{ code: '<img alt="foo" />;', parserOptions },

@@ -48,5 +57,49 @@ { code: '<img alt={"foo"} />;', parserOptions },

{ code: '<img alt={() => void 0} />', parserOptions },
{ code: '<IMG />', parserOptions }
{ code: '<IMG />', parserOptions },
// CUSTOM ELEMENT TESTS FOR STRING OPTION
{ code: '<Avatar alt="foo" />;', options: string, parserOptions },
{ code: '<Avatar alt={"foo"} />;', options: string, parserOptions },
{ code: '<Avatar alt={alt} />;', options: string, parserOptions },
{ code: '<Avatar ALT="foo" />;', options: string, parserOptions },
{ code: '<Avatar ALT={`This is the ${alt} text`} />;', options: string, parserOptions },
{ code: '<Avatar ALt="foo" />;', options: string, parserOptions },
{ code: '<Avatar alt="foo" salt={undefined} />;', options: string, parserOptions },
{ code: '<Avatar {...this.props} alt="foo" />', options: string, parserOptions },
{ code: '<avatar />', options: string, parserOptions },
{ code: '<Avatar alt={function(e) {} } />', options: string, parserOptions },
{ code: '<div alt={function(e) {} } />', options: string, parserOptions },
{ code: '<Avatar alt={() => void 0} />', options: string, parserOptions },
{ code: '<AVATAR />', options: string, parserOptions },
// CUSTOM ELEMENT TESTS FOR ARRAY OPTION TESTS
{ code: '<Thumbnail alt="foo" />;', options: array, parserOptions },
{ code: '<Thumbnail alt={"foo"} />;', options: array, parserOptions },
{ code: '<Thumbnail alt={alt} />;', options: array, parserOptions },
{ code: '<Thumbnail ALT="foo" />;', options: array, parserOptions },
{ code: '<Thumbnail ALT={`This is the ${alt} text`} />;', options: array, parserOptions },
{ code: '<Thumbnail ALt="foo" />;', options: array, parserOptions },
{ code: '<Thumbnail alt="foo" salt={undefined} />;', options: array, parserOptions },
{ code: '<Thumbnail {...this.props} alt="foo" />', options: array, parserOptions },
{ code: '<thumbnail />', options: array, parserOptions },
{ code: '<Thumbnail alt={function(e) {} } />', options: array, parserOptions },
{ code: '<div alt={function(e) {} } />', options: array, parserOptions },
{ code: '<Thumbnail alt={() => void 0} />', options: array, parserOptions },
{ code: '<THUMBNAIL />', options: array, parserOptions },
{ code: '<Image alt="foo" />;', options: array, parserOptions },
{ code: '<Image alt={"foo"} />;', options: array, parserOptions },
{ code: '<Image alt={alt} />;', options: array, parserOptions },
{ code: '<Image ALT="foo" />;', options: array, parserOptions },
{ code: '<Image ALT={`This is the ${alt} text`} />;', options: array, parserOptions },
{ code: '<Image ALt="foo" />;', options: array, parserOptions },
{ code: '<Image alt="foo" salt={undefined} />;', options: array, parserOptions },
{ code: '<Image {...this.props} alt="foo" />', options: array, parserOptions },
{ code: '<image />', options: array, parserOptions },
{ code: '<Image alt={function(e) {} } />', options: array, parserOptions },
{ code: '<div alt={function(e) {} } />', options: array, parserOptions },
{ code: '<Image alt={() => void 0} />', options: array, parserOptions },
{ code: '<IMAGE />', options: array, parserOptions }
],
invalid: [
// DEFAULT ELEMENT 'img' TESTS
{ code: '<img />;', errors: [ expectedError ], parserOptions },

@@ -58,4 +111,29 @@ { code: '<img alt />;', errors: [ expectedError ], parserOptions },

{ code: '<img src="xyz" />', errors: [ expectedError ], parserOptions },
{ code: '<img {...this.props} />', errors: [ expectedError ], parserOptions }
{ code: '<img {...this.props} />', errors: [ expectedError ], parserOptions },
// CUSTOM ELEMENT TESTS FOR STRING OPTION
{ code: '<Avatar />;', errors: [ customError('Avatar') ], options: string, parserOptions },
{ code: '<Avatar alt />;', errors: [ customError('Avatar') ], options: string, parserOptions },
{ code: '<Avatar alt={undefined} />;', errors: [ customError('Avatar') ], options: string, parserOptions },
{ code: '<Avatar alt={`${undefined}`} />;', errors: [ customError('Avatar') ], options: string, parserOptions },
{ code: '<Avatar alt="" />;', errors: [ customError('Avatar') ], options: string, parserOptions },
{ code: '<Avatar src="xyz" />', errors: [ customError('Avatar') ], options: string, parserOptions },
{ code: '<Avatar {...this.props} />', errors: [ customError('Avatar') ], options: string, parserOptions },
// CUSTOM ELEMENT TESTS FOR ARRAY OPTION TESTS
{ code: '<Thumbnail />;', errors: [ customError('Thumbnail') ], options: array, parserOptions },
{ code: '<Thumbnail alt />;', errors: [ customError('Thumbnail') ], options: array, parserOptions },
{ code: '<Thumbnail alt={undefined} />;', errors: [ customError('Thumbnail') ], options: array, parserOptions },
{ code: '<Thumbnail alt={`${undefined}`} />;', errors: [ customError('Thumbnail') ], options: array, parserOptions },
{ code: '<Thumbnail alt="" />;', errors: [ customError('Thumbnail') ], options: array, parserOptions },
{ code: '<Thumbnail src="xyz" />', errors: [ customError('Thumbnail') ], options: array, parserOptions },
{ code: '<Thumbnail {...this.props} />', errors: [ customError('Thumbnail') ], options: array, parserOptions },
{ code: '<Image />;', errors: [ customError('Image') ], options: array, parserOptions },
{ code: '<Image alt />;', errors: [ customError('Image') ], options: array, parserOptions },
{ code: '<Image alt={undefined} />;', errors: [ customError('Image') ], options: array, parserOptions },
{ code: '<Image alt={`${undefined}`} />;', errors: [ customError('Image') ], options: array, parserOptions },
{ code: '<Image alt="" />;', errors: [ customError('Image') ], options: array, parserOptions },
{ code: '<Image src="xyz" />', errors: [ customError('Image') ], options: array, parserOptions },
{ code: '<Image {...this.props} />', errors: [ customError('Image') ], options: array, parserOptions }
]
});

@@ -33,4 +33,8 @@ /**

const string = [ 'Link' ];
const array = [ [ 'Anchor', 'Link' ] ];
ruleTester.run('no-hash-href', rule, {
valid: [
// DEFAULT ELEMENT 'a' TESTS
{ code: '<a />;', parserOptions },

@@ -47,9 +51,63 @@ { code: '<a {...props} />', parserOptions },

{ code: '<a href={"foo"}/>', parserOptions },
{ code: '<a href="#foo" />', parserOptions }
{ code: '<a href="#foo" />', parserOptions },
// CUSTOM ELEMENT TEST FOR STRING OPTION
{ code: '<Link />;', options: string, parserOptions },
{ code: '<Link {...props} />', options: string, parserOptions },
{ code: '<Link href="foo" />', options: string, parserOptions },
{ code: '<Link href={foo} />', options: string, parserOptions },
{ code: '<Link href="/foo" />', options: string, parserOptions },
{ code: '<Link href={`${undefined}`} />', options: string, parserOptions },
{ code: '<div href="foo" />', options: string, parserOptions },
{ code: '<Link href={`${undefined}foo`}/>', options: string, parserOptions },
{ code: '<Link href={`#${undefined}foo`}/>', options: string, parserOptions },
{ code: '<Link href={`#foo`}/>', options: string, parserOptions },
{ code: '<Link href={"foo"}/>', options: string, parserOptions },
{ code: '<Link href="#foo" />', options: string, parserOptions },
// CUSTOM ELEMENT TEST FOR ARRAY OPTION
{ code: '<Anchor />;', options: array, parserOptions },
{ code: '<Anchor {...props} />', options: array, parserOptions },
{ code: '<Anchor href="foo" />', options: array, parserOptions },
{ code: '<Anchor href={foo} />', options: array, parserOptions },
{ code: '<Anchor href="/foo" />', options: array, parserOptions },
{ code: '<Anchor href={`${undefined}`} />', options: array, parserOptions },
{ code: '<div href="foo" />', options: array, parserOptions },
{ code: '<Anchor href={`${undefined}foo`}/>', options: array, parserOptions },
{ code: '<Anchor href={`#${undefined}foo`}/>', options: array, parserOptions },
{ code: '<Anchor href={`#foo`}/>', options: array, parserOptions },
{ code: '<Anchor href={"foo"}/>', options: array, parserOptions },
{ code: '<Anchor href="#foo" />', options: array, parserOptions },
{ code: '<Link />;', options: array, parserOptions },
{ code: '<Link {...props} />', options: array, parserOptions },
{ code: '<Link href="foo" />', options: array, parserOptions },
{ code: '<Link href={foo} />', options: array, parserOptions },
{ code: '<Link href="/foo" />', options: array, parserOptions },
{ code: '<Link href={`${undefined}`} />', options: array, parserOptions },
{ code: '<div href="foo" />', options: array, parserOptions },
{ code: '<Link href={`${undefined}foo`}/>', options: array, parserOptions },
{ code: '<Link href={`#${undefined}foo`}/>', options: array, parserOptions },
{ code: '<Link href={`#foo`}/>', options: array, parserOptions },
{ code: '<Link href={"foo"}/>', options: array, parserOptions },
{ code: '<Link href="#foo" />', options: array, parserOptions }
],
invalid: [
// DEFAULT ELEMENT 'a' TESTS
{ code: '<a href="#" />', errors: [ expectedError ], parserOptions },
{ code: '<a href={"#"} />', errors: [ expectedError ], parserOptions },
{ code: '<a href={`#${undefined}`} />', errors: [ expectedError ], parserOptions }
{ code: '<a href={`#${undefined}`} />', errors: [ expectedError ], parserOptions },
// CUSTOM ELEMENT TEST FOR STRING OPTION
{ code: '<Link href="#" />', errors: [ expectedError ], options: string, parserOptions },
{ code: '<Link href={"#"} />', errors: [ expectedError ], options: string, parserOptions },
{ code: '<Link href={`#${undefined}`} />', errors: [ expectedError ], options: string, parserOptions },
// CUSTOM ELEMENT TEST FOR ARRAY OPTION
{ code: '<Link href="#" />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Link href={"#"} />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Link href={`#${undefined}`} />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Anchor href="#" />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Anchor href={"#"} />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Anchor href={`#${undefined}`} />', errors: [ expectedError ], options: array, parserOptions }
]
});

@@ -48,2 +48,8 @@ /**

{ code: '<img alt={`this should pass for ${now}`} />', parserOptions },
{ code: '<img alt={`this should pass for ${photo}`} />', parserOptions },
{ code: '<img alt={`this should pass for ${image}`} />', parserOptions },
{ code: '<img alt={`this should pass for ${picture}`} />', parserOptions },
{ code: '<img alt={`${photo}`} />', parserOptions },
{ code: '<img alt={`${image}`} />', parserOptions },
{ code: '<img alt={`${picture}`} />', parserOptions },
{ code: '<img alt={"undefined"} />', parserOptions },

@@ -70,4 +76,7 @@ { code: '<img alt={() => {}} />', parserOptions },

{ code: '<img alt="{`photo doing ${things}`}" {...this.props} />', errors: [ expectedError ], parserOptions },
{ code: '<img alt="{`image doing ${things}`}" {...this.props} />', errors: [ expectedError ], parserOptions }
{ code: '<img alt="{`image doing ${things}`}" {...this.props} />', errors: [ expectedError ], parserOptions },
{ code: '<img alt="{`picture doing ${picture}`}" {...this.props} />', errors: [ expectedError ], parserOptions },
{ code: '<img alt="{`photo doing ${photo}`}" {...this.props} />', errors: [ expectedError ], parserOptions },
{ code: '<img alt="{`image doing ${image}`}" {...this.props} />', errors: [ expectedError ], parserOptions }
]
});

@@ -34,4 +34,8 @@ /**

const string = [ 'Label' ];
const array = [ [ 'Label', 'Descriptor' ] ];
ruleTester.run('use-label-for', rule, {
valid: [
// DEFAULT ELEMENT 'label' TESTS
{ code: '<label htmlFor="foo" />', parserOptions },

@@ -44,5 +48,28 @@ { code: '<label htmlFor={"foo"} />', parserOptions },

{ code: '<Label />', parserOptions }, // lower-case convention refers to real HTML elements.
{ code: '<Label htmlFor="foo" />', parserOptions }
{ code: '<Label htmlFor="foo" />', parserOptions },
// CUSTOM ELEMENT STRING OPTION TESTS
{ code: '<Label htmlFor="foo" />', options: string, parserOptions },
{ code: '<Label htmlFor={"foo"} />', options: string, parserOptions },
{ code: '<Label htmlFor={foo} />', options: string, parserOptions },
{ code: '<Label htmlFor={`${id}`} />', options: string, parserOptions },
{ code: '<div />', options: string, parserOptions },
{ code: '<Label htmlFor="foo">Test!</Label>', options: string, parserOptions },
// CUSTOM ELEMENT ARRAY OPTION TESTS
{ code: '<Label htmlFor="foo" />', options: array, parserOptions },
{ code: '<Label htmlFor={"foo"} />', options: array, parserOptions },
{ code: '<Label htmlFor={foo} />', options: array, parserOptions },
{ code: '<Label htmlFor={`${id}`} />', options: array, parserOptions },
{ code: '<div />', options: array, parserOptions },
{ code: '<Label htmlFor="foo">Test!</Label>', options: array, parserOptions },
{ code: '<Descriptor htmlFor="foo" />', options: array, parserOptions },
{ code: '<Descriptor htmlFor={"foo"} />', options: array, parserOptions },
{ code: '<Descriptor htmlFor={foo} />', options: array, parserOptions },
{ code: '<Descriptor htmlFor={`${id}`} />', options: array, parserOptions },
{ code: '<div />', options: array, parserOptions },
{ code: '<Descriptor htmlFor="foo">Test!</Descriptor>', options: array, parserOptions }
],
invalid: [
// DEFAULT ELEMENT 'label' TESTS
{ code: '<label id="foo" />', errors: [ expectedError ], parserOptions },

@@ -52,4 +79,23 @@ { code: '<label htmlFor={undefined} />', errors: [ expectedError ], parserOptions },

{ code: '<label>First Name</label>', errors: [ expectedError ], parserOptions },
{ code: '<label {...props}>Foo</label>', errors: [ expectedError ], parserOptions }
{ code: '<label {...props}>Foo</label>', errors: [ expectedError ], parserOptions },
// CUSTOM ELEMENT STRING OPTION TESTS
{ code: '<Label id="foo" />', errors: [ expectedError ], options: string, parserOptions },
{ code: '<Label htmlFor={undefined} />', errors: [ expectedError ], options: string, parserOptions },
{ code: '<Label htmlFor={`${undefined}`} />', errors: [ expectedError ], options: string, parserOptions },
{ code: '<Label>First Name</Label>', errors: [ expectedError ], options: string, parserOptions },
{ code: '<Label {...props}>Foo</Label>', errors: [ expectedError ], options: string, parserOptions },
// CUSTOM ELEMENT ARRAY OPTION TESTS
{ code: '<Label id="foo" />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Label htmlFor={undefined} />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Label htmlFor={`${undefined}`} />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Label>First Name</Label>', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Label {...props}>Foo</Label>', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Descriptor id="foo" />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Descriptor htmlFor={undefined} />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Descriptor htmlFor={`${undefined}`} />', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Descriptor>First Name</Descriptor>', errors: [ expectedError ], options: array, parserOptions },
{ code: '<Descriptor {...props}>Foo</Descriptor>', errors: [ expectedError ], options: array, parserOptions }
]
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc