Skip to content

Commit 1aaeac6

Browse files
committed
feature: @putout/plugin-putout: check-declare: add
1 parent 4a56d80 commit 1aaeac6

File tree

14 files changed

+174
-1
lines changed

14 files changed

+174
-1
lines changed

packages/plugin-eslint/lib/declare/eslint-flat.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module.exports = {
44
matchToFlat: `import {matchToFlat} from '@putout/eslint-flat'`,
5-
matchToFlatDir: `import {matchToFlat} from '@putout/eslint-flat'`,
5+
matchToFlatDir: `import {matchToFlatDir} from '@putout/eslint-flat'`,
66
mergeESLintConfigs: `import {mergeESLintConfigs} from '@putout/eslint-flat'`,
77
createESLintConfig: `import {createESLintConfig} from '@putout/eslint-flat'`,
88
};

packages/plugin-eslint/lib/declare/fixture/eslint-flat-fix.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {matchToFlatDir} from '@putout/eslint-flat';
12
import {matchToFlat} from '@putout/eslint-flat';
23
import {mergeESLintConfigs} from '@putout/eslint-flat';
34
import {createESLintConfig} from '@putout/eslint-flat';

packages/plugin-putout/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ npm i @putout/plugin-putout -D
3737
-[apply-parens](#apply-parens);
3838
-[apply-short-processors](#apply-short-processors);
3939
-[check-match](#check-match);
40+
-[check-declare](#check-declare);
4041
-[check-replace-code](#check-replace-code);
4142
-[convert-add-argument-to-add-args](#convert-add-argument-to-add-test-args);
4243
-[convert-babel-types](#convert-babel-types);
@@ -105,6 +106,7 @@ npm i @putout/plugin-putout -D
105106
"putout/apply-for-of-to-track-file": "on",
106107
"putout/apply-fixture-name-to-message": "on",
107108
"putout/check-match": "on",
109+
"putout/check-declare": "on",
108110
"putout/check-replace-code": ["on", {
109111
"once": true
110112
}],
@@ -863,6 +865,23 @@ module.exports.match = () => ({
863865
});
864866
```
865867
868+
## check-declare
869+
870+
Checks that [Declarator](https://github.com/coderaiser/putout/tree/master/packages/engine-runner#declarator) transform is possible.
871+
Checkout in 🐊[**Putout Editor**](https://putout.cloudcmd.io/#/gist/9fccb187bb8933afff0dc0db57b3cea8/25cb812978fadb4efb5f0cb44058a61f70f8b78e):
872+
873+
### ❌ Example of incorrect code
874+
875+
```js
876+
module.exports.declare = () => ({
877+
isNumber: 'const isNumber = () => {}',
878+
isString: 'const isNumber = () => {}',
879+
});
880+
```
881+
882+
☝️ *There is no `fix` for this rule, it used internally to be more confident about `test coverage`, because of declaration form, transforms cannon be checked by `nyc` and `c8`, and uncovered lines can find unfixable false positives when running on code.
883+
This is additional tests, if you forget to test some case (from a big list of rules that is supported) it will be checked with this `rule` and make transforms more stable.*
884+
866885
## check-replace-code
867886
868887
Checks that [Replacer](https://github.com/coderaiser/putout/tree/master/packages/engine-runner#replacer) transform is possible.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports.declare = () => ({
2+
isNumber: 'const isNumber = () => {}',
3+
isString: 'const isNumber = () => {}',
4+
});
5+
6+
export const declare = () => ({
7+
isHello: 'const isHello = () => {}',
8+
isWorld: 'const isHello = () => {}',
9+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
isNumber: `const isNumber = () => {}`,
3+
isString: `const isNumber = () => {}`,
4+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
isNumber: 'const isNumber = () => {}',
3+
isString: 'const isNumber = () => {}',
4+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
getRule: `const getRule = ${getRule.toString()};`
3+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
lint: 'putout .',
3+
};
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'use strict';
2+
3+
const tryCatch = require('try-catch');
4+
const putout = require('putout');
5+
6+
const {types, operator} = putout;
7+
8+
const noop = () => {};
9+
const {getTemplateValues} = operator;
10+
11+
const DECLARE_ESM = 'export const declare = () => __object';
12+
const DECLARE_COMMONJS = 'module.exports.declare = () => __object';
13+
const COMMONJS = 'module.exports = __object';
14+
15+
const {
16+
isTemplateLiteral,
17+
isStringLiteral,
18+
} = types;
19+
20+
module.exports.report = ({message}) => message;
21+
22+
module.exports.fix = noop;
23+
module.exports.traverse = ({push}) => ({
24+
[DECLARE_ESM]: createCheck(push, DECLARE_ESM),
25+
[DECLARE_COMMONJS]: createCheck(push, DECLARE_COMMONJS),
26+
[COMMONJS]: createCheck(push, COMMONJS),
27+
});
28+
29+
const createCheck = (push, template) => (path) => {
30+
const {__object} = getTemplateValues(path, template);
31+
32+
const lines = [];
33+
34+
for (const {value} of __object.properties) {
35+
let current = '';
36+
37+
if (isStringLiteral(value)) {
38+
current = value.value;
39+
} else if (isTemplateLiteral(value)) {
40+
if (value.quasis.length > 1)
41+
continue;
42+
43+
current = value.quasis[0].value.cooked;
44+
}
45+
46+
if (/^(const|import)/.test(current))
47+
lines.push(current);
48+
}
49+
50+
const source = lines.join(';\n');
51+
const [error] = tryCatch(putout.parse, source);
52+
53+
if (!error)
54+
return;
55+
56+
const {message} = error;
57+
58+
push({
59+
path,
60+
message,
61+
});
62+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
const {createTest} = require('@putout/test');
4+
const plugin = require('.');
5+
6+
const test = createTest(__dirname, {
7+
plugins: [
8+
['check-declare', plugin],
9+
],
10+
});
11+
12+
test('putout: check-declare: report', (t) => {
13+
t.report('check-declare', [
14+
`Identifier 'isNumber' has already been declared. (2:6)`,
15+
`Identifier 'isHello' has already been declared. (2:6)`,
16+
]);
17+
t.end();
18+
});
19+
20+
test('putout: check-declare: report: commonjs', (t) => {
21+
t.report('commonjs', `Identifier 'isNumber' has already been declared. (2:6)`);
22+
t.end();
23+
});
24+
25+
test('putout: check-declare: report: commonjs-template', (t) => {
26+
t.report('commonjs-template', `Identifier 'isNumber' has already been declared. (2:6)`);
27+
t.end();
28+
});
29+
30+
test('putout: check-declare: no transform', (t) => {
31+
t.noTransform('check-declare');
32+
t.end();
33+
});
34+
35+
test('putout: check-declare: no report: not-declaration', (t) => {
36+
t.noReport('not-declaration');
37+
t.end();
38+
});
39+
40+
test('putout: check-declare: no report: couple-quasis', (t) => {
41+
t.noReport('couple-quasis');
42+
t.end();
43+
});

0 commit comments

Comments
 (0)