# bun:test/no-done-callback

> Disallow the `done` callback in tests and hooks in favor of promises

A test that takes a `done` parameter waits until `done()` is called. If some code path never calls it, the test hangs until it times out, and the timeout doesn't tell you why. An `async` test, or one that returns a promise, ends when the promise settles. If the promise rejects, the test fails with that error.

The parameter's name doesn't matter. Any test or hook callback with exactly one parameter is reported.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"bun:test/no-done-callback" = "error" # or "warn"
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}
```ts
import { expect, test } from "bun:test";

test("reads the config", done => {
  readConfig((error, config) => {
    expect(config.port).toBe(3000);
    done();
  });
});
```

Not reported:

{/* good */}
```ts
import { expect, test } from "bun:test";

test("reads the config", async () => {
  const config = await readConfig();
  expect(config.port).toBe(3000);
});
```

If the API only takes a callback, wrap it in a promise:

{/* good */}
```ts
import { afterAll } from "bun:test";

afterAll(() => new Promise(resolve => server.close(resolve)));
```

The `test.each([...])` callback isn't checked, because its parameters are the row's values:

{/* good */}
```ts
import { expect, test } from "bun:test";

test.each([1, 2, 3])("%i is positive", value => {
  expect(value).toBeGreaterThan(0);
});
```
