diff --git a/.eslintrc b/.eslintrc index dd5aa22..e31d170 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,15 +1,5 @@ { - "extends": [ - "airbnb-base", - "plugin:flowtype/recommended", - "prettier" - ], + "extends": ["plugin:flowtype/recommended", "plugin:prettier/recommended"], "parser": "babel-eslint", - "plugins": [ - "flowtype" - ], - "rules": { - "max-len": "off", - "no-template-curly-in-string": "off" - } + "plugins": ["flowtype"] } diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..544138b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/__tests__/__util__/parserOptionsMapper.js b/__tests__/__util__/parserOptionsMapper.js index 0e9e990..19d99d5 100644 --- a/__tests__/__util__/parserOptionsMapper.js +++ b/__tests__/__util__/parserOptionsMapper.js @@ -1,15 +1,15 @@ const defaultParserOptions = { ecmaVersion: 6, ecmaFeatures: { - jsx: true, - }, + jsx: true + } }; export default function parserOptionsMapper({ code, errors, options = [], - parserOptions = {}, + parserOptions = {} }) { return { code, @@ -17,7 +17,7 @@ export default function parserOptionsMapper({ options, parserOptions: { ...defaultParserOptions, - ...parserOptions, - }, + ...parserOptions + } }; } diff --git a/__tests__/__util__/ruleOptionsMapperFactory.js b/__tests__/__util__/ruleOptionsMapperFactory.js index 5f50608..53de425 100644 --- a/__tests__/__util__/ruleOptionsMapperFactory.js +++ b/__tests__/__util__/ruleOptionsMapperFactory.js @@ -9,18 +9,25 @@ type ESLintTestRunnerTestCase = { parserOptions: ?Array }; -export default function ruleOptionsMapperFactory(ruleOptions: Array = []) { +export default function ruleOptionsMapperFactory( + ruleOptions: Array = [] +) { // eslint-disable-next-line return ({ code, errors, options, parserOptions }: ESLintTestRunnerTestCase): ESLintTestRunnerTestCase => { return { code, errors, // Flatten the array of objects in an array of one object. - options: (options || []).concat(ruleOptions).reduce((acc, item) => [{ - ...acc[0], - ...item, - }], [{}]), - parserOptions, + options: (options || []).concat(ruleOptions).reduce( + (acc, item) => [ + { + ...acc[0], + ...item + } + ], + [{}] + ), + parserOptions }; }; } diff --git a/__tests__/index-test.js b/__tests__/index-test.js index 94ed70f..7006f5b 100644 --- a/__tests__/index-test.js +++ b/__tests__/index-test.js @@ -6,11 +6,12 @@ import fs from 'fs'; import path from 'path'; import plugin from '../src'; -const rules = fs.readdirSync(path.resolve(__dirname, '../src/rules/')) +const rules = fs + .readdirSync(path.resolve(__dirname, '../src/rules/')) .map(f => path.basename(f, '.js')); describe('all rule files should be exported by the plugin', () => { - rules.forEach((ruleName) => { + rules.forEach(ruleName => { it(`should export ${ruleName}`, () => { assert.equal( plugin.rules[ruleName], @@ -21,13 +22,13 @@ describe('all rule files should be exported by the plugin', () => { }); describe('configurations', () => { - it('should export a \'recommended\' configuration', () => { + it("should export a 'recommended' configuration", () => { assert(plugin.configs.recommended); }); }); describe('schemas', () => { - rules.forEach((ruleName) => { + rules.forEach(ruleName => { it(`${ruleName} should export a schema with type object`, () => { const rule = require(path.join('../src/rules', ruleName)); // eslint-disable-line const schema = rule.meta && rule.meta.schema && rule.meta.schema[0]; diff --git a/__tests__/src/rules/accessibility-label-test.js b/__tests__/src/rules/accessibility-label-test.js index e333773..e4b3a36 100644 --- a/__tests__/src/rules/accessibility-label-test.js +++ b/__tests__/src/rules/accessibility-label-test.js @@ -21,20 +21,20 @@ const ruleTester = new RuleTester(); const expectedError = { message: 'If an element adopts the accessible={true} prop, it (or at least one of its children) must also set the accessibilityLabel prop', - type: 'JSXOpeningElement', + type: 'JSXOpeningElement' }; ruleTester.run('accessibility-label', rule, { valid: [ { - code: '', + code: '' }, { - code: '', + code: '' }, { code: - 'Button', + 'Button' }, { code: ` @@ -42,29 +42,29 @@ ruleTester.run('accessibility-label', rule, { Button - `, - }, + ` + } ].map(parserOptionsMapper), invalid: [ { code: '', - errors: [expectedError], + errors: [expectedError] }, { code: '', - errors: [expectedError], + errors: [expectedError] }, { code: '', - errors: [expectedError], + errors: [expectedError] }, { code: '', - errors: [expectedError], + errors: [expectedError] }, { code: '', - errors: [expectedError], + errors: [expectedError] }, { code: ` @@ -73,7 +73,7 @@ ruleTester.run('accessibility-label', rule, { Button `, - errors: [expectedError], - }, - ].map(parserOptionsMapper), + errors: [expectedError] + } + ].map(parserOptionsMapper) }); diff --git a/__tests__/src/rules/has-accessibility-props-test.js b/__tests__/src/rules/has-accessibility-props-test.js index 45c9787..fe79c50 100644 --- a/__tests__/src/rules/has-accessibility-props-test.js +++ b/__tests__/src/rules/has-accessibility-props-test.js @@ -20,7 +20,7 @@ const ruleTester = new RuleTester(); const expectedError = touchable => ({ message: `<${touchable}> must have the accessibilityRole prop, or both accessibilityComponentType and accessibilityTraits`, - type: 'JSXOpeningElement', + type: 'JSXOpeningElement' }); ruleTester.run('has-accessibility-props', rule, { @@ -30,86 +30,85 @@ ruleTester.run('has-accessibility-props', rule, { { code: ';' }, { code: - ';', + ';' }, { code: - ';', + ';' }, { code: - ';', + ';' }, { code: - ';', + ';' }, { code: - ';', + ';' }, { code: - '
;', + '
;' }, { - code: - '
;', - }, + code: '
;' + } ].map(parserOptionsMapper), invalid: [ { code: ';', errors: [expectedError('Touchable')] }, { code: ';', - errors: [expectedError('TouchableOpacity')], + errors: [expectedError('TouchableOpacity')] }, { code: ';', - errors: [expectedError('TouchableOpacity')], + errors: [expectedError('TouchableOpacity')] }, { code: ';', - errors: [expectedError('TouchableOpacity')], + errors: [expectedError('TouchableOpacity')] }, { code: ';', - errors: [expectedError('TouchableHighlight')], + errors: [expectedError('TouchableHighlight')] }, { code: ';', - errors: [expectedError('TouchableHighlight')], + errors: [expectedError('TouchableHighlight')] }, { code: ';', - errors: [expectedError('TouchableHighlight')], + errors: [expectedError('TouchableHighlight')] }, { code: ';', - errors: [expectedError('TouchableWithoutFeedback')], + errors: [expectedError('TouchableWithoutFeedback')] }, { code: ';', - errors: [expectedError('TouchableWithoutFeedback')], + errors: [expectedError('TouchableWithoutFeedback')] }, { code: ';', - errors: [expectedError('TouchableWithoutFeedback')], + errors: [expectedError('TouchableWithoutFeedback')] }, { code: ';', - errors: [expectedError('TouchableNativeFeedback')], + errors: [expectedError('TouchableNativeFeedback')] }, { code: ';', - errors: [expectedError('TouchableNativeFeedback')], + errors: [expectedError('TouchableNativeFeedback')] }, { code: ';', - errors: [expectedError('TouchableNativeFeedback')], + errors: [expectedError('TouchableNativeFeedback')] }, { code: '
;', - errors: [expectedError('TouchableOpacity')], - }, - ].map(parserOptionsMapper), + errors: [expectedError('TouchableOpacity')] + } + ].map(parserOptionsMapper) }); diff --git a/__tests__/src/rules/has-valid-accessibility-component-type-test.js b/__tests__/src/rules/has-valid-accessibility-component-type-test.js index 96948b1..353f649 100644 --- a/__tests__/src/rules/has-valid-accessibility-component-type-test.js +++ b/__tests__/src/rules/has-valid-accessibility-component-type-test.js @@ -20,7 +20,7 @@ const ruleTester = new RuleTester(); const expectedError = { message: 'accessibilityComponentType must be one of defined values', - type: 'JSXAttribute', + type: 'JSXAttribute' }; ruleTester.run('has-valid-accessibility-component-type', rule, { @@ -29,29 +29,29 @@ ruleTester.run('has-valid-accessibility-component-type', rule, { { code: ';' }, { code: - ';', + ';' }, { code: - ';', - }, + ';' + } ].map(parserOptionsMapper), invalid: [ { code: '', - errors: [expectedError], + errors: [expectedError] }, { code: ';', - errors: [expectedError], + errors: [expectedError] }, { code: ';', - errors: [expectedError], + errors: [expectedError] }, { code: '', - errors: [expectedError], - }, - ].map(parserOptionsMapper), + errors: [expectedError] + } + ].map(parserOptionsMapper) }); diff --git a/__tests__/src/rules/has-valid-accessibility-live-region-test.js b/__tests__/src/rules/has-valid-accessibility-live-region-test.js index f6285b2..2c1de8a 100644 --- a/__tests__/src/rules/has-valid-accessibility-live-region-test.js +++ b/__tests__/src/rules/has-valid-accessibility-live-region-test.js @@ -21,35 +21,35 @@ const ruleTester = new RuleTester(); const expectedError = { message: 'accessibilityLiveRegion must be one of defined values', - type: 'JSXAttribute', + type: 'JSXAttribute' }; ruleTester.run('has-valid-accessibility-live-region', rule, { valid: [ { code: 'Click Me' }, { code: 'Click Me' }, - { code: 'Click Me' }, + { code: 'Click Me' } ].map(parserOptionsMapper), invalid: [ { code: 'Click Me', - errors: [expectedError], + errors: [expectedError] }, { code: 'Click Me', - errors: [expectedError], + errors: [expectedError] }, { code: 'Click Me', - errors: [expectedError], + errors: [expectedError] }, { code: 'Click Me', - errors: [expectedError], + errors: [expectedError] }, { code: 'Click Me', - errors: [expectedError], - }, - ].map(parserOptionsMapper), + errors: [expectedError] + } + ].map(parserOptionsMapper) }); diff --git a/__tests__/src/rules/has-valid-accessibility-role-test.js b/__tests__/src/rules/has-valid-accessibility-role-test.js index 1a690cb..1670e4f 100644 --- a/__tests__/src/rules/has-valid-accessibility-role-test.js +++ b/__tests__/src/rules/has-valid-accessibility-role-test.js @@ -20,7 +20,7 @@ const ruleTester = new RuleTester(); const expectedError = { message: 'accessibilityRole must be one of defined values', - type: 'JSXAttribute', + type: 'JSXAttribute' }; ruleTester.run('has-valid-accessibility-role', rule, { @@ -35,24 +35,24 @@ ruleTester.run('has-valid-accessibility-role', rule, { { code: ';' }, { code: ';' }, { code: ';' }, - { code: ';' }, + { code: ';' } ].map(parserOptionsMapper), invalid: [ { code: '', - errors: [expectedError], + errors: [expectedError] }, { code: ';', - errors: [expectedError], + errors: [expectedError] }, { code: ';', - errors: [expectedError], + errors: [expectedError] }, { code: '', - errors: [expectedError], - }, - ].map(parserOptionsMapper), + errors: [expectedError] + } + ].map(parserOptionsMapper) }); diff --git a/__tests__/src/rules/has-valid-accessibility-states-test.js b/__tests__/src/rules/has-valid-accessibility-states-test.js index 5a07f72..a602019 100644 --- a/__tests__/src/rules/has-valid-accessibility-states-test.js +++ b/__tests__/src/rules/has-valid-accessibility-states-test.js @@ -19,31 +19,37 @@ import rule from '../../../src/rules/has-valid-accessibility-states'; const ruleTester = new RuleTester(); const expectedError = { - message: 'accessibilityStates must be one or both of the defined values', - type: 'JSXAttribute' + message: 'accessibilityStates must be one or both of the defined values', + type: 'JSXAttribute' }; ruleTester.run('has-valid-accessibility-states', rule, { - valid: [ - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' } - ].map(parserOptionsMapper), - invalid: [ - { - code: '', - errors: [expectedError] - }, - { - code: ';', - errors: [expectedError] - }, - { - code: '', - errors: [expectedError] - } - ].map(parserOptionsMapper) + valid: [ + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { + code: + ';' + }, + { + code: + ';' + } + ].map(parserOptionsMapper), + invalid: [ + { + code: '', + errors: [expectedError] + }, + { + code: ';', + errors: [expectedError] + }, + { + code: '', + errors: [expectedError] + } + ].map(parserOptionsMapper) }); diff --git a/__tests__/src/rules/has-valid-accessibility-traits-test.js b/__tests__/src/rules/has-valid-accessibility-traits-test.js index 0e485ec..021b9b6 100644 --- a/__tests__/src/rules/has-valid-accessibility-traits-test.js +++ b/__tests__/src/rules/has-valid-accessibility-traits-test.js @@ -19,49 +19,52 @@ import rule from '../../../src/rules/has-valid-accessibility-traits'; const ruleTester = new RuleTester(); const expectedError = { - message: 'accessibilityTraits must be one of defined values', - type: 'JSXAttribute' + message: 'accessibilityTraits must be one of defined values', + type: 'JSXAttribute' }; ruleTester.run('has-valid-accessibility-traits', rule, { - valid: [ - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { code: ';' }, - { - code: ';' - }, - { code: ';' }, - { code: ';' } - ].map(parserOptionsMapper), - invalid: [ - { - code: '', - errors: [expectedError] - }, - { - code: ';', - errors: [expectedError] - }, - { - code: ';', - errors: [expectedError] - }, - { - code: '', - errors: [expectedError] - } - ].map(parserOptionsMapper) + valid: [ + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { code: ';' }, + { + code: + ';' + }, + { code: ';' }, + { + code: ';' + } + ].map(parserOptionsMapper), + invalid: [ + { + code: '', + errors: [expectedError] + }, + { + code: ';', + errors: [expectedError] + }, + { + code: ';', + errors: [expectedError] + }, + { + code: '', + errors: [expectedError] + } + ].map(parserOptionsMapper) }); diff --git a/__tests__/src/rules/has-valid-important-for-accessibility-test.js b/__tests__/src/rules/has-valid-important-for-accessibility-test.js index f1d7aa6..dd75a77 100644 --- a/__tests__/src/rules/has-valid-important-for-accessibility-test.js +++ b/__tests__/src/rules/has-valid-important-for-accessibility-test.js @@ -20,7 +20,7 @@ const ruleTester = new RuleTester(); const expectedError = { message: 'importantForAccessibility must be one of defined values', - type: 'JSXAttribute', + type: 'JSXAttribute' }; ruleTester.run('has-valid-important-for-accessibility', rule, { @@ -28,20 +28,20 @@ ruleTester.run('has-valid-important-for-accessibility', rule, { { code: '' }, { code: '' }, { code: '' }, - { code: '' }, + { code: '' } ].map(parserOptionsMapper), invalid: [ { code: '', - errors: [expectedError], + errors: [expectedError] }, { code: '', - errors: [expectedError], + errors: [expectedError] }, { code: '', - errors: [expectedError], - }, - ].map(parserOptionsMapper), + errors: [expectedError] + } + ].map(parserOptionsMapper) }); diff --git a/__tests__/src/rules/no-nested-touchables-test.js b/__tests__/src/rules/no-nested-touchables-test.js index ad3631e..12d1c0b 100644 --- a/__tests__/src/rules/no-nested-touchables-test.js +++ b/__tests__/src/rules/no-nested-touchables-test.js @@ -21,7 +21,7 @@ const ruleTester = new RuleTester(); const expectedError = { message: 'Elements with accessible={true} must not have any clickable elements inside', - type: 'JSXOpeningElement', + type: 'JSXOpeningElement' }; ruleTester.run('no-nested-touchables', rule, { @@ -32,7 +32,7 @@ ruleTester.run('no-nested-touchables', rule, { accessibilityComponentType="button" accessibilityLabel="Tap Me!" accessible={true} - />`, + />` }, { code: `submitcancel`, - }, + >submitcancel` + } ].map(parserOptionsMapper), invalid: [ { @@ -53,7 +53,7 @@ ruleTester.run('no-nested-touchables', rule, { >
`, - errors: [expectedError], + errors: [expectedError] }, { code: `>Nested`, - errors: [expectedError], - }, - ].map(parserOptionsMapper), + errors: [expectedError] + } + ].map(parserOptionsMapper) }); diff --git a/package.json b/package.json index 9783a16..35e6a21 100644 --- a/package.json +++ b/package.json @@ -41,10 +41,8 @@ "babel-preset-es2015": "^6.24.1", "coveralls": "^3.0.2", "eslint": "^5.6.1", - "eslint-config-airbnb-base": "^13.1.0", "eslint-config-prettier": "^3.1.0", "eslint-plugin-flowtype": "^2.50.3", - "eslint-plugin-import": "^2.14.0", "eslint-plugin-prettier": "^3.0.0", "expect": "^23.6.0", "flow-bin": "^0.82.0", diff --git a/scripts/addRuleToIndex.js b/scripts/addRuleToIndex.js index 3a4f5a4..e427fe5 100644 --- a/scripts/addRuleToIndex.js +++ b/scripts/addRuleToIndex.js @@ -23,7 +23,7 @@ export default function transformer(file, api, options) { changesMade += s .find(j.Identifier, { - name: 'rules', + name: 'rules' }) .forEach((path, index) => { // Add rule path. @@ -33,9 +33,9 @@ export default function transformer(file, api, options) { 'init', j.literal(ruleName), j.callExpression(j.identifier('require'), [ - j.literal(rulePathInSrc), - ]), - ), + j.literal(rulePathInSrc) + ]) + ) ); path.parentPath.value.value.properties.sort(nameSort); } @@ -45,8 +45,8 @@ export default function transformer(file, api, options) { j.property( 'init', j.literal(`react-native-a11y/${ruleName}`), - j.literal('error'), - ), + j.literal('error') + ) ); path.parentPath.value.value.properties.sort(nameSort); } @@ -58,6 +58,6 @@ export default function transformer(file, api, options) { return s.toSource({ quote: 'single', - trailingComma: true, + trailingComma: true }); } diff --git a/scripts/create-rule.js b/scripts/create-rule.js index 30bc8bb..c92630a 100755 --- a/scripts/create-rule.js +++ b/scripts/create-rule.js @@ -19,7 +19,10 @@ const docsPath = path.resolve(`docs/rules/${ruleName}.md`); const jscodeshiftMain = jscodeshiftJSON.main; const jscodeshiftPath = require.resolve('jscodeshift'); -const jscodeshiftRoot = jscodeshiftPath.slice(0, jscodeshiftPath.indexOf(jscodeshiftMain)); +const jscodeshiftRoot = jscodeshiftPath.slice( + 0, + jscodeshiftPath.indexOf(jscodeshiftMain) +); // Validate if (!ruleName) { @@ -47,11 +50,11 @@ exec( '--extensions js', '--parser flow', `--ruleName=${ruleName}`, - `--rulePath=${rulePath}`, + `--rulePath=${rulePath}` ].join(' '), - (error) => { + error => { if (error) { console.error(`exec error: ${error}`); // eslint-disable-line no-console } - }, + } ); diff --git a/src/factory/valid-prop.js b/src/factory/valid-prop.js index e2d46a0..7d6661d 100644 --- a/src/factory/valid-prop.js +++ b/src/factory/valid-prop.js @@ -13,38 +13,46 @@ import isOneOf from '../util/isOneOf'; * @param {Array} validValues Array of possible valid values * @param {string} errorMessage Error message to present if prop is not a valid value */ -const createValidPropRule = (propName: string, validValues: Array, errorMessage: string, meta?: Object, create?: Object) => ({ - meta: { - docs: {}, - schema: [generateObjSchema()], - ...meta, - }, +const createValidPropRule = ( + propName: string, + validValues: Array, + errorMessage: string, + meta?: Object, + create?: Object +) => ({ + meta: { + docs: {}, + schema: [generateObjSchema()], + ...meta + }, - create: (context: ESLintContext) => ({ - JSXAttribute: (node: JSXAttribute) => { - const attrName = elementType(node); - if (attrName === propName) { - // ensure we are only checking literal prop values - const attrValue = getLiteralPropValue(node); - let invalid = false; + create: (context: ESLintContext) => ({ + JSXAttribute: (node: JSXAttribute) => { + const attrName = elementType(node); + if (attrName === propName) { + // ensure we are only checking literal prop values + const attrValue = getLiteralPropValue(node); + let invalid = false; - if (Array.isArray(attrValue)) { - const validate = attrValue.map(strValue => isOneOf(strValue, validValues)); - invalid = validate.indexOf(false) > -1; - } else { - invalid = !isOneOf(attrValue, validValues); - } + if (Array.isArray(attrValue)) { + const validate = attrValue.map(strValue => + isOneOf(strValue, validValues) + ); + invalid = validate.indexOf(false) > -1; + } else { + invalid = !isOneOf(attrValue, validValues); + } - if (invalid) { - context.report({ - node, - message: errorMessage - }); - } - } - }, - ...create - }) + if (invalid) { + context.report({ + node, + message: errorMessage + }); + } + } + }, + ...create + }) }); export default createValidPropRule; diff --git a/src/index.js b/src/index.js index bb51120..3f63a1d 100644 --- a/src/index.js +++ b/src/index.js @@ -11,14 +11,14 @@ module.exports = { 'has-valid-accessibility-states': require('./rules/has-valid-accessibility-states'), 'has-valid-accessibility-traits': require('./rules/has-valid-accessibility-traits'), 'has-valid-important-for-accessibility': require('./rules/has-valid-important-for-accessibility'), - 'no-nested-touchables': require('./rules/no-nested-touchables'), + 'no-nested-touchables': require('./rules/no-nested-touchables') }, configs: { recommended: { parserOptions: { ecmaFeatures: { - jsx: true, - }, + jsx: true + } }, rules: { 'react-native-a11y/accessibility-label': 'error', @@ -29,16 +29,16 @@ module.exports = { 'react-native-a11y/has-valid-accessibility-states': 'error', 'react-native-a11y/has-valid-accessibility-traits': 'error', 'react-native-a11y/has-valid-important-for-accessibility': 'error', - 'react-native-a11y/no-nested-touchables': 'error', - }, + 'react-native-a11y/no-nested-touchables': 'error' + } }, strict: { parserOptions: { ecmaFeatures: { - jsx: true, - }, + jsx: true + } }, - rules: {}, - }, - }, + rules: {} + } + } }; diff --git a/src/rules/accessibility-label.js b/src/rules/accessibility-label.js index 3ed18df..11e060e 100644 --- a/src/rules/accessibility-label.js +++ b/src/rules/accessibility-label.js @@ -16,49 +16,49 @@ import { generateObjSchema } from '../util/schemas'; import findChild from '../util/findChild'; const errorMessage = - 'If an element adopts the accessible={true} prop, it (or at least one of its children) must also set the accessibilityLabel prop'; + 'If an element adopts the accessible={true} prop, it (or at least one of its children) must also set the accessibilityLabel prop'; const schema = generateObjSchema(); function getAccessibilityLabel(node) { - const labelProp = getProp(node.attributes, 'accessibilityLabel'); - if (labelProp && labelProp.value) { - return getLiteralPropValue(labelProp); - } - return null; + const labelProp = getProp(node.attributes, 'accessibilityLabel'); + if (labelProp && labelProp.value) { + return getLiteralPropValue(labelProp); + } + return null; } module.exports = { - meta: { - docs: {}, - schema: [schema] - }, + meta: { + docs: {}, + schema: [schema] + }, - create: (context: ESLintContext) => ({ - JSXOpeningElement: (node: JSXOpeningElement) => { - const accessible = getProp(node.attributes, 'accessible'); - if (accessible) { - const labelPropVal = getAccessibilityLabel(node); - if (!labelPropVal) { - let childWithLabel; - if (node.parent) { - // $FlowFixMe - childWithLabel = findChild(node.parent, child => { - if (child.attributes) { - const childLabelValue = getAccessibilityLabel(child); - return !!childLabelValue; - } - return false; - }); - } - if (!childWithLabel) { - context.report({ - node, - message: errorMessage - }); - } - } - } - } - }) + create: (context: ESLintContext) => ({ + JSXOpeningElement: (node: JSXOpeningElement) => { + const accessible = getProp(node.attributes, 'accessible'); + if (accessible) { + const labelPropVal = getAccessibilityLabel(node); + if (!labelPropVal) { + let childWithLabel; + if (node.parent) { + // $FlowFixMe + childWithLabel = findChild(node.parent, child => { + if (child.attributes) { + const childLabelValue = getAccessibilityLabel(child); + return !!childLabelValue; + } + return false; + }); + } + if (!childWithLabel) { + context.report({ + node, + message: errorMessage + }); + } + } + } + } + }) }; diff --git a/src/rules/has-accessibility-props.js b/src/rules/has-accessibility-props.js index 6e5487e..8e74e58 100644 --- a/src/rules/has-accessibility-props.js +++ b/src/rules/has-accessibility-props.js @@ -28,24 +28,27 @@ module.exports = { additionalProperties: { type: 'array', items: { - type: 'string', + type: 'string' }, - uniqueItems: true, - }, - }, - ], + uniqueItems: true + } + } + ] }, create: (context: ESLintContext) => ({ JSXOpeningElement: (node: JSXOpeningElement) => { if (isTouchable(node, context)) { - if (!hasProp(node.attributes, 'accessibilityRole') && !hasEveryProp(node.attributes, deprecatedProps)) { + if ( + !hasProp(node.attributes, 'accessibilityRole') && + !hasEveryProp(node.attributes, deprecatedProps) + ) { context.report({ node, - message: errorMessage(elementType(node)), + message: errorMessage(elementType(node)) }); } } - }, - }), + } + }) }; diff --git a/src/rules/has-valid-accessibility-component-type.js b/src/rules/has-valid-accessibility-component-type.js index 0ec3dc2..e0857c7 100644 --- a/src/rules/has-valid-accessibility-component-type.js +++ b/src/rules/has-valid-accessibility-component-type.js @@ -16,11 +16,11 @@ const validValues = [ 'none', 'button', 'radiobutton_checked', - 'radiobutton_unchecked', + 'radiobutton_unchecked' ]; module.exports = createValidPropRule( 'accessibilityComponentType', validValues, - errorMessage, + errorMessage ); diff --git a/src/rules/has-valid-accessibility-live-region.js b/src/rules/has-valid-accessibility-live-region.js index c0d1725..058a815 100644 --- a/src/rules/has-valid-accessibility-live-region.js +++ b/src/rules/has-valid-accessibility-live-region.js @@ -18,5 +18,5 @@ const validValues = ['none', 'polite', 'assertive']; module.exports = createValidPropRule( 'accessibilityLiveRegion', validValues, - errorMessage, + errorMessage ); diff --git a/src/rules/has-valid-accessibility-role.js b/src/rules/has-valid-accessibility-role.js index ced8c85..755ecba 100644 --- a/src/rules/has-valid-accessibility-role.js +++ b/src/rules/has-valid-accessibility-role.js @@ -23,11 +23,11 @@ const validValues = [ 'none', 'search', 'summary', - 'text', + 'text' ]; module.exports = createValidPropRule( 'accessibilityRole', validValues, - errorMessage, + errorMessage ); diff --git a/src/rules/has-valid-accessibility-state.js b/src/rules/has-valid-accessibility-state.js index 1619bb0..b8f50f9 100644 --- a/src/rules/has-valid-accessibility-state.js +++ b/src/rules/has-valid-accessibility-state.js @@ -10,7 +10,8 @@ import createValidPropRule from '../factory/valid-prop'; // Rule Definition // ---------------------------------------------------------------------------- -const errorMessage = 'accessibilityStates must be one or both of the defined values'; +const errorMessage = + 'accessibilityStates must be one or both of the defined values'; const validValues = ['selected', 'disabled']; @@ -18,21 +19,22 @@ let deprecationHasBeenWarned = false; const rule = createValidPropRule( 'accessibilityStates', - validValues, errorMessage, + validValues, + errorMessage, { deprecated: true }, { Program: () => { - if (deprecationHasBeenWarned) return + if (deprecationHasBeenWarned) return; // eslint-disable-next-line no-console console.log( 'The react-native-a11y/has-valid-accessibility-state rule is deprecated. ' + - 'Please use the react-native-a11y/has-valid-accessibility-states rule instead.' - ) - deprecationHasBeenWarned = true + 'Please use the react-native-a11y/has-valid-accessibility-states rule instead.' + ); + deprecationHasBeenWarned = true; } } ); -module.exports = rule +module.exports = rule; diff --git a/src/rules/has-valid-accessibility-states.js b/src/rules/has-valid-accessibility-states.js index be1169b..7fe5628 100644 --- a/src/rules/has-valid-accessibility-states.js +++ b/src/rules/has-valid-accessibility-states.js @@ -10,8 +10,13 @@ import createValidPropRule from '../factory/valid-prop'; // Rule Definition // ---------------------------------------------------------------------------- -const errorMessage = 'accessibilityStates must be one or both of the defined values'; +const errorMessage = + 'accessibilityStates must be one or both of the defined values'; const validValues = ['selected', 'disabled']; -module.exports = createValidPropRule('accessibilityStates', validValues, errorMessage); +module.exports = createValidPropRule( + 'accessibilityStates', + validValues, + errorMessage +); diff --git a/src/rules/has-valid-accessibility-traits.js b/src/rules/has-valid-accessibility-traits.js index 919baf2..971cb71 100644 --- a/src/rules/has-valid-accessibility-traits.js +++ b/src/rules/has-valid-accessibility-traits.js @@ -29,11 +29,11 @@ const validValues = [ 'startsMedia', 'adjustable', 'allowsDirectInteraction', - 'pageTurn', + 'pageTurn' ]; module.exports = createValidPropRule( 'accessibilityTraits', validValues, - errorMessage, + errorMessage ); diff --git a/src/rules/has-valid-important-for-accessibility.js b/src/rules/has-valid-important-for-accessibility.js index d2167c9..735d4dd 100644 --- a/src/rules/has-valid-important-for-accessibility.js +++ b/src/rules/has-valid-important-for-accessibility.js @@ -17,5 +17,5 @@ const validValues = ['auto', 'yes', 'no', 'no-hide-descendants']; module.exports = createValidPropRule( 'importantForAccessibility', validValues, - errorMessage, + errorMessage ); diff --git a/src/rules/no-nested-touchables.js b/src/rules/no-nested-touchables.js index 075968d..a007d13 100644 --- a/src/rules/no-nested-touchables.js +++ b/src/rules/no-nested-touchables.js @@ -12,18 +12,19 @@ import { generateObjSchema } from '../util/schemas'; import isTouchable from '../util/isTouchable'; import findChild from '../util/findChild'; -const errorMessage = 'Elements with accessible={true} must not have any clickable elements inside'; +const errorMessage = + 'Elements with accessible={true} must not have any clickable elements inside'; const schema = generateObjSchema(); module.exports = { meta: { docs: {}, - schema: [schema], + schema: [schema] }, create: context => ({ - JSXOpeningElement: (node) => { + JSXOpeningElement: node => { const { parent } = node; const accessibleProp = getProp(node.attributes, 'accessible'); @@ -32,15 +33,16 @@ module.exports = { if (accessible) { const clickableChild = findChild( parent, - child => isTouchable(child, context) || elementType(child) === 'Button', + child => + isTouchable(child, context) || elementType(child) === 'Button' ); if (clickableChild) { context.report({ node, - message: errorMessage, + message: errorMessage }); } } - }, - }), + } + }) }; diff --git a/src/util/findChild.js b/src/util/findChild.js index c4c49c1..10c49af 100644 --- a/src/util/findChild.js +++ b/src/util/findChild.js @@ -8,7 +8,7 @@ import type { JSXOpeningElement, JSXElement } from 'ast-types-flow'; */ export default function findChild( node: JSXElement, - callback: (child: JSXOpeningElement) => boolean, + callback: (child: JSXOpeningElement) => boolean ): ?JSXOpeningElement { const { children } = node; if (children && children.length > 0) { diff --git a/src/util/isOneOf.js b/src/util/isOneOf.js index 1f0c1b3..a4554ca 100644 --- a/src/util/isOneOf.js +++ b/src/util/isOneOf.js @@ -7,5 +7,5 @@ // should be expanded to work with more than just strings // as and when it's needed export default function isOneOf(toCheck: string = '', values: string[] = []) { - return values.includes(toCheck); + return values.includes(toCheck); } diff --git a/src/util/isTouchable.js b/src/util/isTouchable.js index 9715ee9..31f6e6d 100644 --- a/src/util/isTouchable.js +++ b/src/util/isTouchable.js @@ -14,7 +14,7 @@ const defaultTouchables = { TouchableHighlight: true, TouchableWithoutFeedback: true, TouchableNativeFeedback: true, - TouchableBounce: true, + TouchableBounce: true }; export default function isTouchable( @@ -22,22 +22,20 @@ export default function isTouchable( context: ESLintContext = { id: '', options: [], - report: () => {}, - }, + report: () => {} + } ) { const { options } = context; let extraTouchables = []; if ( - options[0] - && Object.prototype.hasOwnProperty.call(options[0], 'touchables') + options[0] && + Object.prototype.hasOwnProperty.call(options[0], 'touchables') ) { const { touchables } = options[0]; - touchables.forEach((touchable) => { + touchables.forEach(touchable => { if (!touchable.startsWith('Touchable')) { throw Error( - `Custom touchable specified in ${ - context.id - } does not start with 'Touchable'`, + `Custom touchable specified in ${context.id} does not start with 'Touchable'` ); } }); diff --git a/src/util/schemas.js b/src/util/schemas.js index 2d6c34a..11277ac 100644 --- a/src/util/schemas.js +++ b/src/util/schemas.js @@ -4,22 +4,23 @@ export const arraySchema = { type: 'array', items: { - type: 'string', + type: 'string' }, uniqueItems: true, - additionalItems: false, + additionalItems: false }; /** * JSON schema to accept an array of unique strings from an enumerated list. */ -export const enumArraySchema = (enumeratedList = [], minItems = 0) => Object.assign({}, arraySchema, { - items: { - type: 'string', - enum: enumeratedList, - }, - minItems, -}); +export const enumArraySchema = (enumeratedList = [], minItems = 0) => + Object.assign({}, arraySchema, { + items: { + type: 'string', + enum: enumeratedList + }, + minItems + }); /** * Factory function to generate an object schema @@ -28,5 +29,5 @@ export const enumArraySchema = (enumeratedList = [], minItems = 0) => Object.ass export const generateObjSchema = (properties = {}, required) => ({ type: 'object', properties, - required, + required });