Skip to content

feat(no-await-sync-queries): add auto-fix #919

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ module.exports = [
| [await-async-utils](docs/rules/await-async-utils.md) | Enforce promises from async utils to be awaited properly | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-vue][] | | |
| [consistent-data-testid](docs/rules/consistent-data-testid.md) | Ensures consistent usage of `data-testid` | | | |
| [no-await-sync-events](docs/rules/no-await-sync-events.md) | Disallow unnecessary `await` for sync events | ![badge-angular][] ![badge-dom][] ![badge-react][] | | |
| [no-await-sync-queries](docs/rules/no-await-sync-queries.md) | Disallow unnecessary `await` for sync queries | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-vue][] | | |
| [no-await-sync-queries](docs/rules/no-await-sync-queries.md) | Disallow unnecessary `await` for sync queries | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-vue][] | | 🔧 |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are some conflicts here, can you resolve that @neriyarde?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks.

Im getting some type errors in these files when im trying to solve the conflicts:

  • lib/create-testing-library-rule/index.ts
  • lib/rules/await-async-utils.ts
  • tools/generate-configs/utils.ts
  • lib/utils/types.ts
  • lib/utils/compat.ts

I don't remember doing any changes in these files but i still get type errors.

Since I don't know these changes and i don't want to break anythig, can I get some help solving these from someone who's familiar with these files and type?

| [no-container](docs/rules/no-container.md) | Disallow the use of `container` methods | ![badge-angular][] ![badge-marko][] ![badge-react][] ![badge-vue][] | | |
| [no-debugging-utils](docs/rules/no-debugging-utils.md) | Disallow the use of debugging utilities like `debug` | | ![badge-angular][] ![badge-marko][] ![badge-react][] ![badge-vue][] | |
| [no-dom-import](docs/rules/no-dom-import.md) | Disallow importing from DOM Testing Library | ![badge-angular][] ![badge-marko][] ![badge-react][] ![badge-vue][] | | 🔧 |
Expand Down
2 changes: 2 additions & 0 deletions docs/rules/no-await-sync-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

💼 This rule is enabled in the following configs: `angular`, `dom`, `marko`, `react`, `vue`.

🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).

<!-- end auto-generated rule header -->

Ensure that sync queries are not awaited unnecessarily.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export type TestingLibrarySettings = {

export type TestingLibraryContext<
TOptions extends readonly unknown[],
TMessageIds extends string,
TMessageIds extends string
> = Readonly<
TSESLint.RuleContext<TMessageIds, TOptions> & {
settings: TestingLibrarySettings;
Expand All @@ -45,7 +45,7 @@ export type TestingLibraryContext<
export type EnhancedRuleCreate<
TOptions extends readonly unknown[],
TMessageIds extends string,
TRuleListener extends TSESLint.RuleListener = TSESLint.RuleListener,
TRuleListener extends TSESLint.RuleListener = TSESLint.RuleListener
> = (
context: TestingLibraryContext<TOptions, TMessageIds>,
optionsWithDefault: Readonly<TOptions>,
Expand Down Expand Up @@ -156,7 +156,7 @@ export type DetectionOptions = {
export function detectTestingLibraryUtils<
TOptions extends readonly unknown[],
TMessageIds extends string,
TRuleListener extends TSESLint.RuleListener = TSESLint.RuleListener,
TRuleListener extends TSESLint.RuleListener = TSESLint.RuleListener
>(
ruleCreate: EnhancedRuleCreate<TOptions, TMessageIds, TRuleListener>,
{ skipRuleReportingCheck = false }: Partial<DetectionOptions> = {}
Expand Down
2 changes: 1 addition & 1 deletion lib/create-testing-library-rule/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
export function createTestingLibraryRule<
TOptions extends readonly unknown[],
TMessageIds extends string,
TRuleListener extends TSESLint.RuleListener = TSESLint.RuleListener,
TRuleListener extends TSESLint.RuleListener = TSESLint.RuleListener
>({
create,
detectionOptions = {},
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/await-async-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type EventModules = (typeof EVENTS_SIMULATORS)[number];
export type Options = [
{
eventModule: EventModules | EventModules[];
},
}
];

export default createTestingLibraryRule<Options, MessageIds>({
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/consistent-data-testid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type Options = [
testIdAttribute?: string[] | string;
testIdPattern: string;
customMessage?: string;
},
}
];

const FILENAME_PLACEHOLDER = '{fileName}';
Expand Down
18 changes: 16 additions & 2 deletions lib/rules/no-await-sync-queries.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TSESTree } from '@typescript-eslint/utils';
import { ASTUtils, TSESTree } from '@typescript-eslint/utils';

import { createTestingLibraryRule } from '../create-testing-library-rule';
import { getDeepestIdentifierNode } from '../node-utils';
Expand Down Expand Up @@ -26,15 +26,20 @@ export default createTestingLibraryRule<Options, MessageIds>({
'`{{ name }}` query is sync so it does not need to be awaited',
},
schema: [],
fixable: 'code',
},
defaultOptions: [],

create(context, _, helpers) {
return {
'AwaitExpression > CallExpression'(node: TSESTree.CallExpression) {
const awaitExpression = node.parent;
const deepestIdentifierNode = getDeepestIdentifierNode(node);

if (!deepestIdentifierNode) {
if (
!ASTUtils.isAwaitExpression(awaitExpression) ||
!deepestIdentifierNode
) {
return;
}

Expand All @@ -45,6 +50,15 @@ export default createTestingLibraryRule<Options, MessageIds>({
data: {
name: deepestIdentifierNode.name,
},
fix: (fixer) => {
const awaitRangeStart = awaitExpression.range[0];
const awaitRangeEnd = awaitExpression.range[0] + 'await'.length;

return fixer.replaceTextRange(
[awaitRangeStart, awaitRangeEnd],
''
);
},
});
}
},
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/no-render-in-lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type MessageIds = 'noRenderInSetup';
type Options = [
{
allowTestingFrameworkSetupHook?: string;
},
}
];

export function findClosestBeforeHook(
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/prefer-explicit-assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Options = [
{
assertion?: string;
includeFindQueries?: boolean;
},
}
];

const isAtTopLevel = (node: TSESTree.Node) =>
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/prefer-presence-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type Options = [
{
presence?: boolean;
absence?: boolean;
},
}
];

export default createTestingLibraryRule<Options, MessageIds>({
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/prefer-query-matchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type Options = [
query: 'get' | 'query';
matcher: string;
}[];
},
}
];

export default createTestingLibraryRule<Options, MessageIds>({
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/compat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ declare module '@typescript-eslint/utils/dist/ts-eslint/Rule' {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
TMessageIds extends string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
TOptions extends readonly unknown[],
TOptions extends readonly unknown[]
> {
/**
* The filename associated with the source.
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export type TestingLibraryRuleMetaDocs<TOptions extends readonly unknown[]> =
};
export type TestingLibraryRuleMeta<
TMessageIds extends string,
TOptions extends readonly unknown[],
TOptions extends readonly unknown[]
> = Omit<TSESLint.RuleMetaData<TMessageIds>, 'docs'> & {
docs: TestingLibraryRuleMetaDocs<TOptions>;
};
Expand Down
2 changes: 1 addition & 1 deletion tests/create-testing-library-rule.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ ruleTester.run(RULE_NAME, rule, {
messageId: 'renderError',
},
],
}) as const
} as const)
),
{
code: `
Expand Down
4 changes: 2 additions & 2 deletions tests/lib/FlatCompatRuleTester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class FlatCompatRuleTester extends TSESLint.RuleTester {

public override run<
TMessageIds extends string,
TOptions extends readonly unknown[],
TOptions extends readonly unknown[]
>(
ruleName: string,
rule: TSESLint.RuleModule<TMessageIds, TOptions>,
Expand All @@ -141,7 +141,7 @@ export class FlatCompatRuleTester extends TSESLint.RuleTester {
| TSESLint.RuleTesterConfig
| string
| TSESLint.ValidTestCase<unknown[]>
| TSESLint.InvalidTestCase<string, unknown[]>,
| TSESLint.InvalidTestCase<string, unknown[]>
>(config: T): T {
if (!config || !usingFlatConfig || typeof config === 'string') {
return config;
Expand Down
44 changes: 22 additions & 22 deletions tests/lib/rules/await-async-events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ ruleTester.run(RULE_NAME, rule, {
await fireEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand All @@ -448,7 +448,7 @@ ruleTester.run(RULE_NAME, rule, {
],
options: [{ eventModule: 'fireEvent' }],
output: null,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -481,7 +481,7 @@ ruleTester.run(RULE_NAME, rule, {
test('should handle external function', run)
`,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand All @@ -508,7 +508,7 @@ ruleTester.run(RULE_NAME, rule, {
await testingLibraryFireEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand All @@ -535,7 +535,7 @@ ruleTester.run(RULE_NAME, rule, {
await testingLibrary.fireEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -569,7 +569,7 @@ ruleTester.run(RULE_NAME, rule, {
await fireEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -598,7 +598,7 @@ ruleTester.run(RULE_NAME, rule, {
await fireEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -631,7 +631,7 @@ ruleTester.run(RULE_NAME, rule, {
await fireEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -664,7 +664,7 @@ ruleTester.run(RULE_NAME, rule, {
await fireEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),

...FIRE_EVENT_ASYNC_FUNCTIONS.map(
Expand Down Expand Up @@ -695,7 +695,7 @@ ruleTester.run(RULE_NAME, rule, {
const promise = await fireEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -731,7 +731,7 @@ ruleTester.run(RULE_NAME, rule, {
await triggerEvent()
})
`,
}) as const
} as const)
),
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand All @@ -756,7 +756,7 @@ ruleTester.run(RULE_NAME, rule, {
],
options: [{ eventModule: 'fireEvent' }],
output: null,
}) as const
} as const)
),
]),
...USER_EVENT_ASYNC_FRAMEWORKS.flatMap((testingFramework) => [
Expand Down Expand Up @@ -785,7 +785,7 @@ ruleTester.run(RULE_NAME, rule, {
await userEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...USER_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand All @@ -806,7 +806,7 @@ ruleTester.run(RULE_NAME, rule, {
],
options: [{ eventModule: 'userEvent' }],
output: null,
}) as const
} as const)
),
...USER_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand All @@ -833,7 +833,7 @@ ruleTester.run(RULE_NAME, rule, {
await testingLibraryUserEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...USER_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -867,7 +867,7 @@ ruleTester.run(RULE_NAME, rule, {
await userEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...USER_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -897,7 +897,7 @@ ruleTester.run(RULE_NAME, rule, {
const promise = await userEvent.${eventMethod}(getByLabelText('username'))
})
`,
}) as const
} as const)
),
...USER_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -933,7 +933,7 @@ ruleTester.run(RULE_NAME, rule, {
await triggerEvent()
})
`,
}) as const
} as const)
),
...USER_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand All @@ -958,7 +958,7 @@ ruleTester.run(RULE_NAME, rule, {
],
options: [{ eventModule: 'userEvent' }],
output: null,
}) as const
} as const)
),
...USER_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand All @@ -984,7 +984,7 @@ ruleTester.run(RULE_NAME, rule, {
condition ? null : (null, true && await userEvent.${eventMethod}(getByLabelText('username')));
});
`,
}) as const
} as const)
),
...USER_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand All @@ -1010,7 +1010,7 @@ ruleTester.run(RULE_NAME, rule, {
await (await userEvent.${eventMethod}(getByLabelText('username')) && userEvent.${eventMethod}(getByLabelText('username')));
});
`,
}) as const
} as const)
),
...USER_EVENT_ASYNC_FUNCTIONS.map(
(eventMethod) =>
Expand Down Expand Up @@ -1044,7 +1044,7 @@ ruleTester.run(RULE_NAME, rule, {
await (await userEvent.${eventMethod}(getByLabelText('username')), null);
});
`,
}) as const
} as const)
),
]),
{
Expand Down
Loading