@putout/test 4.0.0 → 4.3.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,7 +21,22 @@ UPDATE=1 tape test/*.js
21
21
 
22
22
  ## Plugins API
23
23
 
24
- ### report(filename, message | []messages)
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
+
39
+ ### `report(filename, message | []messages)`
25
40
 
26
41
  checks error message (or messages) of a plugin
27
42
 
@@ -32,7 +47,7 @@ test('remove usless variables: for-of', (t) => {
32
47
  });
33
48
  ```
34
49
 
35
- ### reportCode(input, message)
50
+ ### `reportCode(input, message)`
36
51
 
37
52
  checks error message of a plugin from `input` code
38
53
 
@@ -43,7 +58,7 @@ test('remove debugger: report', (t) => {
43
58
  });
44
59
  ```
45
60
 
46
- ### transform(filename [, output, plugins])
61
+ ### `transform(filename [, output, plugins])`
47
62
 
48
63
  check transform of `filename.js` -> `filename-fix.js` in `test/fixtures` directory
49
64
 
@@ -56,7 +71,7 @@ test('remove usless variables: for-of', (t) => {
56
71
  });
57
72
  ```
58
73
 
59
- ### transformCode(input, output)
74
+ ### `transformCode(input, output)`
60
75
 
61
76
  check transform of `input` -> `output` code
62
77
 
@@ -67,7 +82,7 @@ test('remove-console: property identifier: code', (t) => {
67
82
  });
68
83
  ```
69
84
 
70
- ### reportWithOptions(filename, options)
85
+ ### `reportWithOptions(filename, options)`
71
86
 
72
87
  check report of `filename.js` with `options`
73
88
 
@@ -83,7 +98,7 @@ test('putout: test: reportWithOptions', (t) => {
83
98
  });
84
99
  ```
85
100
 
86
- ### noReportWithOptions(filename, options)
101
+ ### `noReportWithOptions(filename, options)`
87
102
 
88
103
  check no report of `filename.js` with `options`
89
104
 
@@ -98,7 +113,7 @@ test('putout: test: noReportWithOptions', (t) => {
98
113
  });
99
114
  ```
100
115
 
101
- ### transformWithOptions(filename, options)
116
+ ### `transformWithOptions(filename, options)`
102
117
 
103
118
  check transform of `filename.js` with `options`
104
119
 
@@ -111,7 +126,7 @@ test('putout: plugin: declare-undefined-variables: transform: parse', (t) => {
111
126
  });
112
127
  ```
113
128
 
114
- ### noTransformWithOptions(filename, options)
129
+ ### `noTransformWithOptions(filename, options)`
115
130
 
116
131
  When file should not be transformed:
117
132
 
@@ -122,7 +137,7 @@ test('test: declared', (t) => {
122
137
  });
123
138
  ```
124
139
 
125
- ### noTransformWithOptions(filename, options)
140
+ ### `noTransformWithOptions(filename, options)`
126
141
 
127
142
  check transform of `filename.js` with `options`
128
143
 
@@ -135,7 +150,7 @@ test('putout: plugin: declare-undefined-variables: transform: assign: dismiss',
135
150
  });
136
151
  ```
137
152
 
138
- ### noReport(filename)
153
+ ### `noReport(filename)`
139
154
 
140
155
  checks error message of a plugin not produces
141
156
 
@@ -146,9 +161,9 @@ test('plugin-putout: check-replace-code: no report: typescript', (t) => {
146
161
  });
147
162
  ```
148
163
 
149
- ### noReportAfterTransform(filename)
164
+ ### `noReportAfterTransform(filename)`
150
165
 
151
- checks error message of a plugin not produces
166
+ checks error message of a plugin not produced
152
167
 
153
168
  ```js
154
169
  test('test: no report after transform', (t) => {
@@ -157,9 +172,9 @@ test('test: no report after transform', (t) => {
157
172
  });
158
173
  ```
159
174
 
160
- ### noTransform(filename)
175
+ ### `noTransform(filename)`
161
176
 
162
- check transform of `filename.js` produce nothing new
177
+ check transform of `filename.js` produce nothing
163
178
 
164
179
  ```js
165
180
  test('plugin-apply-numeric-separators: no transform: hex', (t) => {
@@ -168,7 +183,20 @@ test('plugin-apply-numeric-separators: no transform: hex', (t) => {
168
183
  });
169
184
  ```
170
185
 
171
- ### format(formatter, filename)
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
+
199
+ ### `format(formatter, filename)`
172
200
 
173
201
  check file name formatting (pass `process.env.UPDATE=1` to save fixture)
174
202
 
@@ -178,7 +206,7 @@ test('formatter: codeframe', async ({format}) => {
178
206
  });
179
207
  ```
180
208
 
181
- ### noFormat
209
+ ### `noFormat`
182
210
 
183
211
  check that there is no formatting for for such file
184
212
 
@@ -188,7 +216,7 @@ test('formatter: codeframe: no', async ({noFormat}) => {
188
216
  });
189
217
  ```
190
218
 
191
- ### formatMany(formatter, [filename1, filename2])
219
+ ### `formatMany(formatter, [filename1, filename2])`
192
220
 
193
221
  check file name formatting (pass `process.env.UPDATE=1` to save fixture)
194
222
 
@@ -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,64 @@ 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
+ Example:
270
+
271
+ ```js
272
+ test('test: eslint: transform', async ({process}) => {
273
+ await process('operator-linebreak');
274
+ });
275
+
276
+ test('test: eslint: transform', async ({process}) => {
277
+ await process('operator-linebreak', {
278
+ rules: {
279
+ 'putout/putout': {
280
+ rules: {
281
+ 'convert-esm-to-commonjs': 'on',
282
+ },
283
+ },
284
+ },
285
+ });
286
+ });
287
+ ```
288
+
289
+ ### `noProcess(filename)`
290
+
291
+ Check that filename would not be processed.
292
+
293
+ Example:
294
+
295
+ ```js
296
+ test('test: eslint: noProcess', async ({noProcess}) => {
297
+ await noProcess('operator-linebreak-fix');
298
+ });
299
+ ```
300
+
301
+ ### `comparePlaces(filename, places)`
302
+
303
+ ```js
304
+ test('eslint-config: operator-line-break', async ({comparePlaces}) => {
305
+ await comparePlaces('operator-linebreak', [{
306
+ "message": "There should be no line break before or after '='.",
307
+ "position": {
308
+ "column": 1,
309
+ "line": 2,
310
+ },
311
+ "rule": "operator-linebreak (eslint)",
312
+ }]);
313
+ });
314
+ ```
315
+
227
316
  ## Processors API
228
317
 
229
318
  With `processors api` you can test `processors` in a simplest possible way.
@@ -245,7 +334,7 @@ const test = createTest(__dirname, {
245
334
 
246
335
  ```
247
336
 
248
- ### process(filename [, plugins, ])
337
+ ### `process(filename [, plugins, ])`
249
338
 
250
339
  Example:
251
340
 
@@ -259,7 +348,7 @@ test('putout: processor: json', async ({process}) => {
259
348
  });
260
349
  ```
261
350
 
262
- ### noProcess(filename [, plugins, processors])
351
+ ### `noProcess(filename [, plugins, processors])`
263
352
 
264
353
  Check that filename would not be processed.
265
354
 
@@ -271,7 +360,7 @@ test('putout: process: json: no process', async ({noProcess}) => {
271
360
  });
272
361
  ```
273
362
 
274
- ### comparePlaces(filename, places)
363
+ ### `comparePlaces(filename, places)`
275
364
 
276
365
  ```js
277
366
  test('putout: processor: css: places', async ({comparePlaces}) => {
@@ -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,7 +18,14 @@ const isString = (a) => typeof a === 'string';
18
18
  const {isArray} = Array;
19
19
  const {keys, entries} = Object;
20
20
 
21
- const {UPDATE} = process.env;
21
+ global.__putout_test_fs = {
22
+ readFileSync,
23
+ writeFileSync,
24
+ existsSync,
25
+ };
26
+
27
+ const isUpdate = () => Boolean(Number(process.env.UPDATE));
28
+
22
29
  const TS = {
23
30
  ENABLED: true,
24
31
  DISABLED: false,
@@ -33,7 +40,12 @@ const readFixture = (name) => {
33
40
  return [readFileSync(`${name}.js`, 'utf8'), TS.DISABLED];
34
41
  };
35
42
 
36
- module.exports = (dir, plugin, rules) => {
43
+ module.exports = createTest;
44
+ module.exports.createTest = createTest;
45
+
46
+ function createTest(dir, plugin, rules) {
47
+ const update = isUpdate();
48
+
37
49
  dir = join(dir, 'fixture');
38
50
  const plugins = getPlugins(plugin);
39
51
 
@@ -59,12 +71,12 @@ module.exports = (dir, plugin, rules) => {
59
71
  }),
60
72
 
61
73
  formatSave: formatSave({dir, plugins, rules}),
62
- format: (UPDATE ? formatSave : format)({dir, plugins, rules}),
74
+ format: (update ? formatSave : format)({dir, plugins, rules}),
63
75
  formatManySave: formatManySave({dir, plugins, rules}),
64
- formatMany: (UPDATE ? formatManySave : formatMany)({dir, plugins, rules}),
76
+ formatMany: (update ? formatManySave : formatMany)({dir, plugins, rules}),
65
77
  noFormat: noFormat({dir, plugins, rules}),
66
78
  });
67
- };
79
+ }
68
80
 
69
81
  const format = currify(({dir, plugins, rules}, t) => async (formatter, name, formatterOptions = {}) => {
70
82
  const full = join(dir, name);
@@ -143,6 +155,11 @@ const formatMany = currify(({dir, plugins, rules}, t) => async (formatter, names
143
155
  });
144
156
 
145
157
  const formatManySave = currify(({dir, plugins, rules}, t) => async (formatter, names, options = {}) => {
158
+ const {
159
+ existsSync,
160
+ writeFileSync,
161
+ } = global.__putout_test_fs;
162
+
146
163
  const name = `${names.join('-')}-format.js`;
147
164
  const outputName = join(dir, name);
148
165
 
@@ -163,6 +180,11 @@ const formatManySave = currify(({dir, plugins, rules}, t) => async (formatter, n
163
180
  });
164
181
 
165
182
  const formatSave = currify(({dir, plugins, rules}, t) => async (formatter, name, options = {}) => {
183
+ const {
184
+ existsSync,
185
+ writeFileSync,
186
+ } = global.__putout_test_fs;
187
+
166
188
  const full = join(dir, name);
167
189
  const outputName = `${full}-format.js`;
168
190
 
@@ -190,6 +212,8 @@ const formatSave = currify(({dir, plugins, rules}, t) => async (formatter, name,
190
212
  });
191
213
 
192
214
  const transform = currify(({dir, plugins, rules}, t, name, transformed = null, addons = {}) => {
215
+ const {writeFileSync} = global.__putout_test_fs;
216
+
193
217
  const full = join(dir, name);
194
218
  const [input, isTS] = readFixture(full);
195
219
  const isStr = isString(transformed);
@@ -210,13 +234,15 @@ const transform = currify(({dir, plugins, rules}, t, name, transformed = null, a
210
234
  }],
211
235
  });
212
236
 
213
- if (UPDATE)
237
+ if (isUpdate() && !isStr) {
214
238
  writeFileSync(`${full}-fix.js`, code);
239
+ }
215
240
 
216
241
  return t.equal(code, output);
217
242
  });
218
243
 
219
244
  const transformWithOptions = currify(({dir, plugins}, t, name, options) => {
245
+ const {writeFileSync} = global.__putout_test_fs;
220
246
  const full = join(dir, name);
221
247
  const [input, isTS] = readFixture(full);
222
248
 
@@ -230,7 +256,7 @@ const transformWithOptions = currify(({dir, plugins}, t, name, options) => {
230
256
 
231
257
  const {code} = putout(input, {isTS, plugins, rules});
232
258
 
233
- if (UPDATE)
259
+ if (isUpdate())
234
260
  writeFileSync(`${full}-fix.js`, code);
235
261
 
236
262
  return t.equal(code, output);
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.0",
3
+ "version": "4.3.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,7 +61,7 @@
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",