or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

async-rules.mdconfigurations.mdexecution-rules.mdindex.mdquality-rules.mdsettings.mdstructure-rules.mdstyle-rules.md
tile.json

async-rules.mddocs/

Async Testing Rules

Rules for proper handling of asynchronous tests, callbacks, promises, and async/await patterns in Mocha test suites.

Capabilities

Handle Done Callback Rule

Enforces proper handling of done callbacks in asynchronous tests to prevent hanging tests.

/**
 * Enforces handling of callbacks for async tests
 * Prevents tests from hanging when done callback is not called
 */
const handleDoneCallbackRule = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Enforces handling of callbacks for async tests',
      url: 'https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/docs/rules/handle-done-callback.md'
    },
    schema: [{
      type: 'object',
      properties: {
        ignoreSkipped: {
          type: 'boolean',
          default: false
        }
      },
      additionalProperties: false
    }]
  },
  create: (context) => ESLintVisitor
};

Usage:

{
  "rules": {
    "mocha/handle-done-callback": ["error", { "ignoreSkipped": false }]
  }
}

Examples:

// ✓ Good - done callback is called
it('should handle async operation', function(done) {
  setTimeout(() => {
    assert.equal(1, 1);
    done();
  }, 100);
});

// ✗ Bad - done callback is never called
it('should handle async operation', function(done) {
  setTimeout(() => {
    assert.equal(1, 1);
    // Missing done() call
  }, 100);
});

No Return and Callback Rule

Prevents mixing return statements with done callbacks in the same test, which causes confusing behavior.

/**
 * Disallows both return statement and callback usage in the same test
 * Prevents confusing async test patterns
 */
const noReturnAndCallbackRule = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Disallow return statements in tests with callbacks',
      url: 'https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/docs/rules/no-return-and-callback.md'
    },
    schema: []
  },
  create: (context) => ESLintVisitor
};

Usage:

{
  "rules": {
    "mocha/no-return-and-callback": "error"
  }
}

Examples:

// ✓ Good - using only done callback
it('should handle async operation', function(done) {
  doAsync(() => {
    assert.equal(1, 1);
    done();
  });
});

// ✓ Good - using only return statement with promise
it('should handle async operation', function() {
  return doAsync().then(result => {
    assert.equal(result, 1);
  });
});

// ✗ Bad - mixing return and callback
it('should handle async operation', function(done) {
  return doAsync(() => {
    assert.equal(1, 1);
    done();
  });
});

No Return From Async Rule

Disallows return statements in async tests when using done callbacks, which can cause unexpected behavior.

/**
 * Disallows return statements in async tests with done callbacks
 * Prevents confusing test execution patterns
 */
const noReturnFromAsyncRule = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Disallow return statements in tests with done callback',
      url: 'https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/docs/rules/no-return-from-async.md'
    },
    schema: []
  },
  create: (context) => ESLintVisitor
};

Usage:

{
  "rules": {
    "mocha/no-return-from-async": "error"
  }
}

No Synchronous Tests Rule

Disallows synchronous tests when async testing is expected, enforcing consistent async patterns.

/**
 * Disallows synchronous tests
 * Enforces consistent async test patterns
 */
const noSynchronousTestsRule = {
  meta: {
    type: 'suggestion',
    docs: {
      description: 'Disallow synchronous tests',
      url: 'https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/docs/rules/no-synchronous-tests.md'
    },
    schema: []
  },
  create: (context) => ESLintVisitor
};

Usage:

{
  "rules": {
    "mocha/no-synchronous-tests": "error"
  }
}

Examples:

// ✓ Good - async test with done callback
it('should handle operation', function(done) {
  doSomething(done);
});

// ✓ Good - async test with promise return
it('should handle operation', function() {
  return doSomethingAsync();
});

// ✓ Good - async test with async/await
it('should handle operation', async function() {
  await doSomethingAsync();
});

// ✗ Bad - synchronous test
it('should handle operation', function() {
  const result = doSomething();
  assert.equal(result, 1);
});

Usage Examples

Comprehensive Async Testing Setup

{
  "rules": {
    "mocha/handle-done-callback": "error",
    "mocha/no-return-and-callback": "error",
    "mocha/no-return-from-async": "error",
    "mocha/no-synchronous-tests": "off"
  }
}

Strict Async Enforcement

{
  "rules": {
    "mocha/handle-done-callback": ["error", { "ignoreSkipped": true }],
    "mocha/no-return-and-callback": "error",
    "mocha/no-return-from-async": "error",
    "mocha/no-synchronous-tests": "error"
  }
}

Common Async Patterns

// Promise-based async test
it('should resolve promise', function() {
  return fetchData().then(data => {
    expect(data).to.exist;
  });
});

// Async/await pattern
it('should handle async operation', async function() {
  const result = await processData();
  expect(result).to.equal('processed');
});

// Callback-based async test
it('should handle callback', function(done) {
  processWithCallback((err, result) => {
    if (err) return done(err);
    expect(result).to.be.ok;
    done();
  });
});

// Error handling with done callback
it('should handle errors', function(done) {
  processWithCallback((err, result) => {
    expect(err).to.be.null;
    expect(result).to.exist;
    done();
  });
});