Merge pull request #479 from justjake/jake/some-small-issues

Modularize eslintrc, add tests
This commit is contained in:
Jake Teton-Landis
2015-08-19 14:10:12 -07:00
9 changed files with 356 additions and 221 deletions

View File

@@ -0,0 +1,11 @@
{
"extends": "airbnb",
"rules": {
// disable requiring trailing commas because it might be nice to revert to
// being JSON at some point, and I don't want to make big changes now.
"comma-dangle": 0,
// disabled because I find it tedious to write tests while following this
// rule
"no-shadow": 0
}
}

View File

@@ -4,9 +4,26 @@ This package provides Airbnb's .eslintrc as an extensible shared config.
## Usage
### With React Style
1. `npm install --save-dev eslint-config-airbnb babel-eslint eslint-plugin-react`
2. add `"extends": "eslint-config-airbnb"` to your .eslintrc
2. add `"extends": "airbnb"` to your .eslintrc
### Without React Style
1. `npm install --save-dev eslint-config-airbnb babel-eslint `
2. add `"extends": "airbnb/base"` to your .eslintrc
See [Airbnb's Javascript styleguide](https://github.com/airbnb/javascript) and
the [ESlint config docs](http://eslint.org/docs/user-guide/configuring#extending-configuration-files)
for more information.
## Improving this config
Consider adding test cases if you're making complicated rules changes, like
anything involving regexes. Perhaps in a distant future, we could use literate
programming to structure our README as test cases for our .eslintrc?
You can run tests with `npm test`.
You can make sure this module lints with itself using `npm run lint`.

View File

@@ -0,0 +1,173 @@
module.exports = {
'parser': 'babel-eslint', // https://github.com/babel/babel-eslint
'env': { // http://eslint.org/docs/user-guide/configuring.html#specifying-environments
'browser': true, // browser global variables
'node': true // Node.js global variables and Node.js-specific rules
},
'ecmaFeatures': {
'arrowFunctions': true,
'blockBindings': true,
'classes': true,
'defaultParams': true,
'destructuring': true,
'forOf': true,
'generators': false,
'modules': true,
'objectLiteralComputedProperties': true,
'objectLiteralDuplicateProperties': false,
'objectLiteralShorthandMethods': true,
'objectLiteralShorthandProperties': true,
'spread': true,
'superInFunctions': true,
'templateStrings': true,
'jsx': true
},
'rules': {
/**
* Strict mode
*/
// babel inserts 'use strict'; for us
'strict': [2, 'never'], // http://eslint.org/docs/rules/strict
/**
* ES6
*/
'no-var': 2, // http://eslint.org/docs/rules/no-var
'prefer-const': 2, // http://eslint.org/docs/rules/prefer-const
/**
* Variables
*/
'no-shadow': 2, // http://eslint.org/docs/rules/no-shadow
'no-shadow-restricted-names': 2, // http://eslint.org/docs/rules/no-shadow-restricted-names
'no-unused-vars': [2, { // http://eslint.org/docs/rules/no-unused-vars
'vars': 'local',
'args': 'after-used'
}],
'no-use-before-define': 2, // http://eslint.org/docs/rules/no-use-before-define
/**
* Possible errors
*/
'comma-dangle': [2, 'always-multiline'], // http://eslint.org/docs/rules/comma-dangle
'no-cond-assign': [2, 'always'], // http://eslint.org/docs/rules/no-cond-assign
'no-console': 1, // http://eslint.org/docs/rules/no-console
'no-debugger': 1, // http://eslint.org/docs/rules/no-debugger
'no-alert': 1, // http://eslint.org/docs/rules/no-alert
'no-constant-condition': 1, // http://eslint.org/docs/rules/no-constant-condition
'no-dupe-keys': 2, // http://eslint.org/docs/rules/no-dupe-keys
'no-duplicate-case': 2, // http://eslint.org/docs/rules/no-duplicate-case
'no-empty': 2, // http://eslint.org/docs/rules/no-empty
'no-ex-assign': 2, // http://eslint.org/docs/rules/no-ex-assign
'no-extra-boolean-cast': 0, // http://eslint.org/docs/rules/no-extra-boolean-cast
'no-extra-semi': 2, // http://eslint.org/docs/rules/no-extra-semi
'no-func-assign': 2, // http://eslint.org/docs/rules/no-func-assign
'no-inner-declarations': 2, // http://eslint.org/docs/rules/no-inner-declarations
'no-invalid-regexp': 2, // http://eslint.org/docs/rules/no-invalid-regexp
'no-irregular-whitespace': 2, // http://eslint.org/docs/rules/no-irregular-whitespace
'no-obj-calls': 2, // http://eslint.org/docs/rules/no-obj-calls
'no-sparse-arrays': 2, // http://eslint.org/docs/rules/no-sparse-arrays
'no-unreachable': 2, // http://eslint.org/docs/rules/no-unreachable
'use-isnan': 2, // http://eslint.org/docs/rules/use-isnan
'block-scoped-var': 2, // http://eslint.org/docs/rules/block-scoped-var
/**
* Best practices
*/
'consistent-return': 2, // http://eslint.org/docs/rules/consistent-return
'curly': [2, 'multi-line'], // http://eslint.org/docs/rules/curly
'default-case': 2, // http://eslint.org/docs/rules/default-case
'dot-notation': [2, { // http://eslint.org/docs/rules/dot-notation
'allowKeywords': true
}],
'eqeqeq': 2, // http://eslint.org/docs/rules/eqeqeq
'guard-for-in': 2, // http://eslint.org/docs/rules/guard-for-in
'no-caller': 2, // http://eslint.org/docs/rules/no-caller
'no-else-return': 2, // http://eslint.org/docs/rules/no-else-return
'no-eq-null': 2, // http://eslint.org/docs/rules/no-eq-null
'no-eval': 2, // http://eslint.org/docs/rules/no-eval
'no-extend-native': 2, // http://eslint.org/docs/rules/no-extend-native
'no-extra-bind': 2, // http://eslint.org/docs/rules/no-extra-bind
'no-fallthrough': 2, // http://eslint.org/docs/rules/no-fallthrough
'no-floating-decimal': 2, // http://eslint.org/docs/rules/no-floating-decimal
'no-implied-eval': 2, // http://eslint.org/docs/rules/no-implied-eval
'no-lone-blocks': 2, // http://eslint.org/docs/rules/no-lone-blocks
'no-loop-func': 2, // http://eslint.org/docs/rules/no-loop-func
'no-multi-str': 2, // http://eslint.org/docs/rules/no-multi-str
'no-native-reassign': 2, // http://eslint.org/docs/rules/no-native-reassign
'no-new': 2, // http://eslint.org/docs/rules/no-new
'no-new-func': 2, // http://eslint.org/docs/rules/no-new-func
'no-new-wrappers': 2, // http://eslint.org/docs/rules/no-new-wrappers
'no-octal': 2, // http://eslint.org/docs/rules/no-octal
'no-octal-escape': 2, // http://eslint.org/docs/rules/no-octal-escape
'no-param-reassign': 2, // http://eslint.org/docs/rules/no-param-reassign
'no-proto': 2, // http://eslint.org/docs/rules/no-proto
'no-redeclare': 2, // http://eslint.org/docs/rules/no-redeclare
'no-return-assign': 2, // http://eslint.org/docs/rules/no-return-assign
'no-script-url': 2, // http://eslint.org/docs/rules/no-script-url
'no-self-compare': 2, // http://eslint.org/docs/rules/no-self-compare
'no-sequences': 2, // http://eslint.org/docs/rules/no-sequences
'no-throw-literal': 2, // http://eslint.org/docs/rules/no-throw-literal
'no-with': 2, // http://eslint.org/docs/rules/no-with
'radix': 2, // http://eslint.org/docs/rules/radix
'vars-on-top': 2, // http://eslint.org/docs/rules/vars-on-top
'wrap-iife': [2, 'any'], // http://eslint.org/docs/rules/wrap-iife
'yoda': 2, // http://eslint.org/docs/rules/yoda
/**
* Style
*/
'indent': [2, 2], // http://eslint.org/docs/rules/indent
'brace-style': [
2, // http://eslint.org/docs/rules/brace-style
'1tbs', {
'allowSingleLine': true
}
],
'quotes': [
2, 'single', 'avoid-escape' // http://eslint.org/docs/rules/quotes
],
'camelcase': [2, { // http://eslint.org/docs/rules/camelcase
'properties': 'never'
}],
'comma-spacing': [2, { // http://eslint.org/docs/rules/comma-spacing
'before': false,
'after': true
}],
'comma-style': [2, 'last'], // http://eslint.org/docs/rules/comma-style
'eol-last': 2, // http://eslint.org/docs/rules/eol-last
'func-names': 1, // http://eslint.org/docs/rules/func-names
'key-spacing': [2, { // http://eslint.org/docs/rules/key-spacing
'beforeColon': false,
'afterColon': true
}],
'new-cap': [2, { // http://eslint.org/docs/rules/new-cap
'newIsCap': true
}],
'no-multiple-empty-lines': [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines
'max': 2
}],
'no-nested-ternary': 2, // http://eslint.org/docs/rules/no-nested-ternary
'no-new-object': 2, // http://eslint.org/docs/rules/no-new-object
'no-spaced-func': 2, // http://eslint.org/docs/rules/no-spaced-func
'no-trailing-spaces': 2, // http://eslint.org/docs/rules/no-trailing-spaces
'no-extra-parens': [2, 'functions'], // http://eslint.org/docs/rules/no-extra-parens
'no-underscore-dangle': 0, // http://eslint.org/docs/rules/no-underscore-dangle
'one-var': [2, 'never'], // http://eslint.org/docs/rules/one-var
'padded-blocks': [2, 'never'], // http://eslint.org/docs/rules/padded-blocks
'semi': [2, 'always'], // http://eslint.org/docs/rules/semi
'semi-spacing': [2, { // http://eslint.org/docs/rules/semi-spacing
'before': false,
'after': true
}],
'space-after-keywords': 2, // http://eslint.org/docs/rules/space-after-keywords
'space-before-blocks': 2, // http://eslint.org/docs/rules/space-before-blocks
'space-before-function-paren': [2, 'never'], // http://eslint.org/docs/rules/space-before-function-paren
'space-infix-ops': 2, // http://eslint.org/docs/rules/space-infix-ops
'space-return-throw-case': 2, // http://eslint.org/docs/rules/space-return-throw-case
'spaced-comment': [2, 'always', {// http://eslint.org/docs/rules/spaced-comment
'exceptions': ['-', '+'],
'markers': ['=', '!'] // space here to support sprockets directives
}],
}
};

View File

@@ -1,221 +1,13 @@
module.exports = {
'parser': 'babel-eslint', // https://github.com/babel/babel-eslint
'plugins': [
'react' // https://github.com/yannickcr/eslint-plugin-react
],
'env': { // http://eslint.org/docs/user-guide/configuring.html#specifying-environments
'browser': true, // browser global variables
'node': true // Node.js global variables and Node.js-specific rules
},
'ecmaFeatures': {
'arrowFunctions': true,
'blockBindings': true,
'classes': true,
'defaultParams': true,
'destructuring': true,
'forOf': true,
'generators': false,
'modules': true,
'objectLiteralComputedProperties': true,
'objectLiteralDuplicateProperties': false,
'objectLiteralShorthandMethods': true,
'objectLiteralShorthandProperties': true,
'spread': true,
'superInFunctions': true,
'templateStrings': true,
'jsx': true
},
'rules': {
/**
* Strict mode
*/
// babel inserts 'use strict'; for us
'strict': [2, 'never'], // http://eslint.org/docs/rules/strict
const reactRules = require('./react');
const base = require('./base');
/**
* ES6
*/
'no-var': 2, // http://eslint.org/docs/rules/no-var
'prefer-const': 2, // http://eslint.org/docs/rules/prefer-const
// clone this so we aren't mutating a module
const eslintrc = JSON.parse(JSON.stringify(base));
/**
* Variables
*/
'no-shadow': 2, // http://eslint.org/docs/rules/no-shadow
'no-shadow-restricted-names': 2, // http://eslint.org/docs/rules/no-shadow-restricted-names
'no-unused-vars': [2, { // http://eslint.org/docs/rules/no-unused-vars
'vars': 'local',
'args': 'after-used'
}],
'no-use-before-define': 2, // http://eslint.org/docs/rules/no-use-before-define
// manually merge in React rules
eslintrc.plugins = reactRules.plugins;
Object.keys(reactRules.rules).forEach(function assignRule(ruleId) {
eslintrc.rules[ruleId] = reactRules.rules[ruleId];
});
/**
* Possible errors
*/
'comma-dangle': [2, 'always-multiline'], // http://eslint.org/docs/rules/comma-dangle
'no-cond-assign': [2, 'always'], // http://eslint.org/docs/rules/no-cond-assign
'no-console': 1, // http://eslint.org/docs/rules/no-console
'no-debugger': 1, // http://eslint.org/docs/rules/no-debugger
'no-alert': 1, // http://eslint.org/docs/rules/no-alert
'no-constant-condition': 1, // http://eslint.org/docs/rules/no-constant-condition
'no-dupe-keys': 2, // http://eslint.org/docs/rules/no-dupe-keys
'no-duplicate-case': 2, // http://eslint.org/docs/rules/no-duplicate-case
'no-empty': 2, // http://eslint.org/docs/rules/no-empty
'no-ex-assign': 2, // http://eslint.org/docs/rules/no-ex-assign
'no-extra-boolean-cast': 0, // http://eslint.org/docs/rules/no-extra-boolean-cast
'no-extra-semi': 2, // http://eslint.org/docs/rules/no-extra-semi
'no-func-assign': 2, // http://eslint.org/docs/rules/no-func-assign
'no-inner-declarations': 2, // http://eslint.org/docs/rules/no-inner-declarations
'no-invalid-regexp': 2, // http://eslint.org/docs/rules/no-invalid-regexp
'no-irregular-whitespace': 2, // http://eslint.org/docs/rules/no-irregular-whitespace
'no-obj-calls': 2, // http://eslint.org/docs/rules/no-obj-calls
'no-sparse-arrays': 2, // http://eslint.org/docs/rules/no-sparse-arrays
'no-unreachable': 2, // http://eslint.org/docs/rules/no-unreachable
'use-isnan': 2, // http://eslint.org/docs/rules/use-isnan
'block-scoped-var': 2, // http://eslint.org/docs/rules/block-scoped-var
/**
* Best practices
*/
'consistent-return': 2, // http://eslint.org/docs/rules/consistent-return
'curly': [2, 'multi-line'], // http://eslint.org/docs/rules/curly
'default-case': 2, // http://eslint.org/docs/rules/default-case
'dot-notation': [2, { // http://eslint.org/docs/rules/dot-notation
'allowKeywords': true
}],
'eqeqeq': 2, // http://eslint.org/docs/rules/eqeqeq
'guard-for-in': 2, // http://eslint.org/docs/rules/guard-for-in
'no-caller': 2, // http://eslint.org/docs/rules/no-caller
'no-else-return': 2, // http://eslint.org/docs/rules/no-else-return
'no-eq-null': 2, // http://eslint.org/docs/rules/no-eq-null
'no-eval': 2, // http://eslint.org/docs/rules/no-eval
'no-extend-native': 2, // http://eslint.org/docs/rules/no-extend-native
'no-extra-bind': 2, // http://eslint.org/docs/rules/no-extra-bind
'no-fallthrough': 2, // http://eslint.org/docs/rules/no-fallthrough
'no-floating-decimal': 2, // http://eslint.org/docs/rules/no-floating-decimal
'no-implied-eval': 2, // http://eslint.org/docs/rules/no-implied-eval
'no-lone-blocks': 2, // http://eslint.org/docs/rules/no-lone-blocks
'no-loop-func': 2, // http://eslint.org/docs/rules/no-loop-func
'no-multi-str': 2, // http://eslint.org/docs/rules/no-multi-str
'no-native-reassign': 2, // http://eslint.org/docs/rules/no-native-reassign
'no-new': 2, // http://eslint.org/docs/rules/no-new
'no-new-func': 2, // http://eslint.org/docs/rules/no-new-func
'no-new-wrappers': 2, // http://eslint.org/docs/rules/no-new-wrappers
'no-octal': 2, // http://eslint.org/docs/rules/no-octal
'no-octal-escape': 2, // http://eslint.org/docs/rules/no-octal-escape
'no-param-reassign': 2, // http://eslint.org/docs/rules/no-param-reassign
'no-proto': 2, // http://eslint.org/docs/rules/no-proto
'no-redeclare': 2, // http://eslint.org/docs/rules/no-redeclare
'no-return-assign': 2, // http://eslint.org/docs/rules/no-return-assign
'no-script-url': 2, // http://eslint.org/docs/rules/no-script-url
'no-self-compare': 2, // http://eslint.org/docs/rules/no-self-compare
'no-sequences': 2, // http://eslint.org/docs/rules/no-sequences
'no-throw-literal': 2, // http://eslint.org/docs/rules/no-throw-literal
'no-with': 2, // http://eslint.org/docs/rules/no-with
'radix': 2, // http://eslint.org/docs/rules/radix
'vars-on-top': 2, // http://eslint.org/docs/rules/vars-on-top
'wrap-iife': [2, 'any'], // http://eslint.org/docs/rules/wrap-iife
'yoda': 2, // http://eslint.org/docs/rules/yoda
/**
* Style
*/
'indent': [2, 2], // http://eslint.org/docs/rules/indent
'brace-style': [2, // http://eslint.org/docs/rules/brace-style
'1tbs', {
'allowSingleLine': true
}],
'quotes': [
2, 'single', 'avoid-escape' // http://eslint.org/docs/rules/quotes
],
'camelcase': [2, { // http://eslint.org/docs/rules/camelcase
'properties': 'never'
}],
'comma-spacing': [2, { // http://eslint.org/docs/rules/comma-spacing
'before': false,
'after': true
}],
'comma-style': [2, 'last'], // http://eslint.org/docs/rules/comma-style
'eol-last': 2, // http://eslint.org/docs/rules/eol-last
'func-names': 1, // http://eslint.org/docs/rules/func-names
'key-spacing': [2, { // http://eslint.org/docs/rules/key-spacing
'beforeColon': false,
'afterColon': true
}],
'new-cap': [2, { // http://eslint.org/docs/rules/new-cap
'newIsCap': true
}],
'no-multiple-empty-lines': [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines
'max': 2
}],
'no-nested-ternary': 2, // http://eslint.org/docs/rules/no-nested-ternary
'no-new-object': 2, // http://eslint.org/docs/rules/no-new-object
'no-spaced-func': 2, // http://eslint.org/docs/rules/no-spaced-func
'no-trailing-spaces': 2, // http://eslint.org/docs/rules/no-trailing-spaces
'no-extra-parens': [2, 'functions'], // http://eslint.org/docs/rules/no-extra-parens
'no-underscore-dangle': 0, // http://eslint.org/docs/rules/no-underscore-dangle
'one-var': [2, 'never'], // http://eslint.org/docs/rules/one-var
'padded-blocks': [2, 'never'], // http://eslint.org/docs/rules/padded-blocks
'semi': [2, 'always'], // http://eslint.org/docs/rules/semi
'semi-spacing': [2, { // http://eslint.org/docs/rules/semi-spacing
'before': false,
'after': true
}],
'space-after-keywords': 2, // http://eslint.org/docs/rules/space-after-keywords
'space-before-blocks': 2, // http://eslint.org/docs/rules/space-before-blocks
'space-before-function-paren': [2, 'never'], // http://eslint.org/docs/rules/space-before-function-paren
'space-infix-ops': 2, // http://eslint.org/docs/rules/space-infix-ops
'space-return-throw-case': 2, // http://eslint.org/docs/rules/space-return-throw-case
'spaced-comment': [2, 'always', {// http://eslint.org/docs/rules/spaced-comment
'exceptions': ['-', '+'],
'markers': ['=', '!'] // space here to support sprockets directives
}],
/**
* JSX style
*/
'react/display-name': 0, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md
'react/jsx-boolean-value': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md
'react/jsx-quotes': [2, 'double'], // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-quotes.md
'react/jsx-no-undef': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md
'react/jsx-sort-props': 0, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md
'react/jsx-sort-prop-types': 0, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-prop-types.md
'react/jsx-uses-react': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md
'react/jsx-uses-vars': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md
'react/no-did-mount-set-state': [2, 'allow-in-func'], // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md
'react/no-did-update-set-state': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md
'react/no-multi-comp': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md
'react/no-unknown-property': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md
'react/prop-types': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prop-types.md
'react/react-in-jsx-scope': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md
'react/self-closing-comp': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md
'react/wrap-multilines': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/wrap-multilines.md
'react/sort-comp': [2, { // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md
'order': [
'displayName',
'propTypes',
'contextTypes',
'childContextTypes',
'mixins',
'statics',
'defaultProps',
'constructor',
'getDefaultProps',
'getInitialState',
'getChildContext',
'componentWillMount',
'componentDidMount',
'componentWillReceiveProps',
'shouldComponentUpdate',
'componentWillUpdate',
'componentDidUpdate',
'componentWillUnmount',
'/^on.+$/',
'everything-else',
'/^get.+$/',
'/^render.+$/',
'render'
]
}]
}
};
module.exports = eslintrc;

