Skip to content

Commit 48b19d5

Browse files
authored
fix(consistent-data-testid): avoid crash for filename with square brackets (#643)
fix: consistent-data-testid crashing when square brackets are in filename fileName placeholder will be replaced with an empty string, as dynamic routes cannot be defined Closes #509
1 parent 3c2cbbd commit 48b19d5

File tree

3 files changed

+75
-4
lines changed

3 files changed

+75
-4
lines changed

docs/rules/consistent-data-testid.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ const baz = (props) => <div>...</div>;
2828

2929
## Options
3030

31-
| Option | Required | Default | Details | Example |
32-
| ----------------- | -------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
33-
| `testIdPattern` | Yes | None | A regex used to validate the format of the `data-testid` value. `{fileName}` can optionally be used as a placeholder and will be substituted with the name of the file OR the name of the files parent directory in the case when the file name is `index.js` | `^{fileName}(\_\_([A-Z]+[a-z]_?)+)_\$` |
34-
| `testIdAttribute` | No | `data-testid` | A string (or array of strings) used to specify the attribute used for querying by ID. This is only required if data-testid has been explicitly overridden in the [RTL configuration](https://testing-library.com/docs/dom-testing-library/api-queries#overriding-data-testid) | `data-my-test-attribute`, `["data-testid", "testId"]` |
31+
| Option | Required | Default | Details | Example |
32+
| ----------------- | -------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
33+
| `testIdPattern` | Yes | None | A regex used to validate the format of the `data-testid` value. `{fileName}` can optionally be used as a placeholder and will be substituted with the name of the file OR the name of the files parent directory in the case when the file name is `index.js` OR empty string in the case of dynamically changing routes (that contain square brackets) with `Gatsby.js` or `Next.js` | `^{fileName}(\_\_([A-Z]+[a-z]_?)+)_\$` |
34+
| `testIdAttribute` | No | `data-testid` | A string (or array of strings) used to specify the attribute used for querying by ID. This is only required if data-testid has been explicitly overridden in the [RTL configuration](https://testing-library.com/docs/dom-testing-library/api-queries#overriding-data-testid) | `data-my-test-attribute`, `["data-testid", "testId"]` |
3535

3636
## Example
3737

@@ -56,3 +56,7 @@ const baz = (props) => <div>...</div>;
5656
]
5757
}
5858
```
59+
60+
## Notes
61+
62+
- If you are using Gatsby.js's [client-only routes](https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api/#syntax-client-only-routes) or Next.js's [dynamic routes](https://nextjs.org/docs/routing/dynamic-routes) and therefore have square brackets (`[]`) in the filename (e.g. `../path/to/[component].js`), the `{fileName}` placeholder will be replaced with an empty string. This is because a linter cannot know what the dynamic content will be at run time.

lib/rules/consistent-data-testid.ts

+6
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ export default createTestingLibraryRule<Options, MessageIds>({
7474
function getFileNameData() {
7575
const splitPath = getFilename().split('/');
7676
const fileNameWithExtension = splitPath.pop() ?? '';
77+
if (
78+
fileNameWithExtension.includes('[') ||
79+
fileNameWithExtension.includes(']')
80+
) {
81+
return { fileName: undefined };
82+
}
7783
const parent = splitPath.pop();
7884
const fileName = fileNameWithExtension.split('.').shift();
7985

tests/lib/rules/consistent-data-testid.test.ts

+61
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,67 @@ const validTestCases: ValidTestCase[] = [
200200
`,
201201
options: [{ testIdPattern: 'somethingElse' }],
202202
},
203+
// To fix issue 509, https://github.com/testing-library/eslint-plugin-testing-library/issues/509
204+
// Gatsby.js ja Next.js use square brackets in filenames to create dynamic routes
205+
{
206+
code: `
207+
import React from 'react';
208+
209+
const TestComponent = props => {
210+
return (
211+
<div data-testid="__CoolStuff">
212+
Hello
213+
</div>
214+
)
215+
};
216+
`,
217+
options: [
218+
{
219+
testIdPattern: '^{fileName}(__([A-Z]+[a-z]*?)+)*$',
220+
},
221+
],
222+
filename: '/my/cool/file/path/[client-only].js',
223+
},
224+
{
225+
code: `
226+
import React from 'react';
227+
228+
const TestComponent = props => {
229+
return (
230+
<div data-testid="__CoolStuff">
231+
Hello
232+
</div>
233+
)
234+
};
235+
`,
236+
options: [
237+
{
238+
// should work if given the {fileName} placeholder
239+
testIdPattern: '^{fileName}(__([A-Z]+[a-z]*?)+)*$',
240+
},
241+
],
242+
filename: '/my/cool/file/path/[...wildcard].js',
243+
},
244+
{
245+
code: `
246+
import React from 'react';
247+
248+
const TestComponent = props => {
249+
return (
250+
<div data-testid="__CoolStuff">
251+
Hello
252+
</div>
253+
)
254+
};
255+
`,
256+
options: [
257+
{
258+
// should work also if not given the {fileName} placeholder
259+
testIdPattern: '^(__([A-Z]+[a-z]*?)+)*$',
260+
},
261+
],
262+
filename: '/my/cool/file/path/[...wildcard].js',
263+
},
203264
];
204265
const invalidTestCases: InvalidTestCase[] = [
205266
{

0 commit comments

Comments
 (0)