eslint-plugin-jest-formatting 0.1.0 → 1.2.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.
Files changed (39) hide show
  1. package/.eslintrc +5 -5
  2. package/CHANGELOG.md +28 -6
  3. package/README.md +29 -9
  4. package/docs/rules/padding-around-after-all-blocks.md +25 -0
  5. package/docs/rules/padding-around-after-each-blocks.md +29 -0
  6. package/docs/rules/padding-around-all.md +13 -0
  7. package/docs/rules/padding-around-before-all-blocks.md +29 -0
  8. package/docs/rules/padding-around-before-each-blocks.md +29 -0
  9. package/docs/rules/padding-around-describe-blocks.md +33 -0
  10. package/docs/rules/padding-around-expect-groups.md +35 -0
  11. package/docs/rules/padding-around-test-blocks.md +39 -0
  12. package/lib/ast-utils.js +40 -0
  13. package/lib/index.js +238 -38
  14. package/lib/rules/padding.js +130 -158
  15. package/package.json +4 -2
  16. package/src/ast-utils.ts +78 -0
  17. package/src/index.ts +282 -43
  18. package/src/rules/padding.ts +261 -252
  19. package/tests/catfood.js +39 -0
  20. package/tests/dogfood.spec.js +16 -1
  21. package/tests/lib/ast-utils.spec.ts +94 -0
  22. package/tests/lib/rules/padding-around-after-all-blocks.spec.js +114 -0
  23. package/tests/lib/rules/padding-around-after-each-blocks.spec.js +112 -0
  24. package/tests/lib/rules/padding-around-before-all-blocks.spec.js +114 -0
  25. package/tests/lib/rules/padding-around-before-each-blocks.spec.js +114 -0
  26. package/tests/lib/rules/padding-around-describe-blocks.spec.js +152 -0
  27. package/tests/lib/rules/padding-around-expect-groups.spec.js +154 -0
  28. package/tests/lib/rules/padding-around-test-blocks.spec.js +161 -0
  29. package/tests/lib/rules/padding-before-after-all-blocks.spec.js +1 -7
  30. package/tests/lib/rules/padding-before-after-each-blocks.spec.js +1 -7
  31. package/tests/lib/rules/padding-before-before-all-blocks.spec.js +1 -7
  32. package/tests/lib/rules/padding-before-before-each-blocks.spec.js +1 -7
  33. package/tests/lib/rules/padding-before-describe-blocks.spec.js +1 -7
  34. package/tests/lib/rules/padding-before-expect-statements.spec.js +1 -7
  35. package/tests/lib/rules/padding-before-test-blocks.spec.js +1 -7
  36. package/tsconfig.json +1 -1
  37. package/yarn.lock +12 -10
  38. package/lib/utils.js +0 -15
  39. package/src/utils.ts +0 -40
@@ -0,0 +1,78 @@
1
+ import { AST, SourceCode } from 'eslint';
2
+ import { Node } from 'estree';
3
+
4
+ export const isTokenASemicolon = (token: AST.Token): boolean =>
5
+ token.value === ';' && token.type === 'Punctuator';
6
+
7
+ export const areTokensOnSameLine = (
8
+ left: Node | AST.Token,
9
+ right: Node | AST.Token,
10
+ ): boolean => left.loc.end.line === right.loc.start.line;
11
+
12
+ // We'll only verify nodes with these parent types
13
+ const STATEMENT_LIST_PARENTS = new Set([
14
+ 'Program',
15
+ 'BlockStatement',
16
+ 'SwitchCase',
17
+ 'SwitchStatement',
18
+ ]);
19
+
20
+ export const isValidParent = (parentType: string): boolean => {
21
+ return STATEMENT_LIST_PARENTS.has(parentType);
22
+ };
23
+
24
+ /**
25
+ * Gets the actual last token.
26
+ *
27
+ * If a semicolon is semicolon-less style's semicolon, this ignores it.
28
+ * For example:
29
+ *
30
+ * foo()
31
+ * ;[1, 2, 3].forEach(bar)
32
+ */
33
+ export const getActualLastToken = (
34
+ sourceCode: SourceCode,
35
+ node: Node,
36
+ ): AST.Token => {
37
+ const semiToken = sourceCode.getLastToken(node);
38
+ const prevToken = sourceCode.getTokenBefore(semiToken);
39
+ const nextToken = sourceCode.getTokenAfter(semiToken);
40
+ const isSemicolonLessStyle = Boolean(
41
+ prevToken &&
42
+ nextToken &&
43
+ prevToken.range[0] >= node.range[0] &&
44
+ isTokenASemicolon(semiToken) &&
45
+ semiToken.loc.start.line !== prevToken.loc.end.line &&
46
+ semiToken.loc.end.line === nextToken.loc.start.line,
47
+ );
48
+
49
+ return isSemicolonLessStyle ? prevToken : semiToken;
50
+ };
51
+
52
+ /**
53
+ * Gets padding line sequences between the given 2 statements.
54
+ * Comments are separators of the padding line sequences.
55
+ */
56
+ export const getPaddingLineSequences = (
57
+ prevNode: Node,
58
+ nextNode: Node,
59
+ sourceCode: SourceCode,
60
+ ): AST.Token[][] => {
61
+ const pairs: AST.Token[][] = [];
62
+ const includeComments = true;
63
+ let prevToken = getActualLastToken(sourceCode, prevNode);
64
+
65
+ if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) {
66
+ do {
67
+ const token = sourceCode.getTokenAfter(prevToken, { includeComments });
68
+
69
+ if (token.loc.start.line - prevToken.loc.end.line >= 2) {
70
+ pairs.push([prevToken, token]);
71
+ }
72
+
73
+ prevToken = token;
74
+ } while (prevToken.range[0] < nextNode.range[0]);
75
+ }
76
+
77
+ return pairs;
78
+ };
package/src/index.ts CHANGED
@@ -3,50 +3,289 @@
3
3
  * @author Dan