View File

@@ -0,0 +1 @@
..

View File

@@ -4,7 +4,8 @@
"description": "Airbnb's ESLint config, following our styleguide",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"lint": "./node_modules/.bin/eslint .",
"test": "./node_modules/.bin/babel-tape-runner ./test/test-*.js"
},
"repository": {
"type": "git",
@@ -23,5 +24,13 @@
"bugs": {
"url": "https://github.com/airbnb/javascript/issues"
},
"homepage": "https://github.com/airbnb/javascript"
"homepage": "https://github.com/airbnb/javascript",
"devDependencies": {
"babel-eslint": "4.0.10",
"babel-tape-runner": "1.2.0",
"eslint": "1.1.0",
"eslint-plugin-react": "3.2.3",
"react": "0.13.3",
"tape": "4.2.0"
}
}

36
packages/eslint-config-airbnb/react.js vendored Normal file
View File

@@ -0,0 +1,36 @@
module.exports = {
'plugins': [
'react' // https://github.com/yannickcr/eslint-plugin-react
],
rules: {
/**
* JSX style
*/
'react/display-name': 0, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md
'react/jsx-boolean-value': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md
'react/jsx-quotes': [2, 'double'], // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-quotes.md
'react/jsx-no-undef': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md
'react/jsx-sort-props': 0, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md
'react/jsx-sort-prop-types': 0, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-prop-types.md
'react/jsx-uses-react': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md
'react/jsx-uses-vars': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md
'react/no-did-mount-set-state': [2, 'allow-in-func'], // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md
'react/no-did-update-set-state': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md
'react/no-multi-comp': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md
'react/no-unknown-property': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md
'react/prop-types': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prop-types.md
'react/react-in-jsx-scope': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md
'react/self-closing-comp': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md
'react/wrap-multilines': 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/wrap-multilines.md
'react/sort-comp': [2, { // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md
'order': [
'lifecycle',
'/^on.+$/',
'/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/',
'everything-else',
'/^render.+$/',
'render'
]
}]
}
};

