Skip to content

Commit 8039c49

Browse files
committed
Merge branch 'feat-add-autofix-for-await-async-utils' of github.com-personal:neriyarden/eslint-plugin-testing-library into feat-add-autofix-for-await-async-utils
2 parents 131e636 + a48bcc2 commit 8039c49

36 files changed

+10692
-5543
lines changed

.all-contributorsrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,8 @@
413413
"contributions": [
414414
"code",
415415
"doc",
416-
"test"
416+
"test",
417+
"maintenance"
417418
]
418419
},
419420
{

.editorconfig

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# EditorConfig helps developers define and maintain consistent
2+
# coding styles between different editors and IDEs
3+
# editorconfig.org
4+
5+
root = true
6+
7+
[*]
8+
end_of_line = lf
9+
charset = utf-8
10+
trim_trailing_whitespace = true
11+
insert_final_newline = true
12+
indent_style = tab

.github/workflows/release.yml

+10-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ concurrency:
1515
group: release
1616
cancel-in-progress: false
1717

18+
permissions:
19+
contents: write # to be able to publish a GitHub release
20+
id-token: write # to enable use of OIDC for npm provenance
21+
issues: write # to be able to comment on released issues
22+
pull-requests: write # to be able to comment on released pull requests
23+
1824
jobs:
1925
publish:
2026
name: Publish NPM package
@@ -28,16 +34,18 @@ jobs:
2834
- name: Set up Node
2935
uses: actions/setup-node@v4
3036
with:
37+
cache: npm
3138
node-version-file: '.nvmrc'
3239

3340
- name: Install dependencies
34-
uses: bahmutov/npm-install@v1
41+
run: npm install
3542

3643
- name: Build package
3744
run: npm run build
3845

3946
- name: Release new version
47+
run: npx semantic-release
4048
env:
4149
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50+
NPM_CONFIG_PROVENANCE: true
4251
NPM_TOKEN: ${{ secrets.NPM_AUTOMATION_TOKEN }}
43-
run: npx semantic-release

.github/workflows/verifications.yml

+25-5
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,54 @@ jobs:
1919
- name: Set up Node
2020
uses: actions/setup-node@v4
2121
with:
22+
cache: npm
2223
node-version-file: '.nvmrc'
2324

2425
- name: Install dependencies
25-
uses: bahmutov/npm-install@v1
26+
run: npm install
2627

2728
- name: Run script
2829
run: npm run ${{ matrix.validation-script }}
2930

3031
tests:
3132
name: Tests (Node v${{ matrix.node }} - ESLint v${{ matrix.eslint }})
3233
runs-on: ubuntu-latest
34+
timeout-minutes: 3
3335
strategy:
3436
fail-fast: false
3537
matrix:
36-
# The .x indicates "the most recent one"
37-
node: [19.x, 18.x, 17.x, 16.x, 14.x, 14.17.0, 12.x, 12.22.0]
38-
eslint: [7.5, 7, 8]
38+
node: [12.22.0, 12, 14.17.0, 14, 16, 17, 18, 19, 20, 22]
39+
eslint: [7.5, 7, 8, 9]
40+
exclude:
41+
# eslint@9 doesn't support < Node v18
42+
- node: 17
43+
eslint: 9
44+
- node: 16
45+
eslint: 9
46+
- node: 14
47+
eslint: 9
48+
- node: 14.17.0
49+
eslint: 9
50+
- node: 12
51+
eslint: 9
52+
- node: 12.22.0
53+
eslint: 9
3954
steps:
4055
- name: Checkout
4156
uses: actions/checkout@v4
4257

4358
- name: Set up Node
4459
uses: actions/setup-node@v4
4560
with:
61+
cache: npm
4662
node-version: ${{ matrix.node }}
4763

4864
- name: Install dependencies
49-
uses: bahmutov/npm-install@v1
65+
run: npm install
66+
67+
# see https://github.com/npm/cli/issues/7349
68+
- if: ${{ matrix.eslint == 9 }}
69+
run: npm un @typescript-eslint/eslint-plugin eslint-plugin-jest eslint-doc-generator
5070

5171
- name: Install ESLint v${{ matrix.eslint }}
5272
run: npm install --no-save --force eslint@${{ matrix.eslint }}

.nvmrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
16
1+
20

.prettierignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dist
2+
node_modules
3+
coverage
4+
.all-contributorsrc

.prettierrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module.exports = {
2+
trailingComma: 'es5',
23
singleQuote: true,
34
useTabs: true,
45
};

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
482482
<tr>
483483
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ph-fritsche"><img src="https://avatars.githubusercontent.com/u/39068198?v=4?s=100" width="100px;" alt="Philipp Fritsche"/><br /><sub><b>Philipp Fritsche</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=ph-fritsche" title="Code">💻</a></td>
484484
<td align="center" valign="top" width="14.28%"><a href="http://zaicevas.me"><img src="https://avatars.githubusercontent.com/u/34719980?v=4?s=100" width="100px;" alt="Tomas Zaicevas"/><br /><sub><b>Tomas Zaicevas</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-testing-library/issues?q=author%3Azaicevas" title="Bug reports">🐛</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=zaicevas" title="Code">💻</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=zaicevas" title="Tests">⚠️</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=zaicevas" title="Documentation">📖</a></td>
485-
<td align="center" valign="top" width="14.28%"><a href="https://github.com/G-Rath"><img src="https://avatars.githubusercontent.com/u/3151613?v=4?s=100" width="100px;" alt="Gareth Jones"/><br /><sub><b>Gareth Jones</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=G-Rath" title="Code">💻</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=G-Rath" title="Documentation">📖</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=G-Rath" title="Tests">⚠️</a></td>
485+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/G-Rath"><img src="https://avatars.githubusercontent.com/u/3151613?v=4?s=100" width="100px;" alt="Gareth Jones"/><br /><sub><b>Gareth Jones</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=G-Rath" title="Code">💻</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=G-Rath" title="Documentation">📖</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=G-Rath" title="Tests">⚠️</a> <a href="#maintenance-G-Rath" title="Maintenance">🚧</a></td>
486486
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HonkingGoose"><img src="https://avatars.githubusercontent.com/u/34918129?v=4?s=100" width="100px;" alt="HonkingGoose"/><br /><sub><b>HonkingGoose</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=HonkingGoose" title="Documentation">📖</a> <a href="#maintenance-HonkingGoose" title="Maintenance">🚧</a></td>
487487
<td align="center" valign="top" width="14.28%"><a href="http://everlong.org/"><img src="https://avatars.githubusercontent.com/u/454175?v=4?s=100" width="100px;" alt="Julien Wajsberg"/><br /><sub><b>Julien Wajsberg</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-testing-library/issues?q=author%3Ajulienw" title="Bug reports">🐛</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=julienw" title="Code">💻</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=julienw" title="Tests">⚠️</a></td>
488488
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/maratdyatko/"><img src="https://avatars.githubusercontent.com/u/31615495?v=4?s=100" width="100px;" alt="Marat Dyatko"/><br /><sub><b>Marat Dyatko</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-testing-library/issues?q=author%3Adyatko" title="Bug reports">🐛</a> <a href="https://github.com/testing-library/eslint-plugin-testing-library/commits?author=dyatko" title="Code">💻</a></td>

lib/node-utils/index.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
TSESTree,
77
} from '@typescript-eslint/utils';
88

