Skip to content

Commit a312b16

Browse files
committed
Init rule state-in-constructor
1 parent d7ba7c6 commit a312b16

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ const allRules = {
7878
'self-closing-comp': require('./lib/rules/self-closing-comp'),
7979
'sort-comp': require('./lib/rules/sort-comp'),
8080
'sort-prop-types': require('./lib/rules/sort-prop-types'),
81+
'state-in-constructor': require('./lib/rules/state-in-constructor'),
8182
'style-prop-object': require('./lib/rules/style-prop-object'),
8283
'void-dom-elements-no-children': require('./lib/rules/void-dom-elements-no-children')
8384
};

lib/rules/state-in-constructor.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @fileoverview State initialization in an ES6 class component should be in a constructor
3+
* @author Kanitkorn Sujautra
4+
*/
5+
'use strict';
6+
7+
const Components = require('../util/Components');
8+
const docsUrl = require('../util/docsUrl');
9+
10+
// ------------------------------------------------------------------------------
11+
// Rule Definition
12+
// ------------------------------------------------------------------------------
13+
14+
module.exports = {
15+
meta: {
16+
docs: {
17+
description: 'State initialization in an ES6 class component should be in a constructor',
18+
category: 'Stylistic Issues',
19+
recommended: false,
20+
url: docsUrl('state-in-constructor')
21+
},
22+
schema: []
23+
},
24+
25+
create: Components.detect((context, components, utils) => ({
26+
ClassProperty: function (node) {
27+
if (
28+
!node.static &&
29+
node.key.name === 'state' &&
30+
utils.isES6Component(node.parent.parent)
31+
) {
32+
context.report({
33+
node,
34+
message: 'State initialization should be in a constructor'
35+
});
36+
}
37+
}
38+
}))
39+
};
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/**
2+
* @fileoverview State initialization in an ES6 class component should be in a constructor
3+
* @author Kanitkorn Sujautra
4+
*/
5+
'use strict';
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
const rule = require('../../../lib/rules/state-in-constructor');
12+
const RuleTester = require('eslint').RuleTester;
13+
14+
const ruleTesterConfig = {
15+
parser: 'babel-eslint',
16+
parserOptions: {
17+
ecmaVersion: 2018,
18+
sourceType: 'module',
19+
ecmaFeatures: {
20+
jsx: true
21+
}
22+
}
23+
};
24+
25+
// ------------------------------------------------------------------------------
26+
// Tests
27+
// ------------------------------------------------------------------------------
28+
29+
const ruleTester = new RuleTester(ruleTesterConfig);
30+
ruleTester.run('state-in-constructor', rule, {
31+
valid: [{
32+
code: `
33+
class Foo extends React.Component {
34+
render() {
35+
return <div>Foo</div>
36+
}
37+
}
38+
`
39+
}, {
40+
code: `
41+
class Foo extends React.Component {
42+
constructor(props) {
43+
super(props)
44+
this.state = { bar: 0 }
45+
}
46+
render() {
47+
return <div>Foo</div>
48+
}
49+
}
50+
`
51+
}, {
52+
code: `
53+
class Foo extends React.Component {
54+
constructor(props) {
55+
super(props)
56+
this.state = { bar: 0 }
57+
}
58+
baz = { bar: 0 }
59+
render() {
60+
return <div>Foo</div>
61+
}
62+
}
63+
`
64+
}, {
65+
code: `
66+
class Foo extends React.Component {
67+
constructor(props) {
68+
super(props)
69+
this.baz = { bar: 0 }
70+
}
71+
render() {
72+
return <div>Foo</div>
73+
}
74+
}
75+
`
76+
}, {
77+
code: `
78+
class Foo extends React.Component {
79+
baz = { bar: 0 }
80+
render() {
81+
return <div>Foo</div>
82+
}
83+
}
84+
`
85+
}, {
86+
code: `
87+
const Foo = () => <div>Foo</div>
88+
`
89+
}, {
90+
code: `
91+
function Foo () {
92+
return <div>Foo</div>
93+
}
94+
`
95+
}],
96+
97+
invalid: [{
98+
code: `
99+
class Foo extends React.Component {
100+
state = { bar: 0 }
101+
render() {
102+
return <div>Foo</div>
103+
}
104+
}
105+
`,
106+
errors: [{
107+
message: 'State initialization should be in a constructor'
108+
}]
109+
}, {
110+
code: `
111+
class Foo extends React.Component {
112+
state = { bar: 0 }
113+
baz = { bar: 0 }
114+
render() {
115+
return <div>Foo</div>
116+
}
117+
}
118+
`,
119+
errors: [{
120+
message: 'State initialization should be in a constructor'
121+
}]
122+
}, {
123+
code: `
124+
class Foo extends React.Component {
125+
constructor(props) {
126+
super(props)
127+
this.baz = { bar: 0 }
128+
}
129+
state = { baz: 0 }
130+
render() {
131+
return <div>Foo</div>
132+
}
133+
}
134+
`,
135+
errors: [{
136+
message: 'State initialization should be in a constructor'
137+
}]
138+
}, {
139+
code: `
140+
class Foo extends React.Component {
141+
constructor(props) {
142+
super(props)
143+
this.state = { bar: 0 }
144+
}
145+
state = { baz: 0 }
146+
render() {
147+
return <div>Foo</div>
148+
}
149+
}
150+
`,
151+
errors: [{
152+
message: 'State initialization should be in a constructor'
153+
}]
154+
}]
155+
});

0 commit comments

Comments
 (0)