Skip to content

Commit 0fec322

Browse files
committed
feat: new setting for customizing file name pattern to report
1 parent 63c9d7b commit 0fec322

File tree

4 files changed

+84
-13
lines changed

4 files changed

+84
-13
lines changed

lib/detect-testing-library-utils.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils';
22

33
export type TestingLibrarySettings = {
44
'testing-library/module'?: string;
5+
'testing-library/file-name'?: string;
56
};
67

78
export type TestingLibraryContext<
@@ -25,9 +26,12 @@ export type EnhancedRuleCreate<
2526

2627
export type DetectionHelpers = {
2728
getIsTestingLibraryImported: () => boolean;
29+
getIsValidFileName: () => boolean;
2830
canReportErrors: () => boolean;
2931
};
3032

33+
const DEFAULT_FILE_NAME_PATTERN = '^.*\\.(test|spec)\\.[jt]sx?$';
34+
3135
/**
3236
* Enhances a given rule `create` with helpers to detect Testing Library utils.
3337
*/
@@ -45,6 +49,9 @@ export function detectTestingLibraryUtils<
4549

4650
// Init options based on shared ESLint settings
4751
const customModule = context.settings['testing-library/module'];
52+
const fileNamePattern =
53+
context.settings['testing-library/file-name'] ??
54+
DEFAULT_FILE_NAME_PATTERN;
4855

4956
// Helpers for Testing Library detection.
5057
const helpers: DetectionHelpers = {
@@ -68,11 +75,21 @@ export function detectTestingLibraryUtils<
6875
return isImportingTestingLibraryModule || isImportingCustomModule;
6976
},
7077

78+
/**
79+
* Gets if file name being analyzed is valid or not.
80+
*
81+
* This is based on "testing-library/file-name" setting.
82+
*/
83+
getIsValidFileName() {
84+
const fileName = context.getFilename();
85+
return !!fileName.match(fileNamePattern);
86+
},
87+
7188
/**
7289
* Wraps all conditions that must be met to report rules.
7390
*/
7491
canReportErrors() {
75-
return this.getIsTestingLibraryImported();
92+
return this.getIsTestingLibraryImported() && this.getIsValidFileName();
7693
},
7794
};
7895

tests/create-testing-library-rule.test.ts

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { createRuleTester } from './lib/test-utils';
22
import rule, { RULE_NAME } from './fake-rule';
33

4-
const ruleTester = createRuleTester({
5-
ecmaFeatures: {
6-
jsx: true,
7-
},
8-
});
4+
const ruleTester = createRuleTester();
95

