@atlaskit/eslint-plugin-platform 0.0.5 → 0.0.7

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.
@@ -0,0 +1,308 @@
1
+ import { tester } from '../../../../__tests__/utils/_tester';
2
+ import rule from '../../index';
3
+
4
+ describe('Warning about too many nested test runners', () => {
5
+ tester.run('ensure-test-runner-nested-count', rule, {
6
+ valid: [
7
+ {
8
+ code: `describe('1 FF', () => {
9
+ ffTest('uip.sample.color', () => {
10
+ const { getByText } = render(<SampleComponent />);
11
+ expect(getByText('SampleComponent')).toBeDefined();
12
+ });
13
+ });`,
14
+ },
15
+ {
16
+ code: `describe('2 FFs', () => {
17
+ ffTest(
18
+ 'uip.sample.color',
19
+ ff =>
20
+ ffTest(
21
+ 'uip.sample.backgroundColor',
22
+ () => {
23
+ expect(getByText('SampleComponent')).toHaveStyle('color: red');
24
+ },
25
+ () => {
26
+ expect(getByText('SampleComponent')).toHaveStyle('color: red');
27
+ },
28
+ ff,
29
+ ),
30
+ ff =>
31
+ ffTest(
32
+ 'uip.sample.backgroundColor',
33
+ () => {
34
+ expect(getByText('SampleComponent')).toHaveStyle('color: blue');
35
+ },
36
+ () => {
37
+ expect(getByText('SampleComponent')).toHaveStyle('color: blue');
38
+ },
39
+ ff,
40
+ ),
41
+ );
42
+ });`,
43
+ },
44
+ {
45
+ code: `ffTest(
46
+ 'uip.sample.color',
47
+ (ff) =>
48
+ ffTest(
49
+ 'uip.sample.backgroundColor',
50
+ () => {},
51
+ () => {},
52
+ ff,
53
+ ),
54
+ (ff) =>
55
+ ffTest(
56
+ 'uip.sample.backgroundColor',
57
+ () => {},
58
+ () => {},
59
+ ff,
60
+ ),
61
+ );`,
62
+ },
63
+ {
64
+ code: `ffTest(
65
+ 'uip.sample.color',
66
+ (ff) =>
67
+ ffTest(
68
+ 'uip.sample.backgroundColor',
69
+ (ff) =>
70
+ ffTest(
71
+ 'uip.sample.display',
72
+ () => {},
73
+ () => {},
74
+ ff,
75
+ ),
76
+ (ff) =>
77
+ ffTest(
78
+ 'uip.sample.display',
79
+ () => {},
80
+ () => {},
81
+ ff,
82
+ ),
83
+ ff,
84
+ ),
85
+ (ff) =>
86
+ ffTest(
87
+ 'uip.sample.backgroundColor',
88
+ () => {},
89
+ (ff) =>
90
+ ffTest(
91
+ 'uip.sample.display',
92
+ () => {},
93
+ () => {},
94
+ ff,
95
+ ),
96
+ ff,
97
+ ),
98
+ );`,
99
+ },
100
+ {
101
+ code: `
102
+ ffTest(
103
+ 'uip.sample.color',
104
+ (ff) =>
105
+ ffTest(
106
+ 'uip.sample.backgroundColor',
107
+ (ff) =>
108
+ ffTest(
109
+ 'uip.sample.display',
110
+ () => {},
111
+ () => {},
112
+ ff,
113
+ ),
114
+ (ff) =>
115
+ ffTest(
116
+ 'uip.sample.display',
117
+ () => {},
118
+ () => {},
119
+ ff,
120
+ ),
121
+ ff,
122
+ ),
123
+ (ff) =>
124
+ ffTest(
125
+ 'uip.sample.backgroundColor',
126
+ (ff) =>
127
+ ffTest(
128
+ 'uip.sample.display',
129
+ (ff) =>
130
+ ffTest(
131
+ 'uip.sample.opacity',
132
+ () => {},
133
+ () => {},
134
+ ff,
135
+ ),
136
+ () => {},
137
+ ff,
138
+ ),
139
+ (ff) =>
140
+ ffTest(
141
+ 'uip.sample.display',
142
+ () => {},
143
+ (ff) =>
144
+ ffTest(
145
+ 'uip.sample.opacity',
146
+ () => {},
147
+ () => {},
148
+ ff,
149
+ ),
150
+ ff,
151
+ ),
152
+ ff,
153
+ ),
154
+ );`,
155
+ },
156
+ ],
157
+ invalid: [
158
+ {
159
+ code: `
160
+ describe('5 FFs', () => {
161
+ ffTest(
162
+ 'uip.sample.color',
163
+ (ff) =>
164
+ ffTest(
165
+ 'uip.sample.backgroundColor',
166
+ (ff) =>
167
+ ffTest(
168
+ 'uip.sample.display',
169
+ () => {},
170
+ () => {},
171
+ ff,
172
+ ),
173
+ (ff) =>
174
+ ffTest(
175
+ 'uip.sample.display',
176
+ () => {},
177
+ () => {},
178
+ ff,
179
+ ),
180
+ ff,
181
+ ),
182
+ (ff) =>
183
+ ffTest(
184
+ 'uip.sample.backgroundColor',
185
+ (ff) =>
186
+ ffTest(
187
+ 'uip.sample.display',
188
+ (ff) =>
189
+ ffTest(
190
+ 'uip.sample.opacity',
191
+ (ff) =>
192
+ ffTest(
193
+ 'uip.sample.font',
194
+ () => {},
195
+ () => {},
196
+ ff,
197
+ ),
198
+ () => {},
199
+ ff,
200
+ ),
201
+ () => {},
202
+ ff,
203
+ ),
204
+ (ff) =>
205
+ ffTest(
206
+ 'uip.sample.display',
207
+ () => {},
208
+ (ff) =>
209
+ ffTest(
210
+ 'uip.sample.opacity',
211
+ () => {},
212
+ () => {},
213
+ ff,
214
+ ),
215
+ ff,
216
+ ),
217
+ ff,
218
+ ),
219
+ );
220
+ });`,
221
+ errors: [
222
+ {
223
+ messageId: 'tooManyNestedTestRunner',
224
+ data: {
225
+ nestedTestRunner: 5,
226
+ },
227
+ },
228
+ ],
229
+ },
230
+ {
231
+ code: `
232
+ ffTest(
233
+ 'uip.sample.color',
234
+ (ff) =>
235
+ ffTest(
236
+ 'uip.sample.backgroundColor',
237
+ (ff) =>
238
+ ffTest(
239
+ 'uip.sample.display',
240
+ () => {},
241
+ () => {},
242
+ ff,
243
+ ),
244
+ (ff) =>
245
+ ffTest(
246
+ 'uip.sample.display',
247
+ () => {},
248
+ () => {},
249
+ ff,
250
+ ),
251
+ ff,
252
+ ),
253
+ (ff) =>
254
+ ffTest(
255
+ 'uip.sample.backgroundColor',
256
+ (ff) =>
257
+ ffTest(
258
+ 'uip.sample.display',
259
+ (ff) =>
260
+ ffTest(
261
+ 'uip.sample.opacity',
262
+ (ff) =>
263
+ ffTest(
264
+ 'uip.sample.font',
265
+ (ff) =>
266
+ ffTest(
267
+ 'uip.sample.border',
268
+ () => {},
269
+ () => {},
270
+ ff,
271
+ ),
272
+ () => {},
273
+ ff,
274
+ ),
275
+ () => {},
276
+ ff,
277
+ ),
278
+ () => {},
279
+ ff,
280
+ ),
281
+ (ff) =>
282
+ ffTest(
283
+ 'uip.sample.display',
284
+ () => {},
285
+ (ff) =>
286
+ ffTest(
287
+ 'uip.sample.opacity',
288
+ () => {},
289
+ () => {},
290
+ ff,
291
+ ),
292
+ ff,
293
+ ),
294
+ ff,
295
+ ),
296
+ );`,
297
+ errors: [
298
+ {
299
+ messageId: 'tooManyNestedTestRunner',
300
+ data: {
301
+ nestedTestRunner: 6,
302
+ },
303
+ },
304
+ ],
305
+ },
306
+ ],
307
+ });
308
+ });
@@ -0,0 +1,83 @@
1
+ import type { Rule } from 'eslint';
2
+ import type { SimpleCallExpression } from 'estree';
3
+
4
+ const NESTED_LIMIT: number = 4;
5
+ const TEST_RUNNER_IDENTIFIER = 'ffTest' as const;
6
+
7
+ const getDepthOfNestedRunner = (
8
+ node: SimpleCallExpression & Rule.NodeParentExtension,
9
+ ): number => {
10
+ // Calculate the depth of a binary tree, using a queue to track path
11
+ let queue: typeof node[] = [];
12
+ queue.push(node);
13
+ let depth = 0;
14
+ while (queue.length > 0) {
15
+ let nodeCount = queue.length;
16
+ while (nodeCount > 0) {
17
+ let currentNode = queue.shift() as typeof node;
18
+ if (
19
+ currentNode.arguments[1].type === 'ArrowFunctionExpression' &&
20
+ currentNode.arguments[1].body.type === 'CallExpression' &&
21
+ currentNode.arguments[1].body.callee.type === 'Identifier' &&
22
+ currentNode.arguments[1].body.callee.name === TEST_RUNNER_IDENTIFIER
23
+ ) {
24
+ queue.push({
25
+ ...currentNode.arguments[1].body,
26
+ parent: currentNode.parent,
27
+ });
28
+ }
29
+ if (
30
+ currentNode.arguments[2]?.type === 'ArrowFunctionExpression' &&
31
+ currentNode.arguments[2].body.type === 'CallExpression' &&
32
+ currentNode.arguments[2].body.callee.type === 'Identifier' &&
33
+ currentNode.arguments[2].body.callee.name === TEST_RUNNER_IDENTIFIER
34
+ ) {
35
+ queue.push({
36
+ ...currentNode.arguments[2].body,
37
+ parent: currentNode.parent,
38
+ });
39
+ }
40
+ nodeCount--;
41
+ }
42
+ depth++;
43
+ }
44
+ return depth;
45
+ };
46
+
47
+ const rule: Rule.RuleModule = {
48
+ meta: {
49
+ docs: {
50
+ recommended: false,
51
+ },
52
+ type: 'problem',
53
+ messages: {
54
+ tooManyNestedTestRunner:
55
+ '{{nestedTestRunner}} test runners are nested. Feature flags may need a clean-up',
56
+ },
57
+ },
58
+ create(context) {
59
+ return {
60
+ // Find the most outside test runner, could be inside a describe or not
61
+ [`Program > * > CallExpression[callee.name=/${TEST_RUNNER_IDENTIFIER}/], CallExpression[callee.name=/describe/] > * > * > * > CallExpression[callee.name=/${TEST_RUNNER_IDENTIFIER}/]`]:
62
+ (node: Rule.Node) => {
63
+ if (node.type === 'CallExpression') {
64
+ // Calculate the depth of nested test runners, counting from the most outside
65
+ const depth = getDepthOfNestedRunner(node);
66
+
67
+ if (depth > NESTED_LIMIT) {
68
+ return context.report({
69
+ node,
70
+ messageId: 'tooManyNestedTestRunner',
71
+ data: {
72
+ nestedTestRunner: depth.toString(),
73
+ },
74
+ });
75
+ }
76
+ }
77
+ return {};
78
+ },
79
+ };
80
+ },
81
+ };
82
+
83
+ export default rule;
@@ -12,6 +12,8 @@ export const configs: {
12
12
  plugins: string[];
13
13
  rules: {
14
14
  '@atlaskit/platform/ensure-feature-flag-registration': string;
15
+ '@atlaskit/platform/ensure-test-runner-arguments': string;
16
+ '@atlaskit/platform/ensure-test-runner-nested-count': string;
15
17
  '@atlaskit/platform/no-invalid-feature-flag-usage': string;
16
18
  };
17
19
  };
@@ -20,6 +22,8 @@ export const configs: {
20
22
  // @public (undocumented)
21
23
  export const rules: {
22
24
  'ensure-feature-flag-registration': Rule.RuleModule;
25
+ 'ensure-test-runner-arguments': Rule.RuleModule;
26
+ 'ensure-test-runner-nested-count': Rule.RuleModule;
23
27
  'no-invalid-feature-flag-usage': Rule.RuleModule;
24
28
  };
25
29