Skip to content

Commit

Permalink
add lifecycle method typos
Browse files Browse the repository at this point in the history
  • Loading branch information
Haridu Senadeera committed Jul 24, 2017
1 parent 2d2cf65 commit 13fddef
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 3 deletions.
43 changes: 40 additions & 3 deletions docs/rules/no-typos.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
# Prevents common casing typos (react/no-typos)

Ensure no casing typos were made declaring static class properties
Ensure no casing typos were made declaring static class properties and lifecycle methods.

## Rule Details

This rule checks whether the declared static class properties related to React components
do not contain any typos. It currently makes sure that the following class properties have
This rule checks whether the declared static class properties and lifecycle methods related to React components
do not contain any typos.

It currently makes sure that the following class properties have
no casing typos:

* propTypes
* contextTypes
* childContextTypes
* defaultProps

and the following react lifecycle methods:

* componentWillMount
* componentDidMount
* componentWillReceiveProps
* shouldComponentUpdate
* componentWillUpdate
* componentDidUpdate
* componentWillUnmount


The following patterns are considered warnings:

```js
Expand Down Expand Up @@ -47,6 +60,18 @@ class MyComponent extends React.Component {
class MyComponent extends React.Component {
static defaultprops = {}
}

class MyComponent extends React.Component {
componentwillMount() {}
}

class MyComponent extends React.Component {
ComponentWillReceiveProps() {}
}

class MyComponent extends React.Component {
componentdidupdate() {}
}
```

The following patterns are not considered warnings:
Expand All @@ -67,4 +92,16 @@ class MyComponent extends React.Component {
class MyComponent extends React.Component {
static defaultProps = {}
}

class MyComponent extends React.Component {
componentWillMount() {}
}

class MyComponent extends React.Component {
componentWillReceiveProps() {}
}

class MyComponent extends React.Component {
componentDidUpdate() {}
}
```
28 changes: 28 additions & 0 deletions lib/rules/no-typos.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ const Components = require('../util/Components');
// ------------------------------------------------------------------------------

const STATIC_CLASS_PROPERTIES = ['propTypes', 'contextTypes', 'childContextTypes', 'defaultProps'];
const LIFECYCLE_METHODS = [
'componentWillMount',
'componentDidMount',
'componentWillReceiveProps',
'shouldComponentUpdate',
'componentWillUpdate',
'componentDidUpdate',
'componentWillUnmount'
];

module.exports = {
meta: {
Expand All @@ -33,6 +42,17 @@ module.exports = {
});
}

function reportErrorIfLifecycleMethodCasingTypo(node) {
LIFECYCLE_METHODS.forEach(function(method) {
if (method.toLowerCase() === node.key.name.toLowerCase() && method !== node.key.name) {
context.report({
node: node,
message: 'Typo in component lifecycle method declaration'
});
}
});
}

return {
ClassProperty: function(node) {
if (!node.static || !utils.isES6Component(node.parent.parent)) {
Expand All @@ -54,6 +74,14 @@ module.exports = {
const propertyName = node.property.name;
reportErrorIfCasingTypo(node, propertyName);
}
},

MethodDefinition: function (node) {
if (!utils.isES6Component(node.parent.parent) || utils.isReturningJSX(node.parent.parent)) {
return;
}

reportErrorIfLifecycleMethodCasingTypo(node);
}
};
})
Expand Down
87 changes: 87 additions & 0 deletions tests/lib/rules/no-typos.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const parserOptions = {
// -----------------------------------------------------------------------------

const ERROR_MESSAGE = 'Typo in static class property declaration';
const ERROR_MESSAGE_LIFECYCLE_METHOD = 'Typo in component lifecycle method declaration';

const ruleTester = new RuleTester();
ruleTester.run('no-typos', rule, {
Expand Down Expand Up @@ -181,6 +182,49 @@ ruleTester.run('no-typos', rule, {
'First[defautProps] = {};'
].join('\n'),
parserOptions: parserOptions
}, {
code: [
'class Hello extends React.Component {',
' componentDidUpdate() { }',
' render() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'}'
].join('\n'),
parserOptions: parserOptions
}, {
code: [
'class Hello extends React.Component {',
' componentWillMount() { }',
' componentDidUpdate() { }',
' render() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'}'
].join('\n'),
parserOptions: parserOptions
}, {
code: [
'class Hello extends React.Component {',
' componentWillUnmount() { }',
' componentWillMount() { }',
' render() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'}'
].join('\n'),
parserOptions: parserOptions
}, {
code: [
'class Hello extends React.Component {',
' shouldComponentUpdate() { }',
' componentWillReceiveProps() { }',
' render() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'}'
].join('\n'),
parserOptions: parserOptions
}],

invalid: [{
Expand Down Expand Up @@ -367,5 +411,48 @@ ruleTester.run('no-typos', rule, {
].join('\n'),
parserOptions: parserOptions,
errors: [{message: ERROR_MESSAGE}]
}, {
code: [
'class Hello extends React.Component {',
' ComponentDidUpdate() { }',
' render() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'}'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: ERROR_MESSAGE_LIFECYCLE_METHOD,
type: 'MethodDefinition'
}]
}, {
code: [
'class Hello extends React.Component {',
' componentwillreceiveprops() { }',
' render() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'}'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: ERROR_MESSAGE_LIFECYCLE_METHOD,
type: 'MethodDefinition'
}]
}, {
code: [
'class Hello extends React.Component {',
' componentWillReceiveProps() { }',
' componentWillupdate() { }',
' render() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'}'
].join('\n'),
parserOptions: parserOptions,
errors: [{
message: ERROR_MESSAGE_LIFECYCLE_METHOD,
type: 'MethodDefinition'
}]
}]
});

0 comments on commit 13fddef

Please sign in to comment.