View File

@@ -0,0 +1,13 @@
import test from 'tape';
import base from '../base';
test('base: does not reference react', t => {
t.plan(2);
t.notOk(base.plugins, 'plugins is unspecified');
// scan rules for react/ and fail if any exist
const reactRuleIds = Object.keys(base.rules)
.filter(ruleId => ruleId.indexOf('react/') === 0);
t.deepEquals(reactRuleIds, [], 'there are no react/ rules');
});

View File

@@ -0,0 +1,83 @@
import test from 'tape';
import { CLIEngine } from 'eslint';
import eslintrc from '../';
const cli = new CLIEngine({
useEslintrc: false,
baseConfig: eslintrc,
});
function lint(text) {
// @see http://eslint.org/docs/developer-guide/nodejs-api.html#executeonfiles
// @see http://eslint.org/docs/developer-guide/nodejs-api.html#executeontext
return cli.executeOnText(text).results[0];
}
function wrapComponent(body) {
return `
import React from 'react';
export default class MyComponent extends React.Component {
${body}
}
`;
}
test('validate react prop order', t => {
t.test('make sure our eslintrc has React linting dependencies', t => {
t.plan(2);
t.equal(eslintrc.parser, 'babel-eslint', 'uses babel-eslint');
t.equal(eslintrc.plugins[0], 'react', 'uses eslint-plugin-react');
});
t.test('passes a good component', t => {
t.plan(3);
const result = lint(wrapComponent(`
componentWillMount() { }
componentDidMount() { }
setFoo() { }
getFoo() { }
setBar() { }
someMethod() { }
renderDogs() { }
render() { return <div />; }
`));
t.notOk(result.warningCount, 'no warnings');
t.notOk(result.errorCount, 'no errors');
t.deepEquals(result.messages, [], 'no messages in results');
});
t.test('order: when random method is first', t => {
t.plan(2);
const result = lint(wrapComponent(`
someMethod() { }
componentWillMount() { }
componentDidMount() { }
setFoo() { }
getFoo() { }
setBar() { }
renderDogs() { }
render() { return <div />; }
`));
t.ok(result.errorCount, 'fails');
t.equal(result.messages[0].ruleId, 'react/sort-comp', 'fails due to sort');
});
t.test('order: when random method after lifecycle methods', t => {
t.plan(2);
const result = lint(wrapComponent(`
componentWillMount() { }
componentDidMount() { }
someMethod() { }
setFoo() { }
getFoo() { }
setBar() { }
renderDogs() { }
render() { return <div />; }
`));
t.ok(result.errorCount, 'fails');
t.equal(result.messages[0].ruleId, 'react/sort-comp', 'fails due to sort');
});
});