4
4
  */
5
5
 
6
- import { makeRule } from './utils';
6
+ import {
7
+ Config,
8
+ createRule,
9
+ PaddingType,
10
+ StatementType,
11
+ } from './rules/padding';
7
12
 
8
- //------------------------------------------------------------------------------
9
- // Plugin Definition
10
- //------------------------------------------------------------------------------
11
-
12
- export const rules = {
13
- 'padding-before-after-all-blocks': makeRule([
14
- { blankLine: 'always', prev: '*', next: 'afterAll' },
15
- ]),
16
- 'padding-before-after-each-blocks': makeRule([
17
- { blankLine: 'always', prev: '*', next: 'afterEach' },
18
- ]),
19
- 'padding-before-before-all-blocks': makeRule([
20
- { blankLine: 'always', prev: '*', next: 'beforeAll' },
21
- ]),
22
- 'padding-before-before-each-blocks': makeRule([
23
- { blankLine: 'always', prev: '*', next: 'beforeEach' },
24
- ]),
25
- 'padding-before-describe-blocks': makeRule([
26
- { blankLine: 'always', prev: '*', next: 'describe' },
27
- ]),
28
- 'padding-before-expect-statements': makeRule([
29
- { blankLine: 'always', prev: '*', next: 'expect' },
30
- { blankLine: 'any', prev: 'expect', next: 'expect' },
31
- ]),
32
- 'padding-before-test-blocks': makeRule([
33
- { blankLine: 'always', prev: '*', next: ['test', 'it'] },
34
- ]),
35
- 'padding-before-all': makeRule([
36
- {
37
- blankLine: 'always',
38
- prev: '*',
39
- next: [
40
- 'afterAll',
41
- 'afterEach',
42
- 'beforeAll',
43
- 'beforeEach',
44
- 'describe',
45
- 'expect',
46
- 'it',
47
- 'test',
13
+ const paddingConfigs: { [name: string]: Config[] } = {
14
+ afterAll: [
15
+ {
16
+ paddingType: PaddingType.Always,
17
+ prevStatementType: StatementType.Any,
18
+ nextStatementType: StatementType.AfterAllToken,
19
+ },
20
+ {
21
+ paddingType: PaddingType.Always,
22
+ prevStatementType: StatementType.AfterAllToken,
23
+ nextStatementType: StatementType.Any,
24
+ },
25
+ ],
26
+ afterEach: [
27
+ {
28
+ paddingType: PaddingType.Always,
29
+ prevStatementType: StatementType.Any,
30
+ nextStatementType: StatementType.AfterEachToken,
31
+ },
32
+ {
33
+ paddingType: PaddingType.Always,
34
+ prevStatementType: StatementType.AfterEachToken,
35
+ nextStatementType: StatementType.Any,
36
+ },
37
+ ],
38
+ beforeAll: [
39
+ {
40
+ paddingType: PaddingType.Always,
41
+ prevStatementType: StatementType.Any,
42
+ nextStatementType: StatementType.BeforeAllToken,
43
+ },
44
+ {
45
+ paddingType: PaddingType.Always,
46
+ prevStatementType: StatementType.BeforeAllToken,
47
+ nextStatementType: StatementType.Any,
48
+ },
49
+ ],
50
+ beforeEach: [
51
+ {
52
+ paddingType: PaddingType.Always,
53
+ prevStatementType: StatementType.Any,
54
+ nextStatementType: StatementType.BeforeEachToken,
55
+ },
56
+ {
57
+ paddingType: PaddingType.Always,
58
+ prevStatementType: StatementType.BeforeEachToken,
59
+ nextStatementType: StatementType.Any,
60
+ },
61
+ ],
62
+ describe: [
63
+ {
64
+ paddingType: PaddingType.Always,
65
+ prevStatementType: StatementType.Any,
66
+ nextStatementType: [
67
+ StatementType.DescribeToken,
68
+ StatementType.FdescribeToken,
69
+ StatementType.XdescribeToken,
70
+ ],
71
+ },
72
+ {
73
+ paddingType: PaddingType.Always,
74
+ prevStatementType: [
75
+ StatementType.DescribeToken,
76
+ StatementType.FdescribeToken,
77
+ StatementType.XdescribeToken,
78
+ ],
79
+ nextStatementType: StatementType.Any,
80
+ },
81
+ ],
82
+ expect: [
83
+ {
84
+ paddingType: PaddingType.Always,
85
+ prevStatementType: StatementType.Any,
86
+ nextStatementType: StatementType.ExpectToken,
87
+ },
88
+ {
89
+ paddingType: PaddingType.Always,
90
+ prevStatementType: StatementType.ExpectToken,
91
+ nextStatementType: StatementType.Any,
92
+ },
93
+ {
94
+ paddingType: PaddingType.Any,
95
+ prevStatementType: StatementType.ExpectToken,
96
+ nextStatementType: StatementType.ExpectToken,
97
+ },
98
+ ],
99
+ test: [
100
+ {
101
+ paddingType: PaddingType.Always,
102
+ prevStatementType: StatementType.Any,
103
+ nextStatementType: [
104
+ StatementType.TestToken,
105
+ StatementType.ItToken,
106
+ StatementType.FitToken,
107
+ StatementType.XitToken,
108
+ StatementType.XtestToken,
48
109
  ],
49
110
  },
50
- { blankLine: 'any', prev: 'expect', next: 'expect' },
51
- ]),
111
+ {
112
+ paddingType: PaddingType.Always,
113
+ prevStatementType: [
114
+ StatementType.TestToken,
115
+ StatementType.ItToken,
116
+ StatementType.FitToken,
117
+ StatementType.XitToken,
118
+ StatementType.XtestToken,
119
+ ],
120
+ nextStatementType: StatementType.Any,
121
+ },
122
+ ],
123
+ };
124
+
125
+ export const rules = {
126
+ 'padding-around-after-all-blocks': createRule(paddingConfigs.afterAll),
127
+ 'padding-around-after-each-blocks': createRule(paddingConfigs.afterEach),
128
+ 'padding-around-before-all-blocks': createRule(paddingConfigs.beforeAll),
129
+ 'padding-around-before-each-blocks': createRule(paddingConfigs.beforeEach),
130
+ 'padding-around-describe-blocks': createRule(paddingConfigs.describe),
131
+ 'padding-around-expect-groups': createRule(paddingConfigs.expect),
132
+ 'padding-around-test-blocks': createRule(paddingConfigs.test),
133
+ 'padding-around-all': createRule(
134
+ [].concat(...Object.keys(paddingConfigs).map(k => paddingConfigs[k])),
135
+ ),
136
+
137
+ // ===========================================================================
138
+ // DEPRECATED
139
+ 'padding-before-after-all-blocks': createRule(
140
+ [
141
+ {
142
+ paddingType: PaddingType.Always,
143
+ prevStatementType: StatementType.Any,
144
+ nextStatementType: StatementType.AfterAllToken,
145
+ },
146
+ ],
147
+ true,
148
+ ),
149
+ // DEPRECATED
150
+ 'padding-before-after-each-blocks': createRule(
151
+ [
152
+ {
153
+ paddingType: PaddingType.Always,
154
+ prevStatementType: StatementType.Any,
155
+ nextStatementType: StatementType.AfterEachToken,
156
+ },
157
+ ],
158
+ true,
159
+ ),
160
+ // DEPRECATED
161
+ 'padding-before-before-all-blocks': createRule(
162
+ [
163
+ {
164
+ paddingType: PaddingType.Always,
165
+ prevStatementType: StatementType.Any,
166
+ nextStatementType: StatementType.BeforeAllToken,
167
+ },
168
+ ],
169
+ true,
170
+ ),
171
+ // DEPRECATED
172
+ 'padding-before-before-each-blocks': createRule(
173
+ [
174
+ {
175
+ paddingType: PaddingType.Always,
176
+ prevStatementType: StatementType.Any,
177
+ nextStatementType: StatementType.BeforeEachToken,
178
+ },
179
+ ],
180
+ true,
181
+ ),
182
+ // DEPRECATED
183
+ 'padding-before-describe-blocks': createRule(
184
+ [
185
+ {
186
+ paddingType: PaddingType.Always,
187
+ prevStatementType: StatementType.Any,
188
+ nextStatementType: StatementType.DescribeToken,
189
+ },
190
+ ],
191
+ true,
192
+ ),
193
+ // DEPRECATED
194
+ 'padding-before-expect-statements': createRule(
195
+ [
196
+ {
197
+ paddingType: PaddingType.Always,
198
+ prevStatementType: StatementType.Any,
199
+ nextStatementType: StatementType.ExpectToken,
200
+ },
201
+ {
202
+ paddingType: PaddingType.Any,
203
+ prevStatementType: StatementType.ExpectToken,
204
+ nextStatementType: StatementType.ExpectToken,
205
+ },
206
+ ],
207
+ true,
208
+ ),
209
+ // DEPRECATED
210
+ 'padding-before-test-blocks': createRule(
211
+ [
212
+ {
213
+ paddingType: PaddingType.Always,
214
+ prevStatementType: StatementType.Any,
215
+ nextStatementType: [StatementType.TestToken, StatementType.ItToken],
216
+ },
217
+ ],
218
+ true,
219
+ ),
220
+ // DEPRECATED
221
+ 'padding-before-all': createRule(
222
+ [
223
+ {
224
+ paddingType: PaddingType.Always,
225
+ prevStatementType: StatementType.Any,
226
+ nextStatementType: [
227
+ StatementType.AfterAllToken,
228
+ StatementType.AfterEachToken,
229
+ StatementType.BeforeAllToken,
230
+ StatementType.BeforeEachToken,
231
+ StatementType.DescribeToken,
232
+ StatementType.ExpectToken,
233
+ StatementType.ItToken,
234
+ StatementType.TestToken,
235
+ ],
236
+ },
237
+ {
238
+ paddingType: PaddingType.Any,
239
+ prevStatementType: StatementType.ExpectToken,
240
+ nextStatementType: StatementType.ExpectToken,
241
+ },
242
+ ],
243
+ true,
244
+ ),
245
+ };
246
+
247
+ export const configs = {
248
+ recommended: {
249
+ plugins: ['jest-formatting'],
250
+ overrides: [
251
+ {
252
+ files: [
253
+ '**/*.test.*',
254
+ '**/*_test.*',
255
+ '**/*Test.*',
256
+ '**/*.spec.*',
257
+ '**/*_spec.*',
258
+ '**/*Spec.*',
259
+ '**/__tests__/*',
260
+ ],
261
+ rules: {
262
+ 'jest-formatting/padding-around-after-all-blocks': 2,
263
+ 'jest-formatting/padding-around-after-each-blocks': 2,
264
+ 'jest-formatting/padding-around-before-all-blocks': 2,
265
+ 'jest-formatting/padding-around-before-each-blocks': 2,
266
+ 'jest-formatting/padding-around-describe-blocks': 2,
267
+ 'jest-formatting/padding-around-test-blocks': 2,
268
+ },
269
+ },
270
+ ],
271
+ },
272
+ strict: {
273
+ plugins: ['jest-formatting'],
274
+ overrides: [
275
+ {
276
+ files: [
277
+ '**/*.test.*',
278
+ '**/*_test.*',
279
+ '**/*Test.*',
280
+ '**/*.spec.*',
281
+ '**/*_spec.*',
282
+ '**/*Spec.*',
283
+ '**/__tests__/*',
284
+ ],
285
+ rules: {
286
+ 'jest-formatting/padding-around-all': 2,
287
+ },
288
+ },
289
+ ],
290
+ },
52
291
  };