eslint-plugin-test-selectors
Advanced tools
Comparing version 2.0.4 to 2.1.0
# Changelog | ||
- `2.0.0` - new `onSubmit` rule (thank you @@jzatt), upgrade to ESLint 8 and Mocha 9, fix moderate security advisory for `chalk/ansi-regex` | ||
- `1.3.0` - Add auto-fix capability to `onClick` (thank you @bkonuwa and @pixelbandito). ([#8](https://github.com/davidcalhoun/eslint-plugin-test-selectors/pull/8)) | ||
- `1.1.0` | ||
- elements with `disabled` and `readonly` attributes are now ignored by default. See [Custom Rules Options](#custom-rule-options) to customize this behavior. (fixes [#3][i3]) | ||
- `plugin:test-selectors/recommended` now emits warnings by default instead of errors. For the old stricter behavior which emits errors, folks can use `plugin:test-selectors/recommendedWithErrors` (fixes [#4][i4]) | ||
- Refactoring and cleanup. Readme improvements. | ||
- `1.0.1` - fix bug with inline functions (fixes [#1][i1]) | ||
- `1.0.0` - initial release | ||
- `2.1.0` - custom `testAttribute` property now accepts arrays. Also fixes vulnerability in word-wrap. | ||
- `2.0.0` - new `onSubmit` rule (thank you @@jzatt), upgrade to ESLint 8 and Mocha 9, fix moderate security advisory for `chalk/ansi-regex` | ||
- `1.3.0` - Add auto-fix capability to `onClick` (thank you @bkonuwa and @pixelbandito). ([#8](https://github.com/davidcalhoun/eslint-plugin-test-selectors/pull/8)) | ||
- `1.1.0` | ||
- elements with `disabled` and `readonly` attributes are now ignored by default. See [Custom Rules Options](#custom-rule-options) to customize this behavior. (fixes [#3][i3]) | ||
- `plugin:test-selectors/recommended` now emits warnings by default instead of errors. For the old stricter behavior which emits errors, folks can use `plugin:test-selectors/recommendedWithErrors` (fixes [#4][i4]) | ||
- Refactoring and cleanup. Readme improvements. | ||
- `1.0.1` - fix bug with inline functions (fixes [#1][i1]) | ||
- `1.0.0` - initial release |
@@ -9,18 +9,28 @@ module.exports = { | ||
{ | ||
"enum": ["always", "never"] | ||
enum: ['always', 'never'] | ||
}, | ||
{ | ||
"type": "object", | ||
"properties": { | ||
"testAttribute": { | ||
"type": "string" | ||
type: 'object', | ||
properties: { | ||
testAttribute: { | ||
oneOf: [ | ||
{ | ||
type: 'string' | ||
}, | ||
{ | ||
type: 'array', | ||
items: { | ||
type: 'string' | ||
} | ||
} | ||
] | ||
}, | ||
"ignoreDisabled": { | ||
"type": "boolean" | ||
ignoreDisabled: { | ||
type: 'boolean' | ||
}, | ||
"ignoreReadonly": { | ||
"type": "boolean" | ||
ignoreReadonly: { | ||
type: 'boolean' | ||
} | ||
}, | ||
"additionalProperties": false | ||
additionalProperties: false | ||
} | ||
@@ -27,0 +37,0 @@ ], |
@@ -5,8 +5,8 @@ /** | ||
*/ | ||
"use strict"; | ||
'use strict'; | ||
const requireIndex = require("requireindex"); | ||
const requireIndex = require('requireindex'); | ||
module.exports = { | ||
rules: requireIndex(`${ __dirname }/rules`), | ||
rules: requireIndex(`${__dirname}/rules`), | ||
configs: { | ||
@@ -13,0 +13,0 @@ recommended: { |
@@ -5,12 +5,5 @@ /** | ||
*/ | ||
const { | ||
errors, | ||
defaultRuleSchema, | ||
defaults | ||
} = require('../constants'); | ||
const { errors, defaultRuleSchema, defaults } = require('../constants'); | ||
const { | ||
getError, | ||
shouldBypass | ||
} = require('../utils'); | ||
const { getError, shouldBypass } = require('../utils'); | ||
@@ -29,3 +22,3 @@ module.exports = { | ||
create: function(context) { | ||
create: function (context) { | ||
const options = context.options[1] || {}; | ||
@@ -32,0 +25,0 @@ const testAttribute = options.testAttribute || defaults.testAttribute; |
@@ -5,12 +5,5 @@ /** | ||
*/ | ||
const { | ||
errors, | ||
defaultRuleSchema, | ||
defaults | ||
} = require('../constants'); | ||
const { errors, defaultRuleSchema, defaults } = require('../constants'); | ||
const { | ||
getError, | ||
shouldBypass | ||
} = require('../utils'); | ||
const { getError, shouldBypass } = require('../utils'); | ||
@@ -37,3 +30,3 @@ module.exports = { | ||
create: function(context) { | ||
create: function (context) { | ||
const options = context.options[1] || {}; | ||
@@ -40,0 +33,0 @@ const testAttribute = options.testAttribute || defaults.testAttribute; |
@@ -5,12 +5,5 @@ /** | ||
*/ | ||
const { | ||
errors, | ||
defaultRuleSchema, | ||
defaults | ||
} = require('../constants'); | ||
const { errors, defaultRuleSchema, defaults } = require('../constants'); | ||
const { | ||
getError, | ||
shouldBypass | ||
} = require('../utils'); | ||
const { getError, shouldBypass } = require('../utils'); | ||
@@ -29,3 +22,3 @@ module.exports = { | ||
create: function(context) { | ||
create: function (context) { | ||
const options = context.options[1] || {}; | ||
@@ -32,0 +25,0 @@ const testAttribute = options.testAttribute || defaults.testAttribute; |
@@ -5,12 +5,5 @@ /** | ||
*/ | ||
const { | ||
errors, | ||
defaultRuleSchema, | ||
defaults | ||
} = require('../constants'); | ||
const { errors, defaultRuleSchema, defaults } = require('../constants'); | ||
const { | ||
getError, | ||
shouldBypass | ||
} = require('../utils'); | ||
const { getError, shouldBypass } = require('../utils'); | ||
@@ -29,3 +22,3 @@ module.exports = { | ||
create: function(context) { | ||
create: function (context) { | ||
const options = context.options[1] || {}; | ||
@@ -32,0 +25,0 @@ const testAttribute = options.testAttribute || defaults.testAttribute; |
@@ -5,12 +5,5 @@ /** | ||
*/ | ||
const { | ||
errors, | ||
defaultRuleSchema, | ||
defaults | ||
} = require('../constants'); | ||
const { errors, defaultRuleSchema, defaults } = require('../constants'); | ||
const { | ||
getError, | ||
shouldBypass | ||
} = require('../utils'); | ||
const { getError, shouldBypass } = require('../utils'); | ||
@@ -29,3 +22,3 @@ module.exports = { | ||
create: function(context) { | ||
create: function (context) { | ||
const options = context.options[1] || {}; | ||
@@ -52,11 +45,9 @@ const testAttribute = options.testAttribute || defaults.testAttribute; | ||
const namePositionEnd = node.name.range[1]; | ||
const attributeText = `${ testAttribute }="${ suggestedId }"`; | ||
const singleTestAttribute = Array.isArray(testAttribute) ? testAttribute[0] : testAttribute; | ||
const attributeText = `${singleTestAttribute}="${suggestedId}"`; | ||
const start = namePositionEnd - 1; | ||
const end = start + 1; | ||
return fixer.insertTextAfterRange( | ||
[start, end], | ||
` ${ attributeText }` | ||
); | ||
}, | ||
return fixer.insertTextAfterRange([start, end], ` ${attributeText}`); | ||
} | ||
}); | ||
@@ -63,0 +54,0 @@ } |
@@ -5,12 +5,5 @@ /** | ||
*/ | ||
const { | ||
errors, | ||
defaultRuleSchema, | ||
defaults | ||
} = require('../constants'); | ||
const { errors, defaultRuleSchema, defaults } = require('../constants'); | ||
const { | ||
getError, | ||
shouldBypass | ||
} = require('../utils'); | ||
const { getError, shouldBypass } = require('../utils'); | ||
@@ -29,3 +22,3 @@ module.exports = { | ||
create: function(context) { | ||
create: function (context) { | ||
const options = context.options[1] || {}; | ||
@@ -32,0 +25,0 @@ const testAttribute = options.testAttribute || defaults.testAttribute; |
@@ -5,12 +5,5 @@ /** | ||
*/ | ||
const { | ||
errors, | ||
defaultRuleSchema, | ||
defaults | ||
} = require('../constants'); | ||
const { errors, defaultRuleSchema, defaults } = require('../constants'); | ||
const { | ||
getError, | ||
shouldBypass | ||
} = require('../utils'); | ||
const { getError, shouldBypass } = require('../utils'); | ||
@@ -29,3 +22,3 @@ module.exports = { | ||
create: function(context) { | ||
create: function (context) { | ||
const options = context.options[1] || {}; | ||
@@ -32,0 +25,0 @@ const testAttribute = options.testAttribute || defaults.testAttribute; |
/** | ||
* @fileoverview Requires test attribute data-test-id on elements with the onSubmit property. | ||
*/ | ||
const { | ||
errors, | ||
defaultRuleSchema, | ||
defaults | ||
} = require('../constants'); | ||
const { errors, defaultRuleSchema, defaults } = require('../constants'); | ||
const { | ||
getError, | ||
shouldBypass | ||
} = require('../utils'); | ||
const { getError, shouldBypass } = require('../utils'); | ||
@@ -27,3 +20,3 @@ module.exports = { | ||
create: function(context) { | ||
create: function (context) { | ||
const options = context.options[1] || {}; | ||
@@ -30,0 +23,0 @@ const testAttribute = options.testAttribute || defaults.testAttribute; |
@@ -1,10 +0,4 @@ | ||
const { | ||
elementType, | ||
getProp, | ||
getPropValue, | ||
} = require('jsx-ast-utils'); | ||
const { elementType, getProp, getPropValue } = require('jsx-ast-utils'); | ||
const { | ||
defaults | ||
} = require('./constants'); | ||
const { defaults } = require('./constants'); | ||
@@ -15,3 +9,5 @@ // Hacky use of the Function constructor here, not sure there's a better way, other than using | ||
const fillTemplate = (str, vars) => { | ||
return new Function(`return \`${ str }\`;`).call(vars); | ||
vars.attribute = Array.isArray(vars.attribute) ? vars.attribute.join(', or ') : vars.attribute; | ||
return new Function(`return \`${str}\`;`).call(vars); | ||
}; | ||
@@ -24,5 +20,10 @@ | ||
const attributeTest = (node, { attribute, test }) => { | ||
const attributeValue = getValue(node, attribute); | ||
const attrs = Array.isArray(attribute) ? attribute : [attribute]; | ||
const type = elementType(node); | ||
return test({ attributeValue, elementType: type }); | ||
// One of the attributes must be present on the node | ||
return attrs.some((attr) => { | ||
const attributeValue = getValue(node, attr); | ||
return test({ attributeValue, elementType: type }); | ||
}); | ||
}; | ||
@@ -36,6 +37,7 @@ | ||
shouldBypass: (node, options, rawTests) => { | ||
const tests = [ ...rawTests ]; | ||
const tests = [...rawTests]; | ||
// Ignore elements with a `disabled` attribute. | ||
const shouldIgnoreDisabled = (typeof options.ignoreDisabled === 'boolean' && options.ignoreDisabled) || | ||
const shouldIgnoreDisabled = | ||
(typeof options.ignoreDisabled === 'boolean' && options.ignoreDisabled) || | ||
(typeof options.ignoreDisabled === 'undefined' && defaults.ignoreDisabled); | ||
@@ -50,3 +52,4 @@ if (shouldIgnoreDisabled) { | ||
// Ignore elements with a `readonly` attribute. | ||
const shouldIgnoreReadonly = (typeof options.ignoreReadonly === 'boolean' && options.ignoreReadonly) || | ||
const shouldIgnoreReadonly = | ||
(typeof options.ignoreReadonly === 'boolean' && options.ignoreReadonly) || | ||
(typeof options.ignoreReadonly === 'undefined' && defaults.ignoreReadonly); | ||
@@ -66,5 +69,7 @@ if (shouldIgnoreReadonly) { | ||
test: ({ attributeValue }) => { | ||
return typeof attributeValue !== 'undefined' && | ||
return ( | ||
typeof attributeValue !== 'undefined' && | ||
typeof attributeValue !== 'boolean' && | ||
attributeValue !== null; | ||
attributeValue !== null | ||
); | ||
} | ||
@@ -71,0 +76,0 @@ }); |
{ | ||
"name": "eslint-plugin-test-selectors", | ||
"version": "2.0.4", | ||
"version": "2.1.0", | ||
"description": "Makes sure test DOM attributes (e.g. data-test-id) are added to interactive DOM elements.", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/davidcalhoun/eslint-plugin-test-selectors#readme", |
# eslint-plugin-test-selectors | ||
[![Build Status](https://travis-ci.org/davidcalhoun/eslint-plugin-test-selectors.svg?branch=master)](https://travis-ci.org/davidcalhoun/eslint-plugin-test-selectors) | ||
[![Downloads][downloads-image]][npm-url] | ||
@@ -8,4 +7,4 @@ | ||
- ❌ `<button>Download</button>` | ||
- ✅ `<button data-test-id="download-button">Download</button>` | ||
- ❌ `<button>Download</button>` | ||
- ✅ `<button data-test-id="download-button">Download</button>` | ||
@@ -16,13 +15,10 @@ ### Example of eslint-plugin-test-selectors running in Visual Studio Code: | ||
## Changelog | ||
## Selected changelog | ||
- `2.0.0` - new `onSubmit` rule (thank you @@jzatt), upgrade to ESLint 8 and Mocha 9, fix moderate security advisory for `chalk/ansi-regex` | ||
- `1.3.0` - Add auto-fix capability to `onClick` (thank you @bkonuwa and @pixelbandito). ([#8](https://github.com/davidcalhoun/eslint-plugin-test-selectors/pull/8)) | ||
- `1.1.0` | ||
- elements with `disabled` and `readonly` attributes are now ignored by default. See [Custom Rules Options](#custom-rule-options) to customize this behavior. (fixes [#3][i3]) | ||
- `plugin:test-selectors/recommended` now emits warnings by default instead of errors. For the old stricter behavior which emits errors, folks can use `plugin:test-selectors/recommendedWithErrors` (fixes [#4][i4]) | ||
- Refactoring and cleanup. Readme improvements. | ||
- `1.0.1` - fix bug with inline functions (fixes [#1][i1]) | ||
- `1.0.0` - initial release | ||
[See full changelog](https://github.com/davidcalhoun/eslint-plugin-test-selectors/blob/main/changelog.md) | ||
- `2.1.0` - custom `testAttribute` property now accepts arrays. Also fixes vulnerability in word-wrap. | ||
- `2.0.0` - new `onSubmit` rule (thank you @@jzatt), upgrade to ESLint 8 and Mocha 9, fix moderate security advisory for `chalk/ansi-regex` | ||
- `1.3.0` - Add auto-fix capability to `onClick` (thank you @bkonuwa and @pixelbandito). ([#8](https://github.com/davidcalhoun/eslint-plugin-test-selectors/pull/8)) | ||
## Installation | ||
@@ -50,3 +46,3 @@ | ||
{ | ||
"plugins": ["test-selectors"] | ||
"plugins": ["test-selectors"] | ||
} | ||
@@ -59,3 +55,3 @@ ``` | ||
{ | ||
"extends": ["plugin:test-selectors/recommended"] | ||
"extends": ["plugin:test-selectors/recommended"] | ||
} | ||
@@ -70,5 +66,5 @@ ``` | ||
{ | ||
"rules": { | ||
"test-selectors/button": ["warn", "always"] | ||
} | ||
"rules": { | ||
"test-selectors/button": ["warn", "always"] | ||
} | ||
} | ||
@@ -81,5 +77,5 @@ ``` | ||
{ | ||
"rules": { | ||
"test-selectors/anchor": "off" | ||
} | ||
"rules": { | ||
"test-selectors/anchor": "off" | ||
} | ||
} | ||
@@ -100,12 +96,18 @@ ``` | ||
{ | ||
"rules": { | ||
"test-selectors/onChange": [ | ||
"warn", | ||
"always", | ||
{ "testAttribute": "data-some-custom-attribute" } | ||
] | ||
} | ||
"rules": { | ||
"test-selectors/onChange": ["warn", "always", { "testAttribute": "data-some-custom-attribute" }] | ||
} | ||
} | ||
``` | ||
Note: You can also pass multiple attributes | ||
```json | ||
{ | ||
"rules": { | ||
"test-selectors/onChange": ["warn", "always", { "testAttribute": ["data-testid", "testId"] }] | ||
} | ||
} | ||
``` | ||
### ignoreDisabled | ||
@@ -117,5 +119,5 @@ | ||
{ | ||
"rules": { | ||
"test-selectors/onChange": ["warn", "always", { "ignoreDisabled": false }] | ||
} | ||
"rules": { | ||
"test-selectors/onChange": ["warn", "always", { "ignoreDisabled": false }] | ||
} | ||
} | ||
@@ -130,5 +132,5 @@ ``` | ||
{ | ||
"rules": { | ||
"test-selectors/onChange": ["warn", "always", { "ignoreReadonly": false }] | ||
} | ||
"rules": { | ||
"test-selectors/onChange": ["warn", "always", { "ignoreReadonly": false }] | ||
} | ||
} | ||
@@ -143,5 +145,5 @@ ``` | ||
{ | ||
"rules": { | ||
"test-selectors/button": ["warn", "always", { "htmlOnly": true }] | ||
} | ||
"rules": { | ||
"test-selectors/button": ["warn", "always", { "htmlOnly": true }] | ||
} | ||
} | ||
@@ -152,10 +154,10 @@ ``` | ||
- `test-selectors/anchor` | ||
- `test-selectors/button` | ||
- `test-selectors/input` | ||
- `test-selectors/onChange` | ||
- `test-selectors/onClick` | ||
- `test-selectors/onKeyDown` | ||
- `test-selectors/onKeyUp` | ||
- `test-selectors/onSubmit` | ||
- `test-selectors/anchor` | ||
- `test-selectors/button` | ||
- `test-selectors/input` | ||
- `test-selectors/onChange` | ||
- `test-selectors/onClick` | ||
- `test-selectors/onKeyDown` | ||
- `test-selectors/onKeyUp` | ||
- `test-selectors/onSubmit` | ||
@@ -168,5 +170,5 @@ ## Further Reading | ||
- [Decoupling CSS Selectors From Your Tests](https://mixandgo.com/learn/decoupling-css-selectors-from-your-tests) | ||
- [Test your DOM with Data Attributes](https://medium.com/@colecodes/test-your-dom-with-data-attributes-44fccc43ed4b) | ||
- [Something Better than IDs for Identifying Elements in Selenium Tests](https://techblog.constantcontact.com/software-development/a-better-way-to-id-elements-in-selenium-tests/) | ||
- [Decoupling CSS Selectors From Your Tests](https://mixandgo.com/learn/decoupling-css-selectors-from-your-tests) | ||
- [Test your DOM with Data Attributes](https://medium.com/@colecodes/test-your-dom-with-data-attributes-44fccc43ed4b) | ||
- [Something Better than IDs for Identifying Elements in Selenium Tests](https://techblog.constantcontact.com/software-development/a-better-way-to-id-elements-in-selenium-tests/) | ||
@@ -173,0 +175,0 @@ [downloads-image]: https://img.shields.io/npm/dm/eslint-plugin-test-selectors.svg?style=flat-square |
@@ -7,6 +7,3 @@ /** | ||
const parserOptionsMapper = require('../../parserOptionsMapper'); | ||
const { | ||
defaults, | ||
errors | ||
} = require('../../../lib/constants'); | ||
const { defaults, errors } = require('../../../lib/constants'); | ||
const { getError } = require('../../../lib/utils'); | ||
@@ -32,3 +29,5 @@ | ||
{ code: `<area href="example.com" />` }, | ||
{ code: `<base href="example.com" />` } | ||
{ code: `<base href="example.com" />` }, | ||
{ code: `<a testId={ bar }>Foo</a>`, options: ['always', { testAttribute: 'testId' }] }, | ||
{ code: `<a data-testid={ bar }>Foo</a>`, options: ['always', { testAttribute: ['testId', 'data-testid'] }] } | ||
].map(parserOptionsMapper), | ||
@@ -46,3 +45,8 @@ | ||
{ code: '<Link href="example.com" />', errors: [anchorError] }, | ||
{ | ||
code: `<a data-test-id={ bar }>Foo</a>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }], | ||
errors: [getError(anchor.message, ['testId', 'data-testid'])] | ||
} | ||
].map(parserOptionsMapper) | ||
}); |
@@ -7,6 +7,3 @@ /** | ||
const parserOptionsMapper = require('../../parserOptionsMapper'); | ||
const { | ||
defaults, | ||
errors | ||
} = require('../../../lib/constants'); | ||
const { defaults, errors } = require('../../../lib/constants'); | ||
const { getError } = require('../../../lib/utils'); | ||
@@ -31,3 +28,5 @@ | ||
{ code: `<button readonly />` }, | ||
{ code: `<Button>Foo</Button>`, options: ["warn", {htmlOnly: true}] } | ||
{ code: `<Button>Foo</Button>`, options: ['warn', { htmlOnly: true }] }, | ||
{ code: `<button testId={ bar } />`, options: ['always', { testAttribute: 'testId' }] }, | ||
{ code: `<button data-testid={ bar } />`, options: ['always', { testAttribute: ['testId', 'data-testid'] }] } | ||
].map(parserOptionsMapper), | ||
@@ -47,4 +46,9 @@ | ||
{ code: '<button disabled={ foo } />', errors: [buttonError] }, | ||
{ code: '<button readonly={ foo } />', errors: [buttonError] } | ||
{ code: '<button readonly={ foo } />', errors: [buttonError] }, | ||
{ | ||
code: `<button data-test-id={ bar } />`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }], | ||
errors: [getError(button.message, ['testId', 'data-testid'])] | ||
} | ||
].map(parserOptionsMapper) | ||
}); |
@@ -7,6 +7,3 @@ /** | ||
const parserOptionsMapper = require('../../parserOptionsMapper'); | ||
const { | ||
defaults, | ||
errors | ||
} = require('../../../lib/constants'); | ||
const { defaults, errors } = require('../../../lib/constants'); | ||
const { getError } = require('../../../lib/utils'); | ||
@@ -26,2 +23,7 @@ | ||
{ code: `<input readonly />` }, | ||
{ code: `<input testId={ bar }>Foo</input>`, options: ['always', { testAttribute: 'testId' }] }, | ||
{ | ||
code: `<input data-testid={ bar }>Foo</input>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }] | ||
} | ||
].map(parserOptionsMapper), | ||
@@ -36,4 +38,9 @@ | ||
{ code: '<input disabled={ foo } />', errors: [inputError] }, | ||
{ code: '<input readonly={ foo } />', errors: [inputError] } | ||
{ code: '<input readonly={ foo } />', errors: [inputError] }, | ||
{ | ||
code: `<input data-test-id={ bar }>Foo</input>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }], | ||
errors: [getError(input.message, ['testId', 'data-testid'])] | ||
} | ||
].map(parserOptionsMapper) | ||
}); |
@@ -7,6 +7,3 @@ /** | ||
const parserOptionsMapper = require('../../parserOptionsMapper'); | ||
const { | ||
defaults, | ||
errors | ||
} = require('../../../lib/constants'); | ||
const { defaults, errors } = require('../../../lib/constants'); | ||
const { getError } = require('../../../lib/utils'); | ||
@@ -21,5 +18,5 @@ | ||
valid: [ | ||
{ code: `<div onChange={ this.handleClick } data-test-id={ bar }>Foo</div>` }, | ||
{ code: `<div onChange={ this.handleClick } data-test-id="bar">Foo</div>` }, | ||
{ code: `<div onChange={ this.handleClick } data-test-id="bar" />` }, | ||
{ code: `<div onChange={ this.handleChange } data-test-id={ bar }>Foo</div>` }, | ||
{ code: `<div onChange={ this.handleChange } data-test-id="bar">Foo</div>` }, | ||
{ code: `<div onChange={ this.handleChange } data-test-id="bar" />` }, | ||
{ code: `<div onChange={ () => {} } data-test-id={ bar }>Foo</div>` }, | ||
@@ -32,14 +29,27 @@ { code: `<div onChange={ () => {} } data-test-id="bar">Foo</div>` }, | ||
{ code: `<Bar onChange={ () => {} } disabled />` }, | ||
{ code: `<Bar onChange={ () => {} } readonly />` } | ||
{ code: `<Bar onChange={ () => {} } readonly />` }, | ||
{ | ||
code: `<div onChange={ this.handleChange } testId={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: 'testId' }] | ||
}, | ||
{ | ||
code: `<div onChange={ this.handleChange } data-testid={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }] | ||
} | ||
].map(parserOptionsMapper), | ||
invalid: [ | ||
{ code: '<div onChange={ this.handleClick } />', errors: [onChangeError] }, | ||
{ code: '<div onChange={ this.handleClick }>foo</div>', errors: [onChangeError] }, | ||
{ code: '<Bar onChange={ this.handleClick } />', errors: [onChangeError] }, | ||
{ code: '<Bar onChange={ this.handleClick }>foo</Bar>', errors: [onChangeError] }, | ||
{ code: '<div onChange={ this.handleChange } />', errors: [onChangeError] }, | ||
{ code: '<div onChange={ this.handleChange }>foo</div>', errors: [onChangeError] }, | ||
{ code: '<Bar onChange={ this.handleChange } />', errors: [onChangeError] }, | ||
{ code: '<Bar onChange={ this.handleChange }>foo</Bar>', errors: [onChangeError] }, | ||
{ code: '<Bar onChange={ () => handleChange() }>foo</Bar>', errors: [onChangeError] }, | ||
{ code: '<Bar onChange={ () => handleChange() } disabled={ foo }>foo</Bar>', errors: [onChangeError] }, | ||
{ code: '<Bar onChange={ () => handleChange() } readonly={ foo }>foo</Bar>', errors: [onChangeError] } | ||
{ code: '<Bar onChange={ () => handleChange() } readonly={ foo }>foo</Bar>', errors: [onChangeError] }, | ||
{ | ||
code: `<div onChange={ this.handleChange } data-test-id={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }], | ||
errors: [getError(onChange.message, ['testId', 'data-testid'])] | ||
} | ||
].map(parserOptionsMapper) | ||
}); |
@@ -7,6 +7,3 @@ /** | ||
const parserOptionsMapper = require('../../parserOptionsMapper'); | ||
const { | ||
defaults, | ||
errors | ||
} = require('../../../lib/constants'); | ||
const { defaults, errors } = require('../../../lib/constants'); | ||
const { getError } = require('../../../lib/utils'); | ||
@@ -22,3 +19,3 @@ const nanoidMock = require('mock-require'); | ||
return 'AbYK0YPm2OWYiMaFPKLbp'; | ||
}, | ||
} | ||
}); | ||
@@ -42,3 +39,11 @@ | ||
{ code: `<Bar onClick={ () => {} } disabled />` }, | ||
{ code: `<Bar onClick={ () => {} } readonly />` } | ||
{ code: `<Bar onClick={ () => {} } readonly />` }, | ||
{ | ||
code: `<div onClick={ this.handleClick } testId={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: 'testId' }] | ||
}, | ||
{ | ||
code: `<div onClick={ this.handleClick } data-testid={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }] | ||
} | ||
].map(parserOptionsMapper), | ||
@@ -50,3 +55,3 @@ | ||
errors: [onClickError], | ||
output: `<div data-test-id="${ suggestedId }" onClick={ this.handleClick } />`, | ||
output: `<div data-test-id="${suggestedId}" onClick={ this.handleClick } />` | ||
}, | ||
@@ -56,3 +61,3 @@ { | ||
errors: [onClickError], | ||
output: `<div data-test-id="${ suggestedId }" onClick={ this.handleClick }>foo</div>`, | ||
output: `<div data-test-id="${suggestedId}" onClick={ this.handleClick }>foo</div>` | ||
}, | ||
@@ -62,3 +67,3 @@ { | ||
errors: [onClickError], | ||
output: `<Bar data-test-id="${ suggestedId }" onClick={ this.handleClick } />`, | ||
output: `<Bar data-test-id="${suggestedId}" onClick={ this.handleClick } />` | ||
}, | ||
@@ -68,3 +73,3 @@ { | ||
errors: [onClickError], | ||
output: `<Bar data-test-id="${ suggestedId }" onClick={ this.handleClick }>foo</Bar>`, | ||
output: `<Bar data-test-id="${suggestedId}" onClick={ this.handleClick }>foo</Bar>` | ||
}, | ||
@@ -74,3 +79,3 @@ { | ||
errors: [onClickError], | ||
output: `<Bar data-test-id="${ suggestedId }" onClick={ () => handleClick() }>foo</Bar>`, | ||
output: `<Bar data-test-id="${suggestedId}" onClick={ () => handleClick() }>foo</Bar>` | ||
}, | ||
@@ -80,3 +85,3 @@ { | ||
errors: [onClickError], | ||
output: `<Bar data-test-id="${ suggestedId }" onClick={ () => handleClick() } disabled={ foo }>foo</Bar>`, | ||
output: `<Bar data-test-id="${suggestedId}" onClick={ () => handleClick() } disabled={ foo }>foo</Bar>` | ||
}, | ||
@@ -86,3 +91,3 @@ { | ||
errors: [onClickError], | ||
output: `<Bar data-test-id="${ suggestedId }" onClick={ () => handleClick() } readonly={ foo }>foo</Bar>`, | ||
output: `<Bar data-test-id="${suggestedId}" onClick={ () => handleClick() } readonly={ foo }>foo</Bar>` | ||
}, | ||
@@ -92,6 +97,11 @@ { | ||
errors: [onClickError], | ||
output: | ||
`<Foo.Bar data-test-id="${ suggestedId }" onClick={ () => handleClick() } readonly={ foo }>foo</Foo.Bar>`, | ||
output: `<Foo.Bar data-test-id="${suggestedId}" onClick={ () => handleClick() } readonly={ foo }>foo</Foo.Bar>` | ||
}, | ||
{ | ||
code: `<div onClick={ this.handleClick } data-test-id={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }], | ||
errors: [getError(onClick.message, ['testId', 'data-testid'])], | ||
output: `<div testId="${suggestedId}" onClick={ this.handleClick } data-test-id={ bar }>Foo</div>` | ||
} | ||
].map(parserOptionsMapper) | ||
}); |
@@ -7,6 +7,3 @@ /** | ||
const parserOptionsMapper = require('../../parserOptionsMapper'); | ||
const { | ||
defaults, | ||
errors | ||
} = require('../../../lib/constants'); | ||
const { defaults, errors } = require('../../../lib/constants'); | ||
const { getError } = require('../../../lib/utils'); | ||
@@ -31,3 +28,11 @@ | ||
{ code: `<Bar onKeyDown={ () => {} } disabled />` }, | ||
{ code: `<Bar onKeyDown={ () => {} } readonly />` } | ||
{ code: `<Bar onKeyDown={ () => {} } readonly />` }, | ||
{ | ||
code: `<div onKeyDown={ this.handleKeyDown } testId={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: 'testId' }] | ||
}, | ||
{ | ||
code: `<div onKeyDown={ this.handleKeyDown } data-testid={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }] | ||
} | ||
].map(parserOptionsMapper), | ||
@@ -42,4 +47,9 @@ | ||
{ code: '<Bar onKeyDown={ () => handleKeyDown() } disabled={ bar }>foo</Bar>', errors: [onKeyDownError] }, | ||
{ code: '<Bar onKeyDown={ () => handleKeyDown() } readonly={ bar }>foo</Bar>', errors: [onKeyDownError] } | ||
{ code: '<Bar onKeyDown={ () => handleKeyDown() } readonly={ bar }>foo</Bar>', errors: [onKeyDownError] }, | ||
{ | ||
code: `<div onKeyDown={ this.handleKeyDown } data-test-id={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }], | ||
errors: [getError(onKeyDown.message, ['testId', 'data-testid'])] | ||
} | ||
].map(parserOptionsMapper) | ||
}); |
@@ -7,6 +7,3 @@ /** | ||
const parserOptionsMapper = require('../../parserOptionsMapper'); | ||
const { | ||
defaults, | ||
errors | ||
} = require('../../../lib/constants'); | ||
const { defaults, errors } = require('../../../lib/constants'); | ||
const { getError } = require('../../../lib/utils'); | ||
@@ -31,3 +28,11 @@ | ||
{ code: `<Bar onKeyUp={ () => {} } disabled />` }, | ||
{ code: `<Bar onKeyUp={ () => {} } readonly />` } | ||
{ code: `<Bar onKeyUp={ () => {} } readonly />` }, | ||
{ | ||
code: `<div onKeyUp={ this.handleKeyUp } testId={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: 'testId' }] | ||
}, | ||
{ | ||
code: `<div onKeyUp={ this.handleKeyUp } data-testid={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }] | ||
} | ||
].map(parserOptionsMapper), | ||
@@ -42,4 +47,9 @@ | ||
{ code: '<Bar onKeyUp={ () => handleKeyUp() } disabled={ bar }>foo</Bar>', errors: [onKeyUpError] }, | ||
{ code: '<Bar onKeyUp={ () => handleKeyUp() } readonly={ bar }>foo</Bar>', errors: [onKeyUpError] } | ||
{ code: '<Bar onKeyUp={ () => handleKeyUp() } readonly={ bar }>foo</Bar>', errors: [onKeyUpError] }, | ||
{ | ||
code: `<div onKeyUp={ this.handleKeyUp } data-test-id={ bar }>Foo</div>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }], | ||
errors: [getError(onKeyUp.message, ['testId', 'data-testid'])] | ||
} | ||
].map(parserOptionsMapper) | ||
}); |
@@ -7,6 +7,3 @@ /** | ||
const parserOptionsMapper = require('../../parserOptionsMapper'); | ||
const { | ||
defaults, | ||
errors | ||
} = require('../../../lib/constants'); | ||
const { defaults, errors } = require('../../../lib/constants'); | ||
const { getError } = require('../../../lib/utils'); | ||
@@ -31,3 +28,11 @@ | ||
{ code: `<Bar onSubmit={ () => {} } disabled />` }, | ||
{ code: `<Bar onSubmit={ () => {} } readonly />` } | ||
{ code: `<Bar onSubmit={ () => {} } readonly />` }, | ||
{ | ||
code: `<form onSubmit={ this.handleSubmit } testId={ bar }>Foo</form>`, | ||
options: ['always', { testAttribute: 'testId' }] | ||
}, | ||
{ | ||
code: `<form onSubmit={ this.handleSubmit } data-testid={ bar }>Foo</form>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }] | ||
} | ||
].map(parserOptionsMapper), | ||
@@ -42,4 +47,9 @@ | ||
{ code: '<Bar onSubmit={ () => handleSubmit() } disabled={ foo }>foo</Bar>', errors: [onSubmitError] }, | ||
{ code: '<Bar onSubmit={ () => handleSubmit() } readonly={ foo }>foo</Bar>', errors: [onSubmitError] } | ||
{ code: '<Bar onSubmit={ () => handleSubmit() } readonly={ foo }>foo</Bar>', errors: [onSubmitError] }, | ||
{ | ||
code: `<form onSubmit={ this.handleSubmit } data-test-id={ bar }>Foo</form>`, | ||
options: ['always', { testAttribute: ['testId', 'data-testid'] }], | ||
errors: [getError(onSubmit.message, ['testId', 'data-testid'])] | ||
} | ||
].map(parserOptionsMapper) | ||
}); |
const defaultParserOptions = { | ||
ecmaVersion: 6, | ||
ecmaFeatures: { | ||
jsx: true, | ||
} | ||
ecmaVersion: 6, | ||
ecmaFeatures: { | ||
jsx: true | ||
} | ||
}; | ||
module.exports = function({ | ||
code, | ||
errors, | ||
output, | ||
options = [], | ||
parserOptions = {}, | ||
}) { | ||
const defaultOptions = { | ||
code, | ||
errors, | ||
options, | ||
parserOptions: { | ||
...defaultParserOptions, | ||
...parserOptions, | ||
module.exports = function ({ code, errors, output, options = [], parserOptions = {} }) { | ||
const defaultOptions = { | ||
code, | ||
errors, | ||
options, | ||
parserOptions: { | ||
...defaultParserOptions, | ||
...parserOptions | ||
} | ||
}; | ||
if (output) { | ||
defaultOptions.output = output; | ||
} | ||
} | ||
if (output) { | ||
defaultOptions.output = output; | ||
} | ||
return defaultOptions; | ||
} | ||
return defaultOptions; | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
94762
36
940
170