eslint-plugin-stratified-design 0.12.8 → 0.12.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -85,6 +85,11 @@ const funcC = (...) => {
|
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
```js
|
|
89
|
+
const func = () => "a";
|
|
90
|
+
const obj = { a: func() };
|
|
91
|
+
```
|
|
92
|
+
|
|
88
93
|
Examples of **correct** code for this rule:
|
|
89
94
|
|
|
90
95
|
```js
|
|
@@ -116,3 +121,16 @@ const funcC = (...) => {
|
|
|
116
121
|
...
|
|
117
122
|
}
|
|
118
123
|
```
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
const func = () => "a";
|
|
127
|
+
// @data
|
|
128
|
+
const obj = { a: func() };
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
import { lib } from "module";
|
|
133
|
+
//@import
|
|
134
|
+
const { fn2 } = lib;
|
|
135
|
+
const fn1 = () => fn2();
|
|
136
|
+
```
|
package/lib/helpers/common.js
CHANGED
|
@@ -134,6 +134,24 @@ const match = (path) => {
|
|
|
134
134
|
return (pattern) => minimatch(path, pattern);
|
|
135
135
|
};
|
|
136
136
|
|
|
137
|
+
/**
|
|
138
|
+
* @template T
|
|
139
|
+
* @param {...(() => T)} args
|
|
140
|
+
* @returns {T | undefined}
|
|
141
|
+
*/
|
|
142
|
+
const or = (...args) => {
|
|
143
|
+
for (const arg of args) {
|
|
144
|
+
try {
|
|
145
|
+
const result = arg();
|
|
146
|
+
if (result !== undefined) return result;
|
|
147
|
+
else continue;
|
|
148
|
+
} catch (e) {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return undefined;
|
|
153
|
+
};
|
|
154
|
+
|
|
137
155
|
module.exports = {
|
|
138
156
|
toRelative,
|
|
139
157
|
toSegments,
|
|
@@ -149,4 +167,5 @@ module.exports = {
|
|
|
149
167
|
replaceAlias,
|
|
150
168
|
fromCwd,
|
|
151
169
|
match,
|
|
170
|
+
or,
|
|
152
171
|
};
|
|
@@ -1,150 +1,146 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Disallow calling functions in the same file.
|
|
3
3
|
* @author Hodoug Joung
|
|
4
|
+
* @description 최상위에 있는 node가 함수인지 데이터인지 구분하지 않고 모두 함수로 취급힌다. (데이터인 경우에는 주석으로 '@data'를 붙여줘야 한다. 단, 명백하게 데이터인 경우에는 그 주석을 붙여주지 않아도 된다.)
|
|
4
5
|
*/
|
|
5
6
|
"use strict";
|
|
6
7
|
|
|
7
8
|
const path = require("path");
|
|
8
|
-
const { fromCwd, match } = require("../helpers/common");
|
|
9
|
+
const { fromCwd, match, or } = require("../helpers/common");
|
|
9
10
|
|
|
10
11
|
//------------------------------------------------------------------------------
|
|
11
12
|
// Rule Definition
|
|
12
13
|
//------------------------------------------------------------------------------
|
|
13
14
|
|
|
14
|
-
// FIXME: const Body = styled.div``; const Body2 = styled(Body)`` (TaggedTemplateExpression)
|
|
15
|
-
|
|
16
15
|
/**
|
|
17
16
|
* @typedef {import('eslint').Rule.Node} Node
|
|
18
17
|
* @typedef {import('eslint').AST.Token} Token
|
|
19
18
|
* @typedef {import('eslint').SourceCode} SourceCode
|
|
20
19
|
* @typedef {({[name: string]: number})} Levels
|
|
20
|
+
* @typedef {({[name: string]: boolean})} DataNames
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
const hasArrFunction = (elements, levels) => {
|
|
24
|
-
return elements.reduce((hasFunc, element) => {
|
|
25
|
-
if (hasFunc) return true;
|
|
26
|
-
const type = element.type;
|
|
27
|
-
if (type === "FunctionExpression" || type === "ArrowFunctionExpression")
|
|
28
|
-
return true;
|
|
29
|
-
if (type === "ObjectExpression")
|
|
30
|
-
return hasObjFunction(element.properties, levels);
|
|
31
|
-
if (type === "ArrayExpression")
|
|
32
|
-
return hasArrFunction(element.elements, levels);
|
|
33
|
-
if ("name" in element && element.name in levels) return true;
|
|
34
|
-
return false;
|
|
35
|
-
}, false);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const hasObjFunction = (properties, levels) => {
|
|
39
|
-
return properties.reduce((hasFunc, property) => {
|
|
40
|
-
if (hasFunc) return true;
|
|
41
|
-
if (!("value" in property)) return false;
|
|
42
|
-
const type = property.value.type;
|
|
43
|
-
if (type === "FunctionExpression" || type === "ArrowFunctionExpression")
|
|
44
|
-
return true;
|
|
45
|
-
if (type === "ObjectExpression")
|
|
46
|
-
return hasObjFunction(property.value.properties, levels);
|
|
47
|
-
if (type === "ArrayExpression")
|
|
48
|
-
return hasArrFunction(property.value.elements, levels);
|
|
49
|
-
if ("name" in property.value && property.value.name in levels) return true;
|
|
50
|
-
return false;
|
|
51
|
-
}, false);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
23
|
/**
|
|
55
24
|
* @param {Node | Token} nodeOrToken
|
|
56
25
|
*/
|
|
57
26
|
const deriveDeclaration = (nodeOrToken) => {
|
|
58
|
-
|
|
59
|
-
nodeOrToken.type === "
|
|
27
|
+
const declaration =
|
|
28
|
+
(nodeOrToken.type === "ExportNamedDeclaration" ||
|
|
29
|
+
nodeOrToken.type === "ExportDefaultDeclaration") &&
|
|
60
30
|
Boolean(nodeOrToken.declaration)
|
|
61
|
-
|
|
62
|
-
|
|
31
|
+
? nodeOrToken.declaration
|
|
32
|
+
: nodeOrToken;
|
|
33
|
+
return or(
|
|
34
|
+
() => declaration.declarations[0],
|
|
35
|
+
() => declaration
|
|
36
|
+
);
|
|
63
37
|
};
|
|
64
38
|
|
|
65
39
|
/**
|
|
66
|
-
* @param {
|
|
67
|
-
* @
|
|
40
|
+
* @param {any} declarationInit
|
|
41
|
+
* @param {DataNames} dataNames
|
|
42
|
+
* @returns {boolean}
|
|
68
43
|
*/
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
44
|
+
const isData = (declarationInit, dataNames) => {
|
|
45
|
+
const expression = or(
|
|
46
|
+
() => declarationInit.expression,
|
|
47
|
+
() => declarationInit
|
|
48
|
+
);
|
|
49
|
+
if (!expression) return false;
|
|
74
50
|
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
"CallExpression",
|
|
81
|
-
"TaggedTemplateExpression",
|
|
82
|
-
].includes(init.type)
|
|
83
|
-
) {
|
|
84
|
-
return id.name;
|
|
51
|
+
const type = expression.type;
|
|
52
|
+
if (type === "Literal") return true;
|
|
53
|
+
if (type === "Identifier") {
|
|
54
|
+
const name = or(() => expression.name);
|
|
55
|
+
return name && dataNames[name];
|
|
85
56
|
}
|
|
86
|
-
|
|
87
|
-
|
|
57
|
+
if (type === "MemberExpression") {
|
|
58
|
+
const name = or(() => expression.object.name);
|
|
59
|
+
return name && dataNames[name];
|
|
60
|
+
}
|
|
61
|
+
if (type === "CallExpression") {
|
|
62
|
+
const name = or(() => expression.callee.name);
|
|
63
|
+
return name && dataNames[name];
|
|
64
|
+
}
|
|
65
|
+
if (type === "JSXElement") {
|
|
66
|
+
const name = or(() => expression.openingElement.name.name);
|
|
67
|
+
return name && dataNames[name];
|
|
68
|
+
}
|
|
69
|
+
if (type === "SpreadElement") return isData(expression.argument, dataNames);
|
|
70
|
+
if (type === "ArrayExpression")
|
|
71
|
+
return expression.elements.every((init) => isData(init, dataNames));
|
|
72
|
+
if (type === "ObjectExpression")
|
|
73
|
+
return expression.properties.every(({ value }) => isData(value, dataNames));
|
|
74
|
+
return false;
|
|
88
75
|
};
|
|
89
76
|
|
|
90
77
|
/**
|
|
91
78
|
* @param {Node | Token} nodeOrToken
|
|
92
|
-
* @param {
|
|
93
|
-
* @returns {
|
|
79
|
+
* @param {DataNames} dataNames
|
|
80
|
+
* @returns {boolean}
|
|
94
81
|
*/
|
|
95
|
-
const
|
|
82
|
+
const isNodeData = (nodeOrToken, dataNames) => {
|
|
96
83
|
const declaration = deriveDeclaration(nodeOrToken);
|
|
97
|
-
|
|
98
|
-
const { init, id } = declaration.declarations[0];
|
|
99
|
-
if (
|
|
100
|
-
init.type === "ObjectExpression" &&
|
|
101
|
-
hasObjFunction(init.properties, levels)
|
|
102
|
-
) {
|
|
103
|
-
return id.name;
|
|
104
|
-
} else if (
|
|
105
|
-
init.type === "ArrayExpression" &&
|
|
106
|
-
hasArrFunction(init.elements, levels)
|
|
107
|
-
) {
|
|
108
|
-
return id.name;
|
|
109
|
-
} else {
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const or = (...args) => {
|
|
115
|
-
for (const arg of args) {
|
|
116
|
-
try {
|
|
117
|
-
const result = arg();
|
|
118
|
-
if (result) return result;
|
|
119
|
-
else continue;
|
|
120
|
-
} catch (e) {
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return undefined;
|
|
84
|
+
return isData(declaration.init, dataNames);
|
|
125
85
|
};
|
|
126
86
|
|
|
87
|
+
/**
|
|
88
|
+
* @param {Node | Token} nodeOrToken
|
|
89
|
+
* @param {Levels} levels
|
|
90
|
+
* @returns {string[] | undefined}
|
|
91
|
+
*/
|
|
127
92
|
const deriveNames = (nodeOrToken) => {
|
|
128
93
|
const declaration = deriveDeclaration(nodeOrToken);
|
|
129
94
|
const names = or(
|
|
130
95
|
() => declaration.id.name,
|
|
131
|
-
() => declaration.
|
|
132
|
-
() => declaration.
|
|
133
|
-
() =>
|
|
134
|
-
declaration.declarations[0].id.properties.map(({ value }) => value.name)
|
|
96
|
+
() => declaration.id.elements.map(({ name }) => name),
|
|
97
|
+
() => declaration.id.properties.map(({ value }) => value.name)
|
|
135
98
|
);
|
|
136
99
|
return names === undefined ? [] : Array.isArray(names) ? names : [names];
|
|
137
100
|
};
|
|
138
101
|
|
|
102
|
+
/**
|
|
103
|
+
* @param {Node | Token} nodeOrToken
|
|
104
|
+
* @returns {string | undefined}
|
|
105
|
+
*/
|
|
106
|
+
const deriveCallerName = (nodeOrToken) =>
|
|
107
|
+
or(() => deriveDeclaration(nodeOrToken).id.name);
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {SourceCode} sourceCode
|
|
111
|
+
* @param {Node | Token} nodeOrToken
|
|
112
|
+
* @returns {boolean}
|
|
113
|
+
*/
|
|
114
|
+
const hasDataComment = (sourceCode, nodeOrToken) => {
|
|
115
|
+
const comments = sourceCode.getCommentsBefore(nodeOrToken);
|
|
116
|
+
for (const { value: comment } of comments) {
|
|
117
|
+
if (comment.includes("@data")) return true;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
};
|
|
121
|
+
|
|
139
122
|
/**
|
|
140
123
|
* @param {SourceCode} sourceCode
|
|
141
124
|
* @param {Node | Token} nodeOrToken
|
|
142
|
-
*
|
|
125
|
+
* @returns {boolean}
|
|
126
|
+
*/
|
|
127
|
+
const hasImportComment = (sourceCode, nodeOrToken) => {
|
|
128
|
+
const comments = sourceCode.getCommentsBefore(nodeOrToken);
|
|
129
|
+
for (const { value: comment } of comments) {
|
|
130
|
+
if (comment.includes("@import")) return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @param {SourceCode} sourceCode
|
|
137
|
+
* @param {Node | Token} nodeOrToken
|
|
138
|
+
* @returns {number}
|
|
143
139
|
*/
|
|
144
140
|
const deriveLevel = (sourceCode, nodeOrToken) => {
|
|
145
141
|
const comments = sourceCode.getCommentsBefore(nodeOrToken);
|
|
146
|
-
for (const { value } of comments) {
|
|
147
|
-
const levelInStr =
|
|
142
|
+
for (const { value: comment } of comments) {
|
|
143
|
+
const levelInStr = comment.replace(/^[^]*@level\s+?([0-9]+)[^0-9]*$/, "$1");
|
|
148
144
|
const levelInNum = Number(levelInStr);
|
|
149
145
|
if (levelInStr && !Number.isNaN(levelInNum)) {
|
|
150
146
|
return levelInNum;
|
|
@@ -154,6 +150,7 @@ const deriveLevel = (sourceCode, nodeOrToken) => {
|
|
|
154
150
|
};
|
|
155
151
|
|
|
156
152
|
/**
|
|
153
|
+
* root node(Program) 바로 아래에 있는 부모 노드를 리턴한다.
|
|
157
154
|
* @param {SourceCode} sourceCode
|
|
158
155
|
* @param {Node} node
|
|
159
156
|
*/
|
|
@@ -175,7 +172,7 @@ const isCalleeLowerLevel = (sourceCode, levels) => {
|
|
|
175
172
|
if (calleeLevel === undefined) return true; // 호출되는 함수가 존재하지 않으면 true 리턴. 함수 내의 함수의 경우에는 항상 calleeLevel 이 undefined 이다.
|
|
176
173
|
|
|
177
174
|
const caller = traceAncestor(sourceCode, node);
|
|
178
|
-
const callerName =
|
|
175
|
+
const callerName = deriveCallerName(caller);
|
|
179
176
|
const callerLevel = levels[callerName];
|
|
180
177
|
|
|
181
178
|
if (callerLevel === undefined) return true;
|
|
@@ -248,6 +245,12 @@ module.exports = {
|
|
|
248
245
|
*/
|
|
249
246
|
const levels = {};
|
|
250
247
|
|
|
248
|
+
/**
|
|
249
|
+
* 선언된 것이 데이터인지 여부를 나타내는 객체.
|
|
250
|
+
* @type {DataNames}
|
|
251
|
+
*/
|
|
252
|
+
const dataNames = {};
|
|
253
|
+
|
|
251
254
|
const sourceCode = context.sourceCode;
|
|
252
255
|
|
|
253
256
|
/**
|
|
@@ -269,10 +272,27 @@ module.exports = {
|
|
|
269
272
|
Program(node) {
|
|
270
273
|
node.body.forEach((token) => {
|
|
271
274
|
deriveNames(token).forEach((name) => {
|
|
272
|
-
if (name
|
|
275
|
+
if (!name || hasImportComment(sourceCode, token)) return;
|
|
276
|
+
if (
|
|
277
|
+
hasDataComment(sourceCode, token) ||
|
|
278
|
+
isNodeData(token, dataNames)
|
|
279
|
+
) {
|
|
280
|
+
dataNames[name] = true;
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const level = deriveLevel(sourceCode, token);
|
|
284
|
+
levels[name] = level;
|
|
273
285
|
});
|
|
274
286
|
});
|
|
275
287
|
},
|
|
288
|
+
VariableDeclarator(node) {
|
|
289
|
+
const init = or(() => node.init.name);
|
|
290
|
+
const id = or(() => node.id.name);
|
|
291
|
+
if (!init || !id) return;
|
|
292
|
+
if (levels[init] && !levels[id]) {
|
|
293
|
+
levels[id] = levels[init];
|
|
294
|
+
}
|
|
295
|
+
},
|
|
276
296
|
CallExpression(node) {
|
|
277
297
|
for (const { name } of node.arguments) {
|
|
278
298
|
const isReported = report(node, name);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-stratified-design",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.10",
|
|
4
4
|
"description": "ESlint rules for stratified design",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"lint": "eslint .",
|
|
22
22
|
"test": "mocha tests --recursive",
|
|
23
23
|
"test:watch": "mocha tests --recursive --watch",
|
|
24
|
+
"test:single": "mocha tests --watch",
|
|
24
25
|
"versioning": "node ./scripts/versioning"
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
@@ -9,13 +9,18 @@
|
|
|
9
9
|
//------------------------------------------------------------------------------
|
|
10
10
|
|
|
11
11
|
const rule = require("../../../lib/rules/no-same-level-funcs"),
|
|
12
|
-
RuleTester = require("eslint").RuleTester
|
|
12
|
+
RuleTester = require("eslint").RuleTester,
|
|
13
|
+
path = require("path");
|
|
13
14
|
|
|
14
15
|
//------------------------------------------------------------------------------
|
|
15
16
|
// Tests
|
|
16
17
|
//------------------------------------------------------------------------------
|
|
17
18
|
|
|
18
19
|
const ruleTester = new RuleTester({
|
|
20
|
+
parser: path.resolve(
|
|
21
|
+
__dirname,
|
|
22
|
+
"../../../node_modules/@typescript-eslint/parser/dist/index.js"
|
|
23
|
+
),
|
|
19
24
|
parserOptions: {
|
|
20
25
|
ecmaVersion: 2022,
|
|
21
26
|
sourceType: "module",
|
|
@@ -116,12 +121,10 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
116
121
|
{
|
|
117
122
|
code: "// @level 2\nfunction func2(){};\nfunction func1(){ func2(); }",
|
|
118
123
|
filename: "./src/foo.js",
|
|
119
|
-
errors: [{ messageId: "no-same-level-funcs", data: { func: "func2" } }],
|
|
120
124
|
},
|
|
121
125
|
{
|
|
122
126
|
code: "// @level 2\nexport function func2(){};\nfunction func1(){ func2(); }",
|
|
123
127
|
filename: "./src/foo.js",
|
|
124
|
-
errors: [{ messageId: "no-same-level-funcs", data: { func: "func2" } }],
|
|
125
128
|
},
|
|
126
129
|
|
|
127
130
|
{
|
|
@@ -160,14 +163,14 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
160
163
|
},
|
|
161
164
|
|
|
162
165
|
{
|
|
163
|
-
code: "const func = () => 'a'; const obj = { a: func() }
|
|
166
|
+
code: "/*@level 2*/const func = () => 'a'; const obj = { a: func() }",
|
|
164
167
|
filename: "./src/foo.js",
|
|
165
168
|
},
|
|
166
169
|
{
|
|
167
|
-
code: "
|
|
170
|
+
code: "const func = () => 'a'; /*@data*/const obj = { a: func() }",
|
|
168
171
|
filename: "./src/foo.js",
|
|
169
|
-
errors: [{ messageId: "no-same-level-funcs", data: { func: "obj" } }],
|
|
170
172
|
},
|
|
173
|
+
|
|
171
174
|
{
|
|
172
175
|
code: "/*@level 2*/const obj = { func2: () => {} }; /*@level 1*/const func1 = () => { obj.func2() } ",
|
|
173
176
|
filename: "./src/foo.js",
|
|
@@ -179,11 +182,10 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
179
182
|
{
|
|
180
183
|
code: "/*@level 3*/const func3 = () => 'a'; /*@level 2*/const obj = { func2: func3 }; /*@level 1*/const func1 = () => { obj.func2() } ",
|
|
181
184
|
filename: "./src/foo.js",
|
|
182
|
-
errors: [{ messageId: "no-same-level-funcs", data: { func: "obj" } }],
|
|
183
185
|
},
|
|
184
186
|
|
|
185
187
|
{
|
|
186
|
-
code: "const func = () => 'a'; const arr = [func()];",
|
|
188
|
+
code: "/*@level 2*/const func = () => 'a'; const arr = [func()];",
|
|
187
189
|
filename: "./src/foo.js",
|
|
188
190
|
},
|
|
189
191
|
{
|
|
@@ -231,6 +233,44 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
231
233
|
code: "//@level 2\nconst {dat, fn2: func2} = someFn()\nconst fn1 = () => { func2() }\n",
|
|
232
234
|
filename: "./src/foo.js",
|
|
233
235
|
},
|
|
236
|
+
|
|
237
|
+
{
|
|
238
|
+
code: "const arr = []; const fn = () => arr.push(1)",
|
|
239
|
+
filename: "./src/foo.js",
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
code: "const arr = [{ a: 1 }]; const fn = () => arr.push(1)",
|
|
243
|
+
filename: "./src/foo.js",
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
code: "const obj = { arr: [] }; const fn = () => obj.arr.push(1)",
|
|
247
|
+
filename: "./src/foo.js",
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
code: "const arr = [1, 2, 3] as const; const fn = () => arr.some(v => v === 1)",
|
|
251
|
+
filename: "./src/foo.js",
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
code: "const data = ''; /*@level 2*/const fn2 = (param) => param; const fn1 = () => fn2(data)",
|
|
255
|
+
filename: "./src/foo.js",
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
{
|
|
259
|
+
code: "const CONST = 1; const data = CONST; const fn = () => data.replace(/a/g, 'b')",
|
|
260
|
+
filename: "./src/foo.js",
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
code: "const CONST = 1; const arr = [CONST]; const fn = () => arr.some(v => v === CONST)",
|
|
264
|
+
filename: "./src/foo.js",
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
code: "const CONST = 1; const obj = { a: [CONST] }; const fn = () => obj.a.some(v => v === CONST)",
|
|
268
|
+
filename: "./src/foo.js",
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
code: "import { lib } from 'lib'; /*@import*/const { fn2 } = lib; const fn1 = () => fn2()",
|
|
272
|
+
filename: "./src/foo.js",
|
|
273
|
+
},
|
|
234
274
|
],
|
|
235
275
|
invalid: [
|
|
236
276
|
{
|
|
@@ -309,17 +349,15 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
309
349
|
errors: [{ messageId: "no-same-level-funcs", data: { func: "hof" } }],
|
|
310
350
|
},
|
|
311
351
|
{
|
|
312
|
-
code: "const fnByHof = hof(() => 1); const value = fnByHof()",
|
|
313
|
-
filename: "./src/foo.js",
|
|
314
|
-
errors: [{ messageId: "no-same-level-funcs", data: { func: "fnByHof" } }],
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
code: "const fnByHof = hof(() => 1); const fn = fnByHof(() => 1)",
|
|
352
|
+
code: "const hof = (fn) => () => fn(); const fnByHof = hof(() => 1); const value = fnByHof()",
|
|
318
353
|
filename: "./src/foo.js",
|
|
319
|
-
errors: [
|
|
354
|
+
errors: [
|
|
355
|
+
{ messageId: "no-same-level-funcs", data: { func: "hof" } },
|
|
356
|
+
{ messageId: "no-same-level-funcs", data: { func: "fnByHof" } },
|
|
357
|
+
],
|
|
320
358
|
},
|
|
321
359
|
{
|
|
322
|
-
code: "const fn = () => 1; const fnByHof = hof(fn)",
|
|
360
|
+
code: "const hof = (f) => () => f(); const fn = () => 1; const fnByHof = hof(fn)",
|
|
323
361
|
filename: "./src/foo.js",
|
|
324
362
|
errors: [{ messageId: "no-same-level-funcs", data: { func: "fn" } }],
|
|
325
363
|
},
|
|
@@ -392,19 +430,76 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
392
430
|
},
|
|
393
431
|
|
|
394
432
|
{
|
|
395
|
-
code: "const [dat, fn2] = someFn()
|
|
433
|
+
code: "const someFn = () => [1, () => 2]; const [dat, fn2] = someFn(); const fn1 = () => { fn2() }",
|
|
396
434
|
filename: "./src/foo.js",
|
|
397
435
|
errors: [{ messageId: "no-same-level-funcs", data: { func: "fn2" } }],
|
|
398
436
|
},
|
|
399
437
|
{
|
|
400
|
-
code: "const {dat, fn2} = someFn()
|
|
438
|
+
code: "const someFn = () => ({ dat: 1, fn2: () => 2 }); const {dat, fn2} = someFn(); const fn1 = () => { fn2() };",
|
|
401
439
|
filename: "./src/foo.js",
|
|
402
440
|
errors: [{ messageId: "no-same-level-funcs", data: { func: "fn2" } }],
|
|
403
441
|
},
|
|
404
442
|
{
|
|
405
|
-
code: "const {dat, fn2: func2} = someFn()
|
|
443
|
+
code: "const someFn = () => ({ dat: 1, fn2: () => 2 }); const {dat, fn2: func2} = someFn(); const fn1 = () => { func2() };",
|
|
406
444
|
filename: "./src/foo.js",
|
|
407
445
|
errors: [{ messageId: "no-same-level-funcs", data: { func: "func2" } }],
|
|
408
446
|
},
|
|
447
|
+
|
|
448
|
+
{
|
|
449
|
+
code: "const fn2 = () => {}; const fn1 = () => { const _fn2 = fn2; _fn2()}",
|
|
450
|
+
filename: "./src/foo.js",
|
|
451
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "_fn2" } }],
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
code: "const fn2 = () => {}; const fn1 = () => { const _fn2 = fn2; const __fn2 = _fn2; __fn2()}",
|
|
455
|
+
filename: "./src/foo.js",
|
|
456
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "__fn2" } }],
|
|
457
|
+
},
|
|
458
|
+
|
|
459
|
+
{
|
|
460
|
+
code: "import { lib } from 'lib'; const { fn2 } = lib; const fn1 = () => fn2()",
|
|
461
|
+
filename: "./src/foo.js",
|
|
462
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "fn2" } }],
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
code: "import { lib } from 'lib'; const fn2 = lib.fn2; const fn1 = () => fn2()",
|
|
466
|
+
filename: "./src/foo.js",
|
|
467
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "fn2" } }],
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
code: "import { fn2 } from 'lib'; const arr = [fn2]; const fn1 = () => arr[0]()",
|
|
471
|
+
filename: "./src/foo.js",
|
|
472
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
code: "import { hof1, hof2 } from 'lib'; const fn2 = hof2(); const fn1 = () => hof1(fn2)",
|
|
476
|
+
filename: "./src/foo.js",
|
|
477
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "fn2" } }],
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
code: "import { fn2 } from 'lib'; const arr = [fn2()]; const fn1 = () => arr.push(1)",
|
|
481
|
+
filename: "./src/foo.js",
|
|
482
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
code: "import { fn2 } from 'lib'; const data = [...fn2()]; const fn1 = () => data.push(1)",
|
|
486
|
+
filename: "./src/foo.js",
|
|
487
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "data" } }],
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
code: "import { fn2 } from 'lib'; const arr = [fn2]; const fn1 = () => arr.push(1)",
|
|
491
|
+
filename: "./src/foo.js",
|
|
492
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
code: "import { Comp2 } from 'lib'; const arr = [<Comp2 />]; const fn1 = () => arr.push(1)",
|
|
496
|
+
filename: "./src/foo.js",
|
|
497
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
code: "import { Comp2 } from 'lib'; const arr = [Comp2]; const fn1 = () => arr.push(1)",
|
|
501
|
+
filename: "./src/foo.js",
|
|
502
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
503
|
+
},
|
|
409
504
|
],
|
|
410
505
|
});
|