@atlaskit/eslint-plugin-platform 2.6.0 → 2.7.1

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 (119) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/index.js +4 -3
  3. package/dist/cjs/rules/ensure-critical-dependency-resolutions/index.js +2 -2
  4. package/dist/cjs/rules/ensure-native-and-af-exports-synced/index.js +3 -0
  5. package/dist/cjs/rules/feature-gating/no-alias/index.js +1 -1
  6. package/dist/cjs/rules/no-direct-document-usage/index.js +1 -1
  7. package/dist/cjs/rules/no-set-immediate/index.js +39 -0
  8. package/dist/cjs/rules/util/context-compat.js +4 -2
  9. package/dist/es2019/index.js +4 -3
  10. package/dist/es2019/rules/ensure-critical-dependency-resolutions/index.js +2 -2
  11. package/dist/es2019/rules/ensure-native-and-af-exports-synced/index.js +3 -0
  12. package/dist/es2019/rules/feature-gating/no-alias/index.js +1 -1
  13. package/dist/es2019/rules/no-direct-document-usage/index.js +1 -1
  14. package/dist/es2019/rules/no-set-immediate/index.js +33 -0
  15. package/dist/es2019/rules/util/context-compat.js +4 -2
  16. package/dist/esm/index.js +4 -3
  17. package/dist/esm/rules/ensure-critical-dependency-resolutions/index.js +2 -2
  18. package/dist/esm/rules/ensure-native-and-af-exports-synced/index.js +3 -0
  19. package/dist/esm/rules/feature-gating/no-alias/index.js +1 -1
  20. package/dist/esm/rules/no-direct-document-usage/index.js +1 -1
  21. package/dist/esm/rules/no-set-immediate/index.js +33 -0
  22. package/dist/esm/rules/util/context-compat.js +4 -2
  23. package/dist/types/index.d.ts +14 -6
  24. package/dist/types/rules/util/handle-ast-object.d.ts +1 -1
  25. package/dist/types-ts4.5/index.d.ts +14 -6
  26. package/dist/types-ts4.5/rules/util/handle-ast-object.d.ts +1 -1
  27. package/package.json +2 -2
  28. package/afm-cc/tsconfig.json +0 -24
  29. package/afm-jira/tsconfig.json +0 -24
  30. package/build/tsconfig.json +0 -17
  31. package/dist/cjs/rules/ensure-valid-platform-yarn-protocol-usage/index.js +0 -79
  32. package/dist/es2019/rules/ensure-valid-platform-yarn-protocol-usage/index.js +0 -62
  33. package/dist/esm/rules/ensure-valid-platform-yarn-protocol-usage/index.js +0 -75
  34. package/src/__tests__/utils/_tester.tsx +0 -26
  35. package/src/index.tsx +0 -251
  36. package/src/rules/compiled/README.md +0 -3
  37. package/src/rules/compiled/expand-background-shorthand/README.md +0 -23
  38. package/src/rules/compiled/expand-background-shorthand/__tests__/rule.test.ts +0 -160
  39. package/src/rules/compiled/expand-background-shorthand/index.tsx +0 -43
  40. package/src/rules/compiled/expand-border-shorthand/README.md +0 -51
  41. package/src/rules/compiled/expand-border-shorthand/__tests__/rule.test.ts +0 -211
  42. package/src/rules/compiled/expand-border-shorthand/index.ts +0 -103
  43. package/src/rules/compiled/expand-spacing-shorthand/README.md +0 -38
  44. package/src/rules/compiled/expand-spacing-shorthand/__tests__/rule.test.ts +0 -448
  45. package/src/rules/compiled/expand-spacing-shorthand/index.ts +0 -240
  46. package/src/rules/constants.tsx +0 -20
  47. package/src/rules/ensure-atlassian-team/__tests__/unit/rule.test.ts +0 -24
  48. package/src/rules/ensure-atlassian-team/index.ts +0 -51
  49. package/src/rules/ensure-critical-dependency-resolutions/__test__/unit/rule.test.tsx +0 -200
  50. package/src/rules/ensure-critical-dependency-resolutions/index.tsx +0 -172
  51. package/src/rules/ensure-feature-flag-prefix/__tests__/unit/rule.test.tsx +0 -65
  52. package/src/rules/ensure-feature-flag-prefix/index.tsx +0 -81
  53. package/src/rules/ensure-feature-flag-registration/__tests__/unit/rule.test.tsx +0 -115
  54. package/src/rules/ensure-feature-flag-registration/index.tsx +0 -106
  55. package/src/rules/ensure-native-and-af-exports-synced/__tests__/unit/rule.test.tsx +0 -199
  56. package/src/rules/ensure-native-and-af-exports-synced/index.tsx +0 -188
  57. package/src/rules/ensure-no-private-dependencies/__tests__/unit/rule.test.ts +0 -212
  58. package/src/rules/ensure-no-private-dependencies/index.ts +0 -64
  59. package/src/rules/ensure-publish-valid/__tests__/unit/rule.test.ts +0 -39
  60. package/src/rules/ensure-publish-valid/index.ts +0 -81
  61. package/src/rules/ensure-test-runner-arguments/__tests__/unit/rule.test.tsx +0 -298
  62. package/src/rules/ensure-test-runner-arguments/index.tsx +0 -121
  63. package/src/rules/ensure-test-runner-nested-count/__tests__/unit/rule.test.tsx +0 -308
  64. package/src/rules/ensure-test-runner-nested-count/index.tsx +0 -82
  65. package/src/rules/ensure-valid-bin-values/__tests__/unit/rule.test.ts +0 -159
  66. package/src/rules/ensure-valid-bin-values/index.ts +0 -70
  67. package/src/rules/ensure-valid-platform-yarn-protocol-usage/__tests__/unit/rule.test.ts +0 -147
  68. package/src/rules/ensure-valid-platform-yarn-protocol-usage/index.ts +0 -67
  69. package/src/rules/feature-gating/README.md +0 -8
  70. package/src/rules/feature-gating/inline-usage/README.md +0 -53
  71. package/src/rules/feature-gating/inline-usage/__tests__/rule.test.tsx +0 -106
  72. package/src/rules/feature-gating/inline-usage/index.tsx +0 -135
  73. package/src/rules/feature-gating/no-alias/README.md +0 -29
  74. package/src/rules/feature-gating/no-alias/__tests__/rule.test.tsx +0 -76
  75. package/src/rules/feature-gating/no-alias/index.tsx +0 -80
  76. package/src/rules/feature-gating/no-module-level-eval/README.md +0 -53
  77. package/src/rules/feature-gating/no-module-level-eval/__tests__/test.tsx +0 -133
  78. package/src/rules/feature-gating/no-module-level-eval/index.tsx +0 -54
  79. package/src/rules/feature-gating/no-module-level-eval-nav4/README.md +0 -8
  80. package/src/rules/feature-gating/no-module-level-eval-nav4/__tests__/test.tsx +0 -130
  81. package/src/rules/feature-gating/no-module-level-eval-nav4/index.tsx +0 -73
  82. package/src/rules/feature-gating/no-preconditioning/README.md +0 -69
  83. package/src/rules/feature-gating/no-preconditioning/__tests__/rule.test.tsx +0 -164
  84. package/src/rules/feature-gating/no-preconditioning/index.tsx +0 -138
  85. package/src/rules/feature-gating/prefer-fg/README.md +0 -3
  86. package/src/rules/feature-gating/prefer-fg/__tests__/rule.test.tsx +0 -83
  87. package/src/rules/feature-gating/prefer-fg/index.tsx +0 -110
  88. package/src/rules/feature-gating/static-feature-flags/README.md +0 -3
  89. package/src/rules/feature-gating/static-feature-flags/__tests__/test.tsx +0 -135
  90. package/src/rules/feature-gating/static-feature-flags/index.tsx +0 -103
  91. package/src/rules/feature-gating/use-recommended-utils/README.md +0 -67
  92. package/src/rules/feature-gating/use-recommended-utils/__tests__/rule.test.tsx +0 -78
  93. package/src/rules/feature-gating/use-recommended-utils/index.tsx +0 -57
  94. package/src/rules/feature-gating/utils.tsx +0 -48
  95. package/src/rules/no-direct-document-usage/index.tsx +0 -109
  96. package/src/rules/no-duplicate-dependencies/__tests__/unit/rule.test.ts +0 -116
  97. package/src/rules/no-duplicate-dependencies/index.ts +0 -79
  98. package/src/rules/no-invalid-feature-flag-usage/__tests__/unit/rule.test.tsx +0 -69
  99. package/src/rules/no-invalid-feature-flag-usage/index.tsx +0 -128
  100. package/src/rules/no-invalid-storybook-decorator-usage/__tests__/unit/rule.test.tsx +0 -18
  101. package/src/rules/no-invalid-storybook-decorator-usage/index.tsx +0 -39
  102. package/src/rules/no-pre-post-installs/__tests__/unit/rule.test.ts +0 -41
  103. package/src/rules/no-pre-post-installs/index.ts +0 -35
  104. package/src/rules/no-sparse-checkout/__tests__/unit/rule.test.tsx +0 -48
  105. package/src/rules/no-sparse-checkout/index.tsx +0 -54
  106. package/src/rules/use-entrypoints-in-examples/README.md +0 -27
  107. package/src/rules/use-entrypoints-in-examples/__tests__/rule.test.tsx +0 -34
  108. package/src/rules/use-entrypoints-in-examples/index.tsx +0 -43
  109. package/src/rules/util/__tests__/context-compat.test.ts +0 -122
  110. package/src/rules/util/compiled-utils.ts +0 -27
  111. package/src/rules/util/context-compat.ts +0 -41
  112. package/src/rules/util/file-exclusions.ts +0 -39
  113. package/src/rules/util/handle-ast-object.ts +0 -33
  114. package/src/rules/util/registration-utils.ts +0 -59
  115. package/tsconfig.app.json +0 -43
  116. package/tsconfig.dev.json +0 -40
  117. package/tsconfig.json +0 -23
  118. /package/dist/types/rules/{ensure-valid-platform-yarn-protocol-usage → no-set-immediate}/index.d.ts +0 -0
  119. /package/dist/types-ts4.5/rules/{ensure-valid-platform-yarn-protocol-usage → no-set-immediate}/index.d.ts +0 -0
@@ -1,64 +0,0 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
- import type { Rule } from 'eslint';
3
- import { getObjectPropertyAsObject, getObjectPropertyAsLiteral } from '../util/handle-ast-object';
4
- import { getPackagesSync } from '@manypkg/get-packages';
5
- import { findRootSync } from '@manypkg/find-root';
6
-
7
- const root = findRootSync(process.cwd());
8
- const pkgs = getPackagesSync(root).packages;
9
- const pkgMap = new Map(pkgs.map((pkg) => [pkg.packageJson.name, pkg]));
10
-
11
- const rule: Rule.RuleModule = {
12
- meta: {
13
- type: 'problem',
14
- docs: {
15
- description: `Ensures that private dependencies are not used in published packages.`,
16
- recommended: true,
17
- },
18
- hasSuggestions: false,
19
- messages: {
20
- invalidPrivateDependency: `Published package has private dependency '{{ pkgName }}'. To resolve this error, remove the private dependency or set this package to private.`,
21
- },
22
- },
23
- create(context) {
24
- return {
25
- ObjectExpression: async (node: Rule.Node) => {
26
- // Only run this rule on package.json files
27
- if (!context.filename.endsWith('package.json') || node.type !== 'ObjectExpression') {
28
- return;
29
- }
30
-
31
- // Private dependencies can be used in private packages
32
- const isPrivatePkg = getObjectPropertyAsLiteral(node, 'private') === true;
33
- if (isPrivatePkg === true) {
34
- return;
35
- }
36
-
37
- // Check for private dependencies in dependencies and peerDependencies
38
- // Note: devDependencies are not checked here as they don't end up in consumer lockfiles
39
- const dependencies = getObjectPropertyAsObject(node, 'dependencies');
40
- const peerDependencies = getObjectPropertyAsObject(node, 'peerDependencies');
41
-
42
- for (const obj of [dependencies, peerDependencies]) {
43
- for (const p of obj?.properties || []) {
44
- if (p.type === 'Property' && p.key.type === 'Literal') {
45
- const key = p.key.value;
46
- if (typeof key === 'string' && pkgMap.has(key)) {
47
- const isPrivateDependency = pkgMap.get(key)?.packageJson.private === true;
48
- if (isPrivateDependency) {
49
- context.report({
50
- node,
51
- messageId: 'invalidPrivateDependency',
52
- data: { pkgName: key },
53
- });
54
- }
55
- }
56
- }
57
- }
58
- }
59
- },
60
- };
61
- },
62
- };
63
-
64
- export default rule;
@@ -1,39 +0,0 @@
1
- import { tester } from '../../../../__tests__/utils/_tester';
2
- import rule from '../../index';
3
-
4
- describe('test ensure-publish-valid-rule', () => {
5
- tester.run('ensure-publish-valid', rule, {
6
- valid: [
7
- {
8
- code: `const foo = { "name": "@af/test" }`,
9
- filename: 'package.json',
10
- },
11
- {
12
- options: [{ exceptions: ['@atlaskit/test'] }],
13
- code: `const foo = { "name": "@atlaskit/test" }`,
14
- filename: 'package.json',
15
- },
16
- {
17
- code: `const foo = { "name": "@atlaskit/test", "private": false, "publishConfig": { "registry": "https://registry.npmjs.org/" } }`,
18
- filename: 'foo/package.json',
19
- },
20
- ],
21
- invalid: [
22
- {
23
- code: `const foo = { "name": "@atlaskit/test" }`,
24
- filename: 'foo/package.json',
25
- errors: [
26
- {
27
- messageId: 'publishConfigRequired',
28
- data: { packageName: '@atlaskit/test' },
29
- },
30
- ],
31
- },
32
- {
33
- code: `const foo = { "name": "@atlaskit/test", "private": true, "publishConfig": { "registry": "https://registry.npmjs.org/" } }`,
34
- filename: 'foo/package.json',
35
- errors: [{ messageId: 'noPrivate', data: { packageName: '@atlaskit/test' } }],
36
- },
37
- ],
38
- });
39
- });
@@ -1,81 +0,0 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
- import type { Rule } from 'eslint';
3
- import { getObjectPropertyAsLiteral, getObjectPropertyAsObject } from '../util/handle-ast-object';
4
-
5
- type RuleOptions = {
6
- // exceptions to this rule, will be ignored
7
- exceptions?: string[];
8
- };
9
-
10
- const rule: Rule.RuleModule = {
11
- meta: {
12
- type: 'problem',
13
- docs: {
14
- description:
15
- 'This rule ensures that the package.json for your packages are set up correctly for publishing depending on the package name prefix',
16
- recommended: true,
17
- },
18
- hasSuggestions: false,
19
- schema: [
20
- {
21
- type: 'object',
22
- properties: {
23
- exceptions: {
24
- type: 'array',
25
- items: [{ type: 'string' }],
26
- },
27
- },
28
- },
29
- ],
30
- messages: {
31
- publishConfigRequired:
32
- '@atlaskit prefix is public! You have to specify a `publishConfig`, (package {{packageName}}) see https://go.atlassian.com/package-namespace',
33
- noPrivate:
34
- 'setting private to true prevents publishing, your package prefix implies you want to publish! (package {{packageName}}) see https://go.atlassian.com/package-namespace',
35
- },
36
- },
37
- create(context) {
38
- const { exceptions } = (context.options?.[0] as RuleOptions) ?? {};
39
-
40
- return {
41
- ObjectExpression: (node: Rule.Node) => {
42
- if (!context.getFilename().endsWith('package.json') || node.type !== 'ObjectExpression') {
43
- return;
44
- }
45
-
46
- const packageName = getObjectPropertyAsLiteral(node, 'name');
47
- const packagePrivate = getObjectPropertyAsLiteral(node, 'private');
48
- const packagePublishConfig = getObjectPropertyAsObject(node, 'publishConfig');
49
-
50
- // exit if package is on known exception list
51
- if (exceptions && exceptions.findIndex((name) => name === packageName) !== -1) {
52
- return;
53
- }
54
-
55
- if (typeof packageName === 'string' && packageName.startsWith('@atlaskit')) {
56
- if (typeof packagePrivate === 'boolean' && packagePrivate) {
57
- return context.report({
58
- node,
59
- messageId: 'noPrivate',
60
- data: {
61
- packageName,
62
- },
63
- });
64
- }
65
-
66
- if (packagePublishConfig === null) {
67
- return context.report({
68
- node,
69
- messageId: 'publishConfigRequired',
70
- data: {
71
- packageName,
72
- },
73
- });
74
- }
75
- }
76
- },
77
- };
78
- },
79
- };
80
-
81
- export default rule;
@@ -1,298 +0,0 @@
1
- import { tester } from '../../../../__tests__/utils/_tester';
2
- import rule from '../../index';
3
-
4
- describe('Feature Flag can only be passed into ffTest as Literal', () => {
5
- tester.run('ensure-test-runner-arguments', rule, {
6
- valid: [
7
- {
8
- code: `ffTest('sample.feature.flag', () => {
9
- const { getByText } = render(<SampleComponent />);
10
- expect(getByText('SampleComponent')).toBeDefined();
11
- });`,
12
- },
13
- ],
14
- invalid: [
15
- {
16
- code: `ffTest(myFeatureFlag, () => {
17
- const { getByText } = render(<SampleComponent />);
18
- expect(getByText('SampleComponent')).toBeDefined();
19
- });`,
20
- errors: [
21
- {
22
- messageId: 'onlyInlineFeatureFlag',
23
- data: { identifierName: 'myFeatureFlag' },
24
- },
25
- ],
26
- },
27
- ],
28
- });
29
- });
30
-
31
- describe('Test functions can only be passed in directly, instead of as variables', () => {
32
- tester.run('ensure-test-runner-arguments', rule, {
33
- valid: [
34
- {
35
- code: `ffTest('sample.feature.flag', () => {
36
- const { getByText } = render(<SampleComponent />);
37
- expect(getByText('SampleComponent')).toBeDefined();
38
- });`,
39
- },
40
- {
41
- code: `ffTest('sample.feature.flag', () => {
42
- const { getByText } = render(<SampleComponent />);
43
- expect(getByText('SampleComponent')).toBeDefined();
44
- }, () => {
45
- const { getByText } = render(<SampleComponent />);
46
- expect(getByText('AnotherSampleComponent')).toBeDefined();
47
- });`,
48
- },
49
- ],
50
- invalid: [
51
- {
52
- code: `ffTest('sample.feature.flag', fnToPassIn);`,
53
- errors: [
54
- {
55
- messageId: 'onlyInlineTestFunction',
56
- data: { identifierName: 'fnToPassIn' },
57
- },
58
- ],
59
- },
60
- {
61
- code: `ffTest('sample.feature.flag', () => {
62
- const { getByText } = render(<SampleComponent />);
63
- expect(getByText('SampleComponent')).toBeDefined();
64
- }, fnToPassInWhenFlagIsDisabled);`,
65
- errors: [
66
- {
67
- messageId: 'onlyInlineTestFunction',
68
- data: { identifierName: 'fnToPassInWhenFlagIsDisabled' },
69
- },
70
- ],
71
- },
72
- {
73
- code: `ffTest('sample.feature.flag', fnToPassInWhenFlagIsEnabled, () => {
74
- const { getByText } = render(<SampleComponent />);
75
- expect(getByText('SampleComponent')).toBeDefined();
76
- },);`,
77
- errors: [
78
- {
79
- messageId: 'onlyInlineTestFunction',
80
- data: { identifierName: 'fnToPassInWhenFlagIsEnabled' },
81
- },
82
- ],
83
- },
84
- ],
85
- });
86
- });
87
-
88
- describe('Verify existing ff overrides are passed down if test runner is nested', () => {
89
- tester.run('ensure-test-runner-arguments', rule, {
90
- valid: [
91
- {
92
- code: `ffTest(
93
- 'uip.sample.color',
94
- ff =>
95
- ffTest(
96
- 'uip.sample.backgroundColor',
97
- () => {
98
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
99
- },
100
- () => {
101
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
102
- },
103
- ff,
104
- ),
105
- ff =>
106
- ffTest(
107
- 'uip.sample.backgroundColor',
108
- () => {
109
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
110
- },
111
- () => {
112
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
113
- },
114
- ff,
115
- ),
116
- );
117
- `,
118
- },
119
- ],
120
- invalid: [
121
- {
122
- code: `ffTest(
123
- 'uip.sample.color',
124
- () =>
125
- ffTest(
126
- 'uip.sample.backgroundColor',
127
- () => {
128
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
129
- },
130
- () => {
131
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
132
- },
133
- ff,
134
- ),
135
- ff =>
136
- ffTest(
137
- 'uip.sample.backgroundColor',
138
- () => {
139
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
140
- },
141
- () => {
142
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
143
- },
144
- ff,
145
- ),
146
- );
147
- `,
148
- output: `ffTest(
149
- 'uip.sample.color',
150
- ff =>
151
- ffTest(
152
- 'uip.sample.backgroundColor',
153
- () => {
154
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
155
- },
156
- () => {
157
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
158
- },
159
- ff,
160
- ),
161
- ff =>
162
- ffTest(
163
- 'uip.sample.backgroundColor',
164
- () => {
165
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
166
- },
167
- () => {
168
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
169
- },
170
- ff,
171
- ),
172
- );
173
- `,
174
- errors: [
175
- {
176
- messageId: 'passDownExistingFeatureFlagParam',
177
- },
178
- ],
179
- },
180
- {
181
- code: `ffTest(
182
- 'uip.sample.color',
183
- ff =>
184
- ffTest(
185
- 'uip.sample.backgroundColor',
186
- () => {
187
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
188
- },
189
- () => {
190
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
191
- },
192
- ),
193
- ff =>
194
- ffTest(
195
- 'uip.sample.backgroundColor',
196
- () => {
197
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
198
- },
199
- () => {
200
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
201
- },
202
- ff,
203
- ),
204
- );
205
- `,
206
- output: `ffTest(
207
- 'uip.sample.color',
208
- ff =>
209
- ffTest(
210
- 'uip.sample.backgroundColor',
211
- () => {
212
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
213
- },
214
- () => {
215
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
216
- }, ff,
217
- ),
218
- ff =>
219
- ffTest(
220
- 'uip.sample.backgroundColor',
221
- () => {
222
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
223
- },
224
- () => {
225
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
226
- },
227
- ff,
228
- ),
229
- );
230
- `,
231
- errors: [
232
- {
233
- messageId: 'passDownExistingFeatureFlagArgument',
234
- },
235
- ],
236
- },
237
- {
238
- code: `ffTest(
239
- 'uip.sample.color',
240
- ff =>
241
- ffTest(
242
- 'uip.sample.backgroundColor',
243
- () => {
244
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
245
- },
246
- () => {
247
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
248
- },
249
- ff,
250
- ),
251
- ff =>
252
- ffTest(
253
- 'uip.sample.backgroundColor',
254
- () => {
255
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
256
- },
257
- () => {
258
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
259
- },
260
- ffExisting,
261
- ),
262
- );
263
- `,
264
- output: `ffTest(
265
- 'uip.sample.color',
266
- ff =>
267
- ffTest(
268
- 'uip.sample.backgroundColor',
269
- () => {
270
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
271
- },
272
- () => {
273
- expect(getByText('SampleComponent')).toHaveStyle('color: red');
274
- },
275
- ff,
276
- ),
277
- ff =>
278
- ffTest(
279
- 'uip.sample.backgroundColor',
280
- () => {
281
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
282
- },
283
- () => {
284
- expect(getByText('SampleComponent')).toHaveStyle('color: blue');
285
- },
286
- ff,
287
- ),
288
- );
289
- `,
290
- errors: [
291
- {
292
- messageId: 'passDownExistingFeatureFlagNamesMatch',
293
- },
294
- ],
295
- },
296
- ],
297
- });
298
- });
@@ -1,121 +0,0 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
- import type { Rule } from 'eslint';
3
-
4
- const TEST_RUNNER_IDENTIFIER = 'ffTest' as const;
5
-
6
- const rule: Rule.RuleModule = {
7
- meta: {
8
- docs: {
9
- recommended: false,
10
- },
11
- type: 'problem',
12
- fixable: 'code',
13
- messages: {
14
- onlyInlineFeatureFlag:
15
- 'Only pass in feature flag as string literal, please replace {{identifierName}} with its value.',
16
- onlyInlineTestFunction:
17
- 'Only pass in test functions/cases in an inline manner. Test functions/cases should be passed in directly, instead of as variables. Please replace {{identifierName}} with its own definition.',
18
- passDownExistingFeatureFlagParam:
19
- 'An argument symbolising existing FFs needs to be passed down as param when calling nested test runner. See examples in the package which declares this function.',
20
- passDownExistingFeatureFlagArgument:
21
- 'An argument symbolising existing FFs needs to be passed in as argument when calling nested test runner. See examples in the package which declares this function.',
22
- passDownExistingFeatureFlagNamesMatch:
23
- 'Argument names not matching when passing down existing feature flags. See examples in the package which declares this function.',
24
- },
25
- },
26
- create(context) {
27
- return {
28
- [`CallExpression[callee.name=/${TEST_RUNNER_IDENTIFIER}/]`]: (node: Rule.Node) => {
29
- if (node.type === 'CallExpression') {
30
- const args = node.arguments;
31
-
32
- // Verify FF is passed inline
33
- if (args[0] && args[0].type !== 'Literal') {
34
- return context.report({
35
- node,
36
- messageId: 'onlyInlineFeatureFlag',
37
- data: {
38
- identifierName: args[0].type === 'Identifier' ? args[0].name : '',
39
- },
40
- });
41
- }
42
-
43
- // Verify test functions/cases are passed inline
44
- if (args[1] && args[1].type !== 'ArrowFunctionExpression') {
45
- return context.report({
46
- node,
47
- messageId: 'onlyInlineTestFunction',
48
- data: {
49
- identifierName: args[1].type === 'Identifier' ? args[1].name : '',
50
- },
51
- });
52
- }
53
-
54
- if (args[2] && args[2].type !== 'ArrowFunctionExpression') {
55
- return context.report({
56
- node,
57
- messageId: 'onlyInlineTestFunction',
58
- data: {
59
- identifierName: args[2].type === 'Identifier' ? args[2].name : '',
60
- },
61
- });
62
- }
63
-
64
- // Verify existing ff overrides are passed down if test runner is nested
65
- let upperTestRunner = node.parent?.parent;
66
- if (
67
- upperTestRunner?.type === 'CallExpression' &&
68
- upperTestRunner?.callee.type === 'Identifier' &&
69
- upperTestRunner?.callee.name === TEST_RUNNER_IDENTIFIER &&
70
- node.parent?.type === 'ArrowFunctionExpression'
71
- ) {
72
- // Not pass in ff to the function that calls test runner
73
- if (!node.parent.params[0] || node.parent.params[0].type !== 'Identifier') {
74
- return context.report({
75
- node: node.parent,
76
- messageId: 'passDownExistingFeatureFlagParam',
77
- fix: function (fixer) {
78
- const parentNodeRange = node.parent.range as [number, number];
79
- return [
80
- fixer.replaceTextRange([parentNodeRange[0], parentNodeRange[0] + 2], 'ff'),
81
- node.arguments[3]
82
- ? fixer.replaceText(node.arguments[3], 'ff')
83
- : fixer.insertTextAfter(node.arguments[2], ', ff'),
84
- ];
85
- },
86
- });
87
- }
88
-
89
- // Not pass in ff to test runner as 4th argument
90
- const paramName = node.parent.params[0].name;
91
- if (!node.arguments[3] || node.arguments[3].type !== 'Identifier') {
92
- return context.report({
93
- node,
94
- messageId: 'passDownExistingFeatureFlagArgument',
95
- fix: function (fixer) {
96
- return node.arguments[3]
97
- ? fixer.replaceText(node.arguments[3], paramName)
98
- : fixer.insertTextAfter(node.arguments[2], `, ${paramName}`);
99
- },
100
- });
101
- }
102
- // Pass in the above two, but names don't match
103
- const arguName = node.arguments[3].name;
104
- if (paramName !== arguName) {
105
- return context.report({
106
- node: node.parent,
107
- messageId: 'passDownExistingFeatureFlagNamesMatch',
108
- fix: function (fixer) {
109
- return fixer.replaceText(node.arguments[3], paramName);
110
- },
111
- });
112
- }
113
- }
114
- }
115
- return {};
116
- },
117
- };
118
- },
119
- };
120
-
121
- export default rule;