@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 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 [🐊`Putout`](https://github.com/coderaiser/putout#plugins-api). Basically it is [supercharged `tape`](https://github.com/coderaiser/supertape) with aditional asseritions:
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 test = require('@putout/test')(__dirname, {
207
- 'remove-console': require('..'),
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 || global.__putout_test_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 = (dir, plugin, rules) => {
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
- }, {checkDuplicates: false});
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.1",
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
- ".": "./lib/test.js",
13
- "./processor": "./lib/processor/index.js"
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": "^12.0.0",
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": {