9+
import { getDeclaredVariables, getScope } from '../utils';
10+
911
import {
1012
isArrayExpression,
1113
isArrowFunctionExpression,
@@ -287,7 +289,7 @@ export function getVariableReferences(
287289
): TSESLint.Scope.Reference[] {
288290
if (ASTUtils.isVariableDeclarator(node)) {
289291
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
290-
return context.getDeclaredVariables(node)[0]?.references?.slice(1) ?? [];
292+
return getDeclaredVariables(context, node)[0]?.references?.slice(1) ?? [];
291293
}
292294

293295
return [];
@@ -305,7 +307,7 @@ export function getInnermostFunctionScope(
305307
asyncQueryNode: TSESTree.Identifier
306308
): InnermostFunctionScope | null {
307309
const innermostScope = ASTUtils.getInnermostScope(
308-
context.getScope(),
310+
getScope(context, asyncQueryNode),
309311
asyncQueryNode
310312
);
311313

lib/rules/consistent-data-testid.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createTestingLibraryRule } from '../create-testing-library-rule';
22
import { isJSXAttribute, isLiteral } from '../node-utils';
3+
import { getFilename } from '../utils';
34

45
export const RULE_NAME = 'consistent-data-testid';
56
export type MessageIds =
@@ -77,11 +78,10 @@ export default createTestingLibraryRule<Options, MessageIds>({
7778
},
7879

7980
create: (context, [options]) => {
80-
const { getFilename } = context;
8181
const { testIdPattern, testIdAttribute: attr, customMessage } = options;
8282

8383
function getFileNameData() {
84-
const splitPath = getFilename().split('/');
84+
const splitPath = getFilename(context).split('/');
8585
const fileNameWithExtension = splitPath.pop() ?? '';
8686
if (
8787
fileNameWithExtension.includes('[') ||

lib/rules/no-debugging-utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
isObjectPattern,
1212
isProperty,
1313
} from '../node-utils';
14-
import { DEBUG_UTILS } from '../utils';
14+
import { DEBUG_UTILS, getDeclaredVariables } from '../utils';
1515

1616
type DebugUtilsToCheckForConfig = Record<(typeof DEBUG_UTILS)[number], boolean>;
1717
type DebugUtilsToCheckFor = Partial<DebugUtilsToCheckForConfig>;
@@ -175,7 +175,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
175175

176176
const isVariableFromBuiltInConsole = builtInConsoleNodes.some(
177177
(variableDeclarator) => {
178-
const variables = context.getDeclaredVariables(variableDeclarator);
178+
const variables = getDeclaredVariables(context, variableDeclarator);
179179
return variables.some(
180180
({ name }) =>
181181
name === callExpressionIdentifier.name &&

lib/rules/no-manual-cleanup.ts

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import { ASTUtils, TSESTree, TSESLint } from '@typescript-eslint/utils';
1+
import { ASTUtils, TSESLint, TSESTree } from '@typescript-eslint/utils';
22

33
import { createTestingLibraryRule } from '../create-testing-library-rule';
44
import {
5+
getImportModuleName,
56
getVariableReferences,
7+
ImportModuleNode,
8+
isImportDeclaration,
69
isImportDefaultSpecifier,
710
isImportSpecifier,
811
isMemberExpression,
912
isObjectPattern,
1013
isProperty,
11-
ImportModuleNode,
12-
isImportDeclaration,
1314
} from '../node-utils';
15+
import { getDeclaredVariables } from '../utils';
1416

1517
export const RULE_NAME = 'no-manual-cleanup';
1618
export type MessageIds = 'noManualCleanup';
@@ -64,7 +66,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
6466
if (isImportDeclaration(moduleNode)) {
6567
// case: import utils from 'testing-library-module'
6668
if (isImportDefaultSpecifier(moduleNode.specifiers[0])) {
67-
const { references } = context.getDeclaredVariables(moduleNode)[0];
69+
const { references } = getDeclaredVariables(context, moduleNode)[0];
6870

6971
reportImportReferences(references);
7072
}
@@ -110,12 +112,15 @@ export default createTestingLibraryRule<Options, MessageIds>({
110112

111113
return {
112114
'Program:exit'() {
113-
const testingLibraryImportName = helpers.getTestingLibraryImportName();
114115
const customModuleImportNode = helpers.getCustomModuleImportNode();
115116

116-
if (testingLibraryImportName?.match(CLEANUP_LIBRARY_REGEXP)) {
117-
for (const importNode of helpers.getAllTestingLibraryImportNodes()) {
118-
reportCandidateModule(importNode);
117+
for (const testingLibraryImportNode of helpers.getAllTestingLibraryImportNodes()) {
118+
const testingLibraryImportName = getImportModuleName(
119+
testingLibraryImportNode
120+
);
121+
122+
if (testingLibraryImportName?.match(CLEANUP_LIBRARY_REGEXP)) {
123+
reportCandidateModule(testingLibraryImportNode);
119124
}
120125
}
121126

lib/rules/no-promise-in-fire-event.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
isNewExpression,
99
isPromiseIdentifier,
1010
} from '../node-utils';
11+
import { getScope } from '../utils';
1112

1213
export const RULE_NAME = 'no-promise-in-fire-event';
1314
export type MessageIds = 'noPromiseInFireEvent';
@@ -76,7 +77,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
7677

7778
if (ASTUtils.isIdentifier(node)) {
7879
const nodeVariable = ASTUtils.findVariable(
79-
context.getScope(),
80+
getScope(context, node),
8081
node.name
8182
);
8283
if (!nodeVariable) {

lib/rules/prefer-find-by.ts

+17-12
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
isObjectPattern,
1010
isProperty,
1111
} from '../node-utils';
12+
import { getScope, getSourceCode } from '../utils';
1213

1314
export const RULE_NAME = 'prefer-find-by';
1415
export type MessageIds = 'preferFindBy';
@@ -69,7 +70,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
6970
defaultOptions: [],
7071

7172
create(context, _, helpers) {
72-
const sourceCode = context.getSourceCode();
73+
const sourceCode = getSourceCode(context);
7374

7475
/**
7576
* Reports the invalid usage of wait* plus getBy/QueryBy methods and automatically fixes the scenario
@@ -118,7 +119,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
118119
isCallExpression(node.body.callee.object.arguments[0]) &&
119120
ASTUtils.isIdentifier(node.body.callee.object.arguments[0].callee)
120121
) {
121-
return node.body.callee.object.arguments[0].callee.name;
122+
return node.body.callee.object.arguments[0].callee;
122123
}
123124

124125
if (!ASTUtils.isIdentifier(node.body.callee.property)) {
@@ -134,7 +135,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
134135
node.body.callee.object.arguments[0].callee.property
135136
)
136137
) {
137-
return node.body.callee.object.arguments[0].callee.property.name;
138+
return node.body.callee.object.arguments[0].callee.property;
138139
}
139140

140141
// expect(screen.getByText).not shape
@@ -149,7 +150,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
149150
node.body.callee.object.object.arguments[0].callee.property
150151
)
151152
) {
152-
return node.body.callee.object.object.arguments[0].callee.property.name;
153+
return node.body.callee.object.object.arguments[0].callee.property;
153154
}
154155

155156
// expect(getByText).not shape
@@ -161,10 +162,10 @@ export default createTestingLibraryRule<Options, MessageIds>({
161162
node.body.callee.object.object.arguments[0].callee
162163
)
163164
) {
164-
return node.body.callee.object.object.arguments[0].callee.name;
165+
return node.body.callee.object.object.arguments[0].callee;
165166
}
166167

167-
return node.body.callee.property.name;
168+
return node.body.callee.property;
168169
}
169170

170171
function getWrongQueryName(node: TSESTree.ArrowFunctionExpression) {
@@ -177,7 +178,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
177178
ASTUtils.isIdentifier(node.body.callee) &&
178179
helpers.isSyncQuery(node.body.callee)
179180
) {
180-
return node.body.callee.name;
181+
return node.body.callee;
181182
}
182183

183184
return getWrongQueryNameInAssertion(node);
@@ -353,12 +354,14 @@ export default createTestingLibraryRule<Options, MessageIds>({
353354
}
354355

355356
// shape of () => screen.getByText
356-
const fullQueryMethod = getWrongQueryName(argument);
357+
const fullQueryMethodNode = getWrongQueryName(argument);
357358

358-
if (!fullQueryMethod) {
359+
if (!fullQueryMethodNode) {
359360
return;
360361
}
361362

363+
const fullQueryMethod = fullQueryMethodNode.name;
364+
362365
// if there is a second argument to AwaitExpression, it is the options
363366
const waitOptions = node.arguments[1];
364367
let waitOptionsSourceCode = '';
@@ -400,12 +403,14 @@ export default createTestingLibraryRule<Options, MessageIds>({
400403
}
401404

402405
// shape of () => getByText
403-
const fullQueryMethod = getWrongQueryName(argument);
406+
const fullQueryMethodNode = getWrongQueryName(argument);
404407

405-
if (!fullQueryMethod) {
408+
if (!fullQueryMethodNode) {
406409
return;
407410
}
408411

412+
const fullQueryMethod = fullQueryMethodNode.name;
413+
409414
const queryMethod = fullQueryMethod.split('By')[1];
410415
const queryVariant = getFindByQueryVariant(fullQueryMethod);
411416
const callArguments = getQueryArguments(argument.body);
@@ -434,7 +439,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
434439

435440
// this adds the findBy* declaration - adding it to the list of destructured variables { findBy* } = render()
436441
const definition = findRenderDefinitionDeclaration(
437-
context.getScope(),
442+
getScope(context, fullQueryMethodNode),
438443
fullQueryMethod
439444
);
440445
// I think it should always find it, otherwise code should not be valid (it'd be using undeclared variables)

0 commit comments

Comments
 (0)