106
ruleTester.run(RULE_NAME, rule, {
117
valid: [
128
{
9+
filename: 'MyComponent.test.js',
1310
code: `
1411
// case: nothing related to Testing Library at all
1512
import { shallow } from 'enzyme';
@@ -18,6 +15,7 @@ ruleTester.run(RULE_NAME, rule, {
1815
`,
1916
},
2017
{
18+
filename: 'MyComponent.test.js',
2119
code: `
2220
// case: render imported from other than custom module
2321
import { render } from '@somewhere/else'
@@ -29,6 +27,7 @@ ruleTester.run(RULE_NAME, rule, {
2927
},
3028
},
3129
{
30+
filename: 'MyComponent.test.js',
3231
code: `
3332
// case: prevent import which should trigger an error since it's imported
3433
// from other than custom module
@@ -38,16 +37,47 @@ ruleTester.run(RULE_NAME, rule, {
3837
'testing-library/module': 'test-utils',
3938
},
4039
},
40+
{
41+
filename: 'MyComponent.test.js',
42+
code: `
43+
// case: import module forced to be reported but not matching file name
44+
import { foo } from 'report-me'
45+
`,
46+
settings: {
47+
'testing-library/file-name': 'testing-library\\.js',
48+
},
49+
},
4150
],
4251
invalid: [
4352
{
53+
filename: 'MyComponent.test.js',
4454
code: `
4555
// case: import module forced to be reported
4656
import { foo } from 'report-me'
4757
`,
4858
errors: [{ line: 3, column: 7, messageId: 'fakeError' }],
4959
},
5060
{
61+
filename: 'MyComponent.spec.js',
62+
code: `
63+
// case: import module forced to be reported but from .spec.js named file
64+
import { foo } from 'report-me'
65+
`,
66+
errors: [{ line: 3, column: 7, messageId: 'fakeError' }],
67+
},
68+
{
69+
filename: 'MyComponent.testing-library.js',
70+
code: `
71+
// case: import module forced to be reported with custom file name
72+
import { foo } from 'report-me'
73+
`,
74+
settings: {
75+
'testing-library/file-name': 'testing-library\\.js',
76+
},
77+
errors: [{ line: 3, column: 7, messageId: 'fakeError' }],
78+
},
79+
{
80+
filename: 'MyComponent.test.js',
5181
code: `
5282
// case: render imported from any module by default (aggressive reporting)
5383
import { render } from '@somewhere/else'
@@ -64,6 +94,7 @@ ruleTester.run(RULE_NAME, rule, {
6494
],
6595
},
6696
{
97+
filename: 'MyComponent.test.js',
6798
code: `
6899
// case: render imported from Testing Library module
69100
import { render } from '@testing-library/react'
@@ -80,6 +111,7 @@ ruleTester.run(RULE_NAME, rule, {
80111
],
81112
},
82113
{
114+
filename: 'MyComponent.test.js',
83115
code: `
84116
// case: render imported from config custom module
85117
import { render } from 'test-utils'
@@ -99,6 +131,7 @@ ruleTester.run(RULE_NAME, rule, {
99131
],
100132
},
101133
{
134+
filename: 'MyComponent.test.js',
102135
code: `
103136
// case: render imported from Testing Library module if
104137
// custom module setup

tests/lib/rules/no-node-access.test.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ const ruleTester = createRuleTester({
1010
ruleTester.run(RULE_NAME, rule, {
1111
valid: [
1212
{
13+
filename: 'MyComponent.test.js',
1314
code: `
1415
import { screen } from '@testing-library/react';
1516
1617
const buttonText = screen.getByText('submit');
1718
`,
1819
},
1920
{
21+
filename: 'MyComponent.test.js',
2022
code: `
2123
import { screen } from '@testing-library/react';
2224
@@ -26,6 +28,7 @@ ruleTester.run(RULE_NAME, rule, {
2628
`,
2729
},
2830
{
31+
filename: 'MyComponent.test.js',
2932
code: `
3033
import { screen } from '@testing-library/react';
3134
@@ -34,6 +37,7 @@ ruleTester.run(RULE_NAME, rule, {
3437
`,
3538
},
3639
{
40+
filename: 'MyComponent.test.js',
3741
code: `
3842
import { screen } from '@testing-library/react';
3943
@@ -43,6 +47,7 @@ ruleTester.run(RULE_NAME, rule, {
4347
`,
4448
},
4549
{
50+
filename: 'MyComponent.test.js',
4651
code: `
4752
import { render, within } from '@testing-library/react';
4853
@@ -51,19 +56,19 @@ ruleTester.run(RULE_NAME, rule, {
5156
within(signinModal).getByPlaceholderText('Username');
5257
`,
5358
},
54-
/*{
55-
// TODO: this one should be valid indeed. Rule implementation must be improved
56-
// to track where the nodes are coming from. This one wasn't reported before
57-
// just because this code is not importing TL module, but that's a really
58-
// brittle check. Instead, this one shouldn't be reported since `children`
59-
// it's just a property not related to a node
59+
{
60+
filename: 'MyComponent.test.js',
6061
code: `
6162
const Component = props => {
6263
return <div>{props.children}</div>
6364
}
6465
`,
65-
},*/
66+
settings: {
67+
'testing-library/file-name': 'testing-library\\.js',
68+
},
69+
},
6670
{
71+
filename: 'MyComponent.test.js',
6772
code: `
6873
// case: importing custom module
6974
const closestButton = document.getElementById('submit-btn').closest('button');
@@ -76,6 +81,7 @@ ruleTester.run(RULE_NAME, rule, {
7681
],
7782
invalid: [
7883
{
84+
filename: 'MyComponent.test.js',
7985
code: `
8086
// case: without importing TL (aggressive reporting)
8187
const closestButton = document.getElementById('submit-btn')
@@ -84,6 +90,7 @@ ruleTester.run(RULE_NAME, rule, {
8490
errors: [{ messageId: 'noNodeAccess', line: 3 }],
8591
},
8692
{
93+
filename: 'MyComponent.test.js',
8794
code: `
8895
import { screen } from '@testing-library/react';
8996
@@ -99,6 +106,7 @@ ruleTester.run(RULE_NAME, rule, {
99106
],
100107
},
101108
{
109+
filename: 'MyComponent.test.js',
102110
code: `
103111
import { screen } from '@testing-library/react';
104112
@@ -111,6 +119,7 @@ ruleTester.run(RULE_NAME, rule, {
111119
],
112120
},
113121
{
122+
filename: 'MyComponent.test.js',
114123
code: `
115124
import { screen } from '@testing-library/react';
116125
@@ -126,6 +135,7 @@ ruleTester.run(RULE_NAME, rule, {
126135
],
127136
},
128137
{
138+
filename: 'MyComponent.test.js',
129139
code: `
130140
import { screen } from '@testing-library/react';
131141
@@ -138,6 +148,7 @@ ruleTester.run(RULE_NAME, rule, {
138148
],
139149
},
140150
{
151+
filename: 'MyComponent.test.js',
141152
code: `
142153
import { render } from '@testing-library/react';
143154
@@ -151,6 +162,7 @@ ruleTester.run(RULE_NAME, rule, {
151162
],
152163
},
153164
{
165+
filename: 'MyComponent.test.js',
154166
code: `
155167
import { screen } from '@testing-library/react';
156168
@@ -175,6 +187,7 @@ ruleTester.run(RULE_NAME, rule, {
175187
],
176188
},
177189
{
190+
filename: 'MyComponent.test.js',
178191
code: `
179192
import { screen } from '@testing-library/react';
180193
@@ -188,6 +201,7 @@ ruleTester.run(RULE_NAME, rule, {
188201
],
189202
},
190203
{
204+
filename: 'MyComponent.test.js',
191205
code: `
192206
import { render } from '@testing-library/react';
193207
@@ -202,6 +216,7 @@ ruleTester.run(RULE_NAME, rule, {
202216
],
203217
},
204218
{
219+
filename: 'MyComponent.test.js',
205220
code: `
206221
import { render } from '@testing-library/react';
207222
@@ -215,6 +230,7 @@ ruleTester.run(RULE_NAME, rule, {
215230
],
216231
},
217232
{
233+
filename: 'MyComponent.test.js',
218234
code: `
219235
import { screen } from '@testing-library/react';
220236
@@ -245,6 +261,7 @@ ruleTester.run(RULE_NAME, rule, {
245261
],
246262
},
247263
{
264+
filename: 'MyComponent.test.js',
248265
code: `
249266
import { screen } from '@testing-library/react';
250267

tests/lib/test-utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ export const createRuleTester = (
99
parserOptions: {
1010
ecmaVersion: 2018,
1111
sourceType: 'module',
12+
// TODO: we should deep merge here
13+
ecmaFeatures: {
14+
jsx: true,
15+
},
1216
...parserOptions,
1317
},
1418
});

0 commit comments

Comments
 (0)