Skip to content

Commit f7a9dcc

Browse files
Tom910yannickcr
authored andcommitted
Add allowDecorators option to require-optimization
1 parent 1614cc6 commit f7a9dcc

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed

docs/rules/require-optimization.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,30 @@ React.createClass({
5252

5353
```js
5454
...
55-
"require-optimization": [<enabled>]
55+
"require-optimization": [<enabled>, { allowDecorators: [<allowDecorator>] }]
5656
...
5757
```
5858

59+
* `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.
60+
* `allowDecorators`: optional array of decorators names to allow validation.
61+
62+
63+
### `allowDecorators`
64+
65+
Sets the allowed names of decorators. If the variable is present in the chain of decorators, it validates
66+
67+
The following patterns are not warnings:
68+
69+
```js
70+
// ['pureRender']
71+
@pureRender
72+
class Hello extends React.Component {}
73+
```
74+
5975
### Example
6076

6177
```js
6278
...
63-
"require-optimization": 2
79+
"require-optimization": [2, {allowDecorators: ['customDecorators']}]
6480
...
6581
```

lib/rules/require-optimization.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ var Components = require('../util/Components');
88

99
module.exports = Components.detect(function (context, components) {
1010
var MISSING_MESSAGE = 'Component is not optimized. Please add a shouldComponentUpdate method.';
11+
var configuration = context.options[0] || {};
12+
var allowDecorators = configuration.allowDecorators || [];
1113

1214
/**
1315
* Checks to see if our component is decorated by PureRenderMixin via reactMixin
@@ -36,6 +38,30 @@ module.exports = Components.detect(function (context, components) {
3638
return false;
3739
};
3840

41+
/**
42+
* Checks to see if our component is custom decorated
43+
* @param {ASTNode} node The AST node being checked.
44+
* @returns {Boolean} True if node is decorated name with a custom decorated, false if not.
45+
*/
46+
var hasCustomDecorator = function (node) {
47+
var allowLenght = allowDecorators.length;
48+
49+
if (allowLenght && node.decorators && node.decorators.length) {
50+
for (var i = 0; i < allowLenght; i++) {
51+
for (var j = 0, l = node.decorators.length; j < l; j++) {
52+
if (
53+
node.decorators[j].expression &&
54+
node.decorators[j].expression.name === allowDecorators[i]
55+
) {
56+
return true;
57+
}
58+
}
59+
}
60+
}
61+
62+
return false;
63+
};
64+
3965
/**
4066
* Checks if we are declaring a shouldComponentUpdate method
4167
* @param {ASTNode} node The AST node being checked.
@@ -102,7 +128,7 @@ module.exports = Components.detect(function (context, components) {
102128
},
103129

104130
ClassDeclaration: function (node) {
105-
if (!hasPureRenderDecorator(node)) {
131+
if (!(hasPureRenderDecorator(node) || hasCustomDecorator(node))) {
106132
return;
107133
}
108134
markSCUAsDeclared(node);
@@ -148,3 +174,16 @@ module.exports = Components.detect(function (context, components) {
148174
}
149175
};
150176
});
177+
178+
module.exports.schema = [{
179+
type: 'object',
180+
properties: {
181+
allowDecorators: {
182+
type: 'array',
183+
items: {
184+
type: 'string'
185+
}
186+
}
187+
},
188+
additionalProperties: false
189+
}];

tests/lib/rules/require-optimization.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ ruleTester.run('react-require-optimization', rule, {
7777
].join('\n'),
7878
parser: 'babel-eslint',
7979
parserOptions: parserOptions
80+
}, {
81+
code: [
82+
'@bar',
83+
'@pureRender',
84+
'@foo',
85+
'class DecoratedComponent extends Component {' +
86+
'}'
87+
].join('\n'),
88+
parser: 'babel-eslint',
89+
options: [{allowDecorators: ['renderPure', 'pureRender']}],
90+
parserOptions: parserOptions
8091
}],
8192

8293
invalid: [{
@@ -129,5 +140,19 @@ ruleTester.run('react-require-optimization', rule, {
129140
}],
130141
parser: 'babel-eslint',
131142
parserOptions: parserOptions
143+
}, {
144+
code: [
145+
'@bar',
146+
'@pure',
147+
'@foo',
148+
'class DecoratedComponent extends Component {' +
149+
'}'
150+
].join('\n'),
151+
errors: [{
152+
message: MESSAGE
153+
}],
154+
parser: 'babel-eslint',
155+
options: [{allowDecorators: ['renderPure', 'pureRender']}],
156+
parserOptions: parserOptions
132157
}]
133158
});

0 commit comments

Comments
 (0)