Skip to content

chore(eslint): add mocha/no-async-suite rule and fix violations#6498

Closed
0xAxiom wants to merge 1 commit intoOpenZeppelin:masterfrom
0xAxiom:fix/eslint-no-async-describe
Closed

chore(eslint): add mocha/no-async-suite rule and fix violations#6498
0xAxiom wants to merge 1 commit intoOpenZeppelin:masterfrom
0xAxiom:fix/eslint-no-async-describe

Conversation

@0xAxiom
Copy link
Copy Markdown

@0xAxiom 0xAxiom commented May 6, 2026

Closes #4943.

What

  • Adds eslint-plugin-mocha (v11) as a dev dependency.
  • Enables the mocha/no-async-suite rule in eslint.config.mjs — this is the v11 successor to no-async-describe referenced in the issue. It flags describe('...', async function () {...}) where the async keyword has no effect and silently absorbs top-level rejections.
  • Removes async from three pre-existing violators:
    • test/token/ERC6909/ERC6909.behavior.js (line 145)
    • test/access/manager/AccessManager.test.js (line 1111)
    • test/crosschain/BridgeERC1155.behavior.js (line 30)

In each case the describe body has no top-level await, so removing async is a no-op at runtime.

Why

Per #4943, an unintended async on a describe block can mask test failures by swallowing the returned promise. The plugin rule prevents future regressions cheaply.

The issue also noted catching missing awaits would require a TypeScript migration; this PR does not attempt that broader change.

Verification

  • npm run lint:js passes.
  • Manually injected an async describe into a temp file in test/ and confirmed the rule errors with mocha/no-async-suite.
  • Ran the affected suites — all pass:
    • npx hardhat test test/access/manager/AccessManager.test.js → 489 passing.
    • npx hardhat test test/token/ERC6909/ERC6909.test.js test/crosschain/BridgeERC1155.test.js → 47 passing.

Changeset

Added a no-bump changeset (tooling-only, no public API or contract changes).

Closes OpenZeppelin#4943

Adds `eslint-plugin-mocha` and enables the `mocha/no-async-suite` rule
(formerly `no-async-describe` in older versions of the plugin). This
catches `describe('...', async function () { ... })` patterns where the
`async` keyword has no effect and silently swallows top-level errors.

Removes the unused `async` keyword from three existing call sites:
- test/token/ERC6909/ERC6909.behavior.js
- test/access/manager/AccessManager.test.js
- test/crosschain/BridgeERC1155.behavior.js

None of the three describe bodies awaited at the top level, so removing
`async` is a no-op for runtime behavior.
@0xAxiom 0xAxiom requested a review from a team as a code owner May 6, 2026 21:00
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 6, 2026

🦋 Changeset detected

Latest commit: ba1d4e5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@socket-security
Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​eslint-plugin-mocha@​11.2.010010010085100

View full report

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

Walkthrough

This pull request introduces ESLint tooling to catch unintended async usage on Mocha describe blocks. It adds eslint-plugin-mocha as a development dependency, configures the mocha/no-async-suite rule in the ESLint configuration, and documents the change in a changeset. Additionally, it updates three existing test files that previously used async describe blocks, converting them to regular functions to comply with the new rule.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding the mocha/no-async-suite ESLint rule and fixing violations across the codebase.
Description check ✅ Passed The description clearly explains what was added, why it was needed, and provides verification details. It directly relates to the changeset.
Linked Issues check ✅ Passed The PR successfully implements the core requirement from issue #4943 by adding eslint-plugin-mocha and enabling the no-async-suite rule, and fixes all pre-existing violations.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the mocha/no-async-suite ESLint rule as requested in issue #4943. No out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
eslint.config.mjs (1)

14-31: 💤 Low value

Consider scoping the Mocha plugin config to test files only.

The mocha plugin and no-async-suite rule are applied to every file in the project. While this causes no false positives today (non-test files don't use describe), best practice for ESLint flat config is to scope Mocha rules to the test directory.

♻️ Suggested scope restriction
 export default [
   js.configs.recommended,
   prettier,
   {
-    plugins: { mocha },
     languageOptions: {
       ecmaVersion: 2022,
       globals: {
         ...globals.browser,
         ...globals.mocha,
         ...globals.node,
         artifacts: 'readonly',
         contract: 'readonly',
         web3: 'readonly',
         extendEnvironment: 'readonly',
         expect: 'readonly',
       },
     },
-    rules: {
-      'mocha/no-async-suite': 'error',
-    },
   },
+  {
+    files: ['test/**/*.js'],
+    plugins: { mocha },
+    rules: {
+      'mocha/no-async-suite': 'error',
+    },
+  },
   includeIgnoreFile(path.resolve(__dirname, '.gitignore')),
 ];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@eslint.config.mjs` around lines 14 - 31, The Mocha plugin and rule (plugins:
{ mocha } and rules: { 'mocha/no-async-suite' }) are currently applied globally;
restrict them to test files by moving the mocha plugin and the
'mocha/no-async-suite' rule into an ESLint overrides entry that targets your
test file globs (e.g., tests/**/*.js, **/*.spec.js, or similar), so only files
matching those patterns get the Mocha globals and rule; update the top-level
config to remove the global mocha plugin/rule and add an overrides object
containing the same languageOptions.globals additions and the mocha plugin +
rule for the test file patterns.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@eslint.config.mjs`:
- Around line 14-31: The Mocha plugin and rule (plugins: { mocha } and rules: {
'mocha/no-async-suite' }) are currently applied globally; restrict them to test
files by moving the mocha plugin and the 'mocha/no-async-suite' rule into an
ESLint overrides entry that targets your test file globs (e.g., tests/**/*.js,
**/*.spec.js, or similar), so only files matching those patterns get the Mocha
globals and rule; update the top-level config to remove the global mocha
plugin/rule and add an overrides object containing the same
languageOptions.globals additions and the mocha plugin + rule for the test file
patterns.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5df552d5-36e0-4d74-80fc-3be1a9196df7

📥 Commits

Reviewing files that changed from the base of the PR and between 6dd405a and ba1d4e5.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • .changeset/eslint-no-async-suite.md
  • eslint.config.mjs
  • package.json
  • test/access/manager/AccessManager.test.js
  • test/crosschain/BridgeERC1155.behavior.js
  • test/token/ERC6909/ERC6909.behavior.js

@gonzaotc
Copy link
Copy Markdown
Contributor

gonzaotc commented May 6, 2026

Closing as duplicated: #6438

@gonzaotc gonzaotc closed this May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider adding an ESLint rule for no async in describe blocks

2 participants