@putout/test 4.0.1 → 4.4.0
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.
- package/README.md +98 -3
- package/lib/eslint/eslint.mjs +76 -0
- package/lib/test.js +16 -11
- package/lib/test.mjs +12 -0
- package/package.json +13 -7
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[NPMIMGURL]: https://img.shields.io/npm/v/@putout/test.svg?style=flat&longCache=true
|
|
4
4
|
[NPMURL]: https://npmjs.org/package/@putout/test "npm"
|
|
5
5
|
|
|
6
|
-
Test runner for [
|
|
6
|
+
Test runner for 🐊[`Putout`](https://github.com/coderaiser/putout#plugins-api). Basically it is [supercharged `tape`](https://github.com/coderaiser/supertape) with aditional asseritions:
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
@@ -21,6 +21,21 @@ UPDATE=1 tape test/*.js
|
|
|
21
21
|
|
|
22
22
|
## Plugins API
|
|
23
23
|
|
|
24
|
+
All plugins 🐊`Putout` plugins written in `CommonJS`, since `ESLint` written on `CommonJS` and we have a huge `ESLint`-based ecosystem which is good to reuse.
|
|
25
|
+
🐊`Putout`can be used in all IDE's supported by`ESLint` as [`eslint-plugin-putout`](https://github.com/coderaiser/putout/tree/packages/eslint-plugin-putout).
|
|
26
|
+
When [async rules will be supported](https://github.com/eslint/eslint/issues/15394) we can switch to `ESM`.
|
|
27
|
+
|
|
28
|
+
To write test for your plugins you need initialize `test` using `createTest`:
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import {createTest} from '@putout/test';
|
|
32
|
+
const rmVars = require('@putout/plugin-remove-unused-variables');
|
|
33
|
+
|
|
34
|
+
const test = createTest(import.meta.url, {
|
|
35
|
+
'remove-unused-variables': rmVars,
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
24
39
|
### `report(filename, message | []messages)`
|
|
25
40
|
|
|
26
41
|
checks error message (or messages) of a plugin
|
|
@@ -168,6 +183,19 @@ test('plugin-apply-numeric-separators: no transform: hex', (t) => {
|
|
|
168
183
|
});
|
|
169
184
|
```
|
|
170
185
|
|
|
186
|
+
## Formatters API
|
|
187
|
+
|
|
188
|
+
First you need to create test with:
|
|
189
|
+
|
|
190
|
+
```js
|
|
191
|
+
import {createTest} from '@putout/test';
|
|
192
|
+
import rmVars from '@putout/plugin-remove-unused-variables';
|
|
193
|
+
|
|
194
|
+
const test = createTest(import.meta.url, {
|
|
195
|
+
'remove-unused-variables': rmVars,
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
171
199
|
### `format(formatter, filename)`
|
|
172
200
|
|
|
173
201
|
check file name formatting (pass `process.env.UPDATE=1` to save fixture)
|
|
@@ -203,8 +231,11 @@ test('formatter: dump: many', async ({formatMany}) => {
|
|
|
203
231
|
Here is example of tests for [remove-console](https://github.com/coderaiser/putout/tree/master/packages/plugin-remove-console):
|
|
204
232
|
|
|
205
233
|
```js
|
|
206
|
-
const
|
|
207
|
-
|
|
234
|
+
const {createTest} = require('@putout/test');
|
|
235
|
+
const removeConsole = require('@putout/plugin-remove-console');
|
|
236
|
+
|
|
237
|
+
const test = createTest(__dirname, {
|
|
238
|
+
'remove-console': removeConsole,
|
|
208
239
|
});
|
|
209
240
|
|
|
210
241
|
test('remove-console: report', (t) => {
|
|
@@ -224,6 +255,70 @@ test('test: declared', (t) => {
|
|
|
224
255
|
});
|
|
225
256
|
```
|
|
226
257
|
|
|
258
|
+
## ESLint API
|
|
259
|
+
|
|
260
|
+
First you need to create test with:
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
import {createTest} from '@putout/test/eslint';
|
|
264
|
+
const test = createTest(import.meta.url);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### `process(filename [, config])`
|
|
268
|
+
|
|
269
|
+
Works in similar to [transform](#transformfilename--output-plugins) way:
|
|
270
|
+
|
|
271
|
+
- ✅ reads `operator-linebreak.js`;
|
|
272
|
+
- ✅ transforms it;
|
|
273
|
+
- ✅ checks that transformed is equal to `operator-linebreak-fix.js`;
|
|
274
|
+
|
|
275
|
+
Example:
|
|
276
|
+
|
|
277
|
+
```js
|
|
278
|
+
test('test: eslint: transform', async ({process}) => {
|
|
279
|
+
await process('operator-linebreak');
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
test('test: eslint: transform', async ({process}) => {
|
|
283
|
+
await process('operator-linebreak', {
|
|
284
|
+
rules: {
|
|
285
|
+
'putout/putout': {
|
|
286
|
+
rules: {
|
|
287
|
+
'convert-esm-to-commonjs': 'on',
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### `noProcess(filename)`
|
|
296
|
+
|
|
297
|
+
Check that filename would not be processed.
|
|
298
|
+
|
|
299
|
+
Example:
|
|
300
|
+
|
|
301
|
+
```js
|
|
302
|
+
test('test: eslint: noProcess', async ({noProcess}) => {
|
|
303
|
+
await noProcess('operator-linebreak-fix');
|
|
304
|
+
});
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### `comparePlaces(filename, places)`
|
|
308
|
+
|
|
309
|
+
```js
|
|
310
|
+
test('eslint-config: operator-line-break', async ({comparePlaces}) => {
|
|
311
|
+
await comparePlaces('operator-linebreak', [{
|
|
312
|
+
"message": "There should be no line break before or after '='.",
|
|
313
|
+
"position": {
|
|
314
|
+
"column": 1,
|
|
315
|
+
"line": 2,
|
|
316
|
+
},
|
|
317
|
+
"rule": "operator-linebreak (eslint)",
|
|
318
|
+
}]);
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
227
322
|
## Processors API
|
|
228
323
|
|
|
229
324
|
With `processors api` you can test `processors` in a simplest possible way.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {readFile} from 'fs/promises';
|
|
2
|
+
import {join} from 'path';
|
|
3
|
+
|
|
4
|
+
import eslint from 'putout/eslint';
|
|
5
|
+
import tryToCatch from 'try-to-catch';
|
|
6
|
+
import {extend} from 'supertape';
|
|
7
|
+
|
|
8
|
+
const config = {
|
|
9
|
+
extends: [
|
|
10
|
+
'plugin:node/recommended',
|
|
11
|
+
'plugin:eslint-plugin/recommended',
|
|
12
|
+
'plugin:putout/recommended',
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const read = async (name) => {
|
|
17
|
+
const [, data] = await tryToCatch(readFile, `${name}.js`, 'utf8');
|
|
18
|
+
|
|
19
|
+
if (data)
|
|
20
|
+
return [`${name}.js`, data];
|
|
21
|
+
|
|
22
|
+
return [`${name}.ts`, await readFile(`${name}.ts`, 'utf8')];
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const createTest = (url) => {
|
|
26
|
+
const fixtureDir = new URL('fixture', url).pathname;
|
|
27
|
+
|
|
28
|
+
return extend({
|
|
29
|
+
process: (operator) => async (name, override) => {
|
|
30
|
+
const full = join(fixtureDir, name);
|
|
31
|
+
const [resolvedName, code] = await read(full);
|
|
32
|
+
const [, fixture] = await read(`${full}-fix`);
|
|
33
|
+
const fix = true;
|
|
34
|
+
|
|
35
|
+
const [source] = await eslint({
|
|
36
|
+
name: resolvedName,
|
|
37
|
+
code,
|
|
38
|
+
fix,
|
|
39
|
+
putout: true,
|
|
40
|
+
config: {
|
|
41
|
+
...config,
|
|
42
|
+
...override,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return operator.equal(source, fixture);
|
|
47
|
+
},
|
|
48
|
+
noProcess: (operator) => async (name) => {
|
|
49
|
+
const full = join(fixtureDir, name);
|
|
50
|
+
const [resolvedName, code] = await read(full);
|
|
51
|
+
const fix = true;
|
|
52
|
+
|
|
53
|
+
const [source] = await eslint({
|
|
54
|
+
name: resolvedName,
|
|
55
|
+
config,
|
|
56
|
+
code,
|
|
57
|
+
fix,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return operator.equal(source, code);
|
|
61
|
+
},
|
|
62
|
+
comparePlaces: (operator) => async (name, expected) => {
|
|
63
|
+
const full = join(fixtureDir, name);
|
|
64
|
+
const [resolvedName, code] = await read(full);
|
|
65
|
+
|
|
66
|
+
const [, places] = await eslint({
|
|
67
|
+
config,
|
|
68
|
+
name: resolvedName,
|
|
69
|
+
code,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return operator.deepEqual(places, expected);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
|
package/lib/test.js
CHANGED
|
@@ -18,15 +18,13 @@ const isString = (a) => typeof a === 'string';
|
|
|
18
18
|
const {isArray} = Array;
|
|
19
19
|
const {keys, entries} = Object;
|
|
20
20
|
|
|
21
|
-
const {UPDATE} = process.env;
|
|
22
|
-
global.__putout_test_update = UPDATE;
|
|
23
21
|
global.__putout_test_fs = {
|
|
24
22
|
readFileSync,
|
|
25
23
|
writeFileSync,
|
|
26
24
|
existsSync,
|
|
27
25
|
};
|
|
28
26
|
|
|
29
|
-
const isUpdate = () => UPDATE
|
|
27
|
+
const isUpdate = () => Boolean(Number(process.env.UPDATE));
|
|
30
28
|
|
|
31
29
|
const TS = {
|
|
32
30
|
ENABLED: true,
|
|
@@ -42,7 +40,10 @@ const readFixture = (name) => {
|
|
|
42
40
|
return [readFileSync(`${name}.js`, 'utf8'), TS.DISABLED];
|
|
43
41
|
};
|
|
44
42
|
|
|
45
|
-
module.exports =
|
|
43
|
+
module.exports = createTest;
|
|
44
|
+
module.exports.createTest = createTest;
|
|
45
|
+
|
|
46
|
+
function createTest(dir, plugin, rules) {
|
|
46
47
|
const update = isUpdate();
|
|
47
48
|
|
|
48
49
|
dir = join(dir, 'fixture');
|
|
@@ -75,7 +76,7 @@ module.exports = (dir, plugin, rules) => {
|
|
|
75
76
|
formatMany: (update ? formatManySave : formatMany)({dir, plugins, rules}),
|
|
76
77
|
noFormat: noFormat({dir, plugins, rules}),
|
|
77
78
|
});
|
|
78
|
-
}
|
|
79
|
+
}
|
|
79
80
|
|
|
80
81
|
const format = currify(({dir, plugins, rules}, t) => async (formatter, name, formatterOptions = {}) => {
|
|
81
82
|
const full = join(dir, name);
|
|
@@ -211,6 +212,8 @@ const formatSave = currify(({dir, plugins, rules}, t) => async (formatter, name,
|
|
|
211
212
|
});
|
|
212
213
|
|
|
213
214
|
const transform = currify(({dir, plugins, rules}, t, name, transformed = null, addons = {}) => {
|
|
215
|
+
const {writeFileSync} = global.__putout_test_fs;
|
|
216
|
+
|
|
214
217
|
const full = join(dir, name);
|
|
215
218
|
const [input, isTS] = readFixture(full);
|
|
216
219
|
const isStr = isString(transformed);
|
|
@@ -231,13 +234,15 @@ const transform = currify(({dir, plugins, rules}, t, name, transformed = null, a
|
|
|
231
234
|
}],
|
|
232
235
|
});
|
|
233
236
|
|
|
234
|
-
if (isUpdate())
|
|
237
|
+
if (isUpdate() && !isStr) {
|
|
235
238
|
writeFileSync(`${full}-fix.js`, code);
|
|
239
|
+
}
|
|
236
240
|
|
|
237
241
|
return t.equal(code, output);
|
|
238
242
|
});
|
|
239
243
|
|
|
240
244
|
const transformWithOptions = currify(({dir, plugins}, t, name, options) => {
|
|
245
|
+
const {writeFileSync} = global.__putout_test_fs;
|
|
241
246
|
const full = join(dir, name);
|
|
242
247
|
const [input, isTS] = readFixture(full);
|
|
243
248
|
|
|
@@ -404,11 +409,15 @@ function preTest(test, plugin) {
|
|
|
404
409
|
match,
|
|
405
410
|
}] = entries(plugin).pop();
|
|
406
411
|
|
|
412
|
+
const options = {
|
|
413
|
+
checkDuplicates: false,
|
|
414
|
+
};
|
|
415
|
+
|
|
407
416
|
if (rules) {
|
|
408
417
|
test(`${name}: rules is an object`, (t) => {
|
|
409
418
|
t.equal(typeof rules, 'object', 'should export "rules" object');
|
|
410
419
|
t.end();
|
|
411
|
-
},
|
|
420
|
+
}, options);
|
|
412
421
|
|
|
413
422
|
const entries = Object.entries(rules);
|
|
414
423
|
for (const [entryName, plugin] of entries) {
|
|
@@ -420,10 +429,6 @@ function preTest(test, plugin) {
|
|
|
420
429
|
return;
|
|
421
430
|
}
|
|
422
431
|
|
|
423
|
-
const options = {
|
|
424
|
-
checkDuplicates: false,
|
|
425
|
-
};
|
|
426
|
-
|
|
427
432
|
test(`${name}: report: is function`, (t) => {
|
|
428
433
|
t.equal(typeof report, 'function', 'should export "report" function');
|
|
429
434
|
t.end();
|
package/lib/test.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {dirname} from 'path';
|
|
2
|
+
import {fileURLToPath} from 'url';
|
|
3
|
+
import create from './test.js';
|
|
4
|
+
|
|
5
|
+
export default create;
|
|
6
|
+
|
|
7
|
+
export const createTest = (url, plugins) => {
|
|
8
|
+
const __filename = fileURLToPath(url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
|
|
11
|
+
return create(__dirname, plugins);
|
|
12
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@putout/test",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.4.0",
|
|
4
|
+
"type": "commonjs",
|
|
4
5
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
5
6
|
"description": "test runner for putout plugins ",
|
|
6
7
|
"homepage": "https://github.com/coderaiser/putout/tree/master/packages/test#readme",
|
|
@@ -9,8 +10,13 @@
|
|
|
9
10
|
"tape": "bin/test.mjs"
|
|
10
11
|
},
|
|
11
12
|
"exports": {
|
|
12
|
-
".":
|
|
13
|
-
|
|
13
|
+
".": {
|
|
14
|
+
"require": "./lib/test.js",
|
|
15
|
+
"import": "./lib/test.mjs"
|
|
16
|
+
},
|
|
17
|
+
"./processor": "./lib/processor/index.js",
|
|
18
|
+
"./formatter": "./lib/formatter/index.mjs",
|
|
19
|
+
"./eslint": "./lib/eslint/eslint.mjs"
|
|
14
20
|
},
|
|
15
21
|
"release": false,
|
|
16
22
|
"tag": false,
|
|
@@ -34,7 +40,8 @@
|
|
|
34
40
|
"currify": "^4.0.0",
|
|
35
41
|
"putout": "*",
|
|
36
42
|
"supertape": "^6.0.0",
|
|
37
|
-
"try-catch": "^3.0.0"
|
|
43
|
+
"try-catch": "^3.0.0",
|
|
44
|
+
"try-to-catch": "^3.0.0"
|
|
38
45
|
},
|
|
39
46
|
"keywords": [
|
|
40
47
|
"putout",
|
|
@@ -54,12 +61,11 @@
|
|
|
54
61
|
"c8": "^7.5.0",
|
|
55
62
|
"eslint": "^8.0.1",
|
|
56
63
|
"eslint-plugin-node": "^11.0.0",
|
|
57
|
-
"eslint-plugin-putout": "^
|
|
64
|
+
"eslint-plugin-putout": "^13.0.0",
|
|
58
65
|
"lerna": "^4.0.0",
|
|
59
66
|
"madrun": "^8.0.1",
|
|
60
67
|
"mock-require": "^3.0.3",
|
|
61
|
-
"nodemon": "^2.0.1"
|
|
62
|
-
"simport": "^1.2.0"
|
|
68
|
+
"nodemon": "^2.0.1"
|
|
63
69
|
},
|
|
64
70
|
"license": "MIT",
|
|
65
71
|
"engines": {
|