0.2.0 - Mid migration

This commit is contained in:
Daniel Mason 2022-04-25 14:47:15 +12:00
parent 139e6a915e
commit 7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions

View file

@ -0,0 +1,89 @@
# Have control over `test` and `it` usages (`consistent-test-it`)
Jest allows you to choose how you want to define your tests, using the `it` or
the `test` keywords, with multiple permutations for each:
- **it:** `it`, `xit`, `fit`, `it.only`, `it.skip`.
- **test:** `test`, `xtest`, `test.only`, `test.skip`.
This rule gives you control over the usage of these keywords in your codebase.
## Rule Details
This rule can be configured as follows
```json5
{
type: 'object',
properties: {
fn: {
enum: ['it', 'test'],
},
withinDescribe: {
enum: ['it', 'test'],
},
},
additionalProperties: false,
}
```
#### fn
Decides whether to use `test` or `it`.
#### withinDescribe
Decides whether to use `test` or `it` within a `describe` scope.
```js
/*eslint jest/consistent-test-it: ["error", {"fn": "test"}]*/
test('foo'); // valid
test.only('foo'); // valid
it('foo'); // invalid
it.only('foo'); // invalid
```
```js
/*eslint jest/consistent-test-it: ["error", {"fn": "it"}]*/
it('foo'); // valid
it.only('foo'); // valid
test('foo'); // invalid
test.only('foo'); // invalid
```
```js
/*eslint jest/consistent-test-it: ["error", {"fn": "it", "withinDescribe": "test"}]*/
it('foo'); // valid
describe('foo', function () {
test('bar'); // valid
});
test('foo'); // invalid
describe('foo', function () {
it('bar'); // invalid
});
```
### Default configuration
The default configuration forces all top-level tests to use `test` and all tests
nested within `describe` to use `it`.
```js
/*eslint jest/consistent-test-it: ["error"]*/
test('foo'); // valid
describe('foo', function () {
it('bar'); // valid
});
it('foo'); // invalid
describe('foo', function () {
test('bar'); // invalid
});
```

View file

@ -0,0 +1,104 @@
# Enforce assertion to be made in a test body (`expect-expect`)
Ensure that there is at least one `expect` call made in a test.
## Rule details
This rule triggers when there is no call made to `expect` in a test, to prevent
users from forgetting to add assertions.
Examples of **incorrect** code for this rule:
```js
it('should be a test', () => {
console.log('no assertion');
});
test('should assert something', () => {});
```
Examples of **correct** code for this rule:
```js
it('should be a test', () => {
expect(true).toBeDefined();
});
it('should work with callbacks/async', () => {
somePromise().then(res => expect(res).toBe('passed'));
});
```
## Options
```json
{
"jest/expect-expect": [
"error",
{
"assertFunctionNames": ["expect"]
}
]
}
```
### `assertFunctionNames`
This array option specifies the names of functions that should be considered to
be asserting functions. Function names can use wildcards i.e `request.*.expect`,
`request.**.expect`, `request.*.expect*`
Examples of **incorrect** code for the `{ "assertFunctionNames": ["expect"] }`
option:
```js
/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect"] }] */
import { expectSaga } from 'redux-saga-test-plan';
import { addSaga } from '../src/sagas';
test('returns sum', () => {
expectSaga(addSaga, 1, 1).returns(2).run();
});
```
Examples of **correct** code for the
`{ "assertFunctionNames": ["expect", "expectSaga"] }` option:
```js
/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "expectSaga"] }] */
import { expectSaga } from 'redux-saga-test-plan';
import { addSaga } from '../src/sagas';
test('returns sum', () => {
expectSaga(addSaga, 1, 1).returns(2).run();
});
```
Since the string is compiled into a regular expression, you'll need to escape
special characters such as `$` with a double backslash:
```js
/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect\\$"] }] */
it('is money-like', () => {
expect$(1.0);
});
```
Examples of **correct** code for working with the HTTP assertions library
[SuperTest](https://www.npmjs.com/package/supertest) with the
`{ "assertFunctionNames": ["expect", "request.**.expect"] }` option:
```js
/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "request.**.expect"] }] */
const request = require('supertest');
const express = require('express');
const app = express();
describe('GET /user', function () {
it('responds with json', function (done) {
request(app).get('/user').expect('Content-Type', /json/).expect(200, done);
});
});
```

View file

@ -0,0 +1,106 @@
# Enforce lowercase test names (`lowercase-name`)
## Rule details
Enforce `it`, `test` and `describe` to have descriptions that begin with a
lowercase letter. This provides more readable test failures. This rule is not
enabled by default.
The following pattern is considered a warning:
```js
it('Adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
```
The following pattern is not considered a warning:
```js
it('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
```
## Options
```json
{
"jest/lowercase-name": [
"error",
{
"ignore": ["describe", "test"]
}
]
}
```
### `ignore`
This array option controls which Jest functions are checked by this rule. There
are three possible values:
- `"describe"`
- `"test"`
- `"it"`
By default, none of these options are enabled (the equivalent of
`{ "ignore": [] }`).
Example of **correct** code for the `{ "ignore": ["describe"] }` option:
```js
/* eslint jest/lowercase-name: ["error", { "ignore": ["describe"] }] */
describe('Uppercase description');
```
Example of **correct** code for the `{ "ignore": ["test"] }` option:
```js
/* eslint jest/lowercase-name: ["error", { "ignore": ["test"] }] */
test('Uppercase description');
```
Example of **correct** code for the `{ "ignore": ["it"] }` option:
```js
/* eslint jest/lowercase-name: ["error", { "ignore": ["it"] }] */
it('Uppercase description');
```
### `allowedPrefixes`
This array option allows specifying prefixes which contain capitals that titles
can start with. This can be useful when writing tests for api endpoints, where
you'd like to prefix with the HTTP method.
By default, nothing is allowed (the equivalent of `{ "allowedPrefixes": [] }`).
Example of **correct** code for the `{ "allowedPrefixes": ["GET"] }` option:
```js
/* eslint jest/lowercase-name: ["error", { "allowedPrefixes": ["GET"] }] */
describe('GET /live');
```
### `ignoreTopLevelDescribe`
This option can be set to allow only the top-level `describe` blocks to have a
title starting with an upper-case letter.
Example of **correct** code for the `{ "ignoreTopLevelDescribe": true }` option:
```js
/* eslint jest/lowercase-name: ["error", { "ignoreTopLevelDescribe": true }] */
describe('MyClass', () => {
describe('#myMethod', () => {
it('does things', () => {
//
});
});
});
```

View file

@ -0,0 +1,131 @@
# Enforces a maximum depth to nested describe calls (`max-nested-describe`)
While it's useful to be able to group your tests together within the same file
using `describe()`, having too many levels of nesting throughout your tests make
them difficult to read.
## Rule Details
This rule enforces a maximum depth to nested `describe()` calls to improve code
clarity in your tests.
The following patterns are considered warnings (with the default option of
`{ "max": 5 } `):
```js
describe('foo', () => {
describe('bar', () => {
describe('baz', () => {
describe('qux', () => {
describe('quxx', () => {
describe('too many', () => {
it('should get something', () => {
expect(getSomething()).toBe('Something');
});
});
});
});
});
});
});
describe('foo', function () {
describe('bar', function () {
describe('baz', function () {
describe('qux', function () {
describe('quxx', function () {
describe('too many', function () {
it('should get something', () => {
expect(getSomething()).toBe('Something');
});
});
});
});
});
});
});
```
The following patterns are **not** considered warnings (with the default option
of `{ "max": 5 } `):
```js
describe('foo', () => {
describe('bar', () => {
it('should get something', () => {
expect(getSomething()).toBe('Something');
});
});
describe('qux', () => {
it('should get something', () => {
expect(getSomething()).toBe('Something');
});
});
});
describe('foo2', function () {
it('should get something', () => {
expect(getSomething()).toBe('Something');
});
});
describe('foo', function () {
describe('bar', function () {
describe('baz', function () {
describe('qux', function () {
describe('this is the limit', function () {
it('should get something', () => {
expect(getSomething()).toBe('Something');
});
});
});
});
});
});
```
## Options
```json
{
"jest/max-nested-describe": [
"error",
{
"max": 5
}
]
}
```
### `max`
Enforces a maximum depth for nested `describe()`.
This has a default value of `5`.
Examples of patterns **not** considered warnings with options set to
`{ "max": 2 }`:
```js
describe('foo', () => {
describe('bar', () => {
it('should get something', () => {
expect(getSomething()).toBe('Something');
});
});
});
describe('foo2', function()) {
describe('bar2', function() {
it('should get something', function() {
expect(getSomething()).toBe('Something');
});
it('should get else', function() {
expect(getSomething()).toBe('Something');
});
});
});
```

View file

@ -0,0 +1,46 @@
# Disallow alias methods (`no-alias-methods`)
Several Jest methods have alias names, such as `toThrow` having the alias of
`toThrowError`. This rule ensures that only the canonical name as used in the
Jest documentation is used in the code. This makes it easier to search for all
occurrences of the method within code, and it ensures consistency among the
method names used.
## Rule details
This rule triggers a warning if the alias name, rather than the canonical name,
of a method is used.
### Default configuration
The following patterns are considered warnings:
```js
expect(a).toBeCalled();
expect(a).toBeCalledTimes();
expect(a).toBeCalledWith();
expect(a).lastCalledWith();
expect(a).nthCalledWith();
expect(a).toReturn();
expect(a).toReturnTimes();
expect(a).toReturnWith();
expect(a).lastReturnedWith();
expect(a).nthReturnedWith();
expect(a).toThrowError();
```
The following patterns are not considered warnings:
```js
expect(a).toHaveBeenCalled();
expect(a).toHaveBeenCalledTimes();
expect(a).toHaveBeenCalledWith();
expect(a).toHaveBeenLastCalledWith();
expect(a).toHaveBeenNthCalledWith();
expect(a).toHaveReturned();
expect(a).toHaveReturnedTimes();
expect(a).toHaveReturnedWith();
expect(a).toHaveLastReturnedWith();
expect(a).toHaveNthReturnedWith();
expect(a).toThrow();
```

View file

@ -0,0 +1,61 @@
# Disallow commented out tests (`no-commented-out-tests`)
This rule raises a warning about commented out tests. It's similar to
no-disabled-tests rule.
## Rule Details
The rule uses fuzzy matching to do its best to determine what constitutes a
commented out test, checking for a presence of `it(`, `describe(`, `it.skip(`,
etc. in code comments.
The following patterns are considered warnings:
```js
// describe('foo', () => {});
// it('foo', () => {});
// test('foo', () => {});
// describe.skip('foo', () => {});
// it.skip('foo', () => {});
// test.skip('foo', () => {});
// describe['skip']('bar', () => {});
// it['skip']('bar', () => {});
// test['skip']('bar', () => {});
// xdescribe('foo', () => {});
// xit('foo', () => {});
// xtest('foo', () => {});
/*
describe('foo', () => {});
*/
```
These patterns would not be considered warnings:
```js
describe('foo', () => {});
it('foo', () => {});
test('foo', () => {});
describe.only('bar', () => {});
it.only('bar', () => {});
test.only('bar', () => {});
// foo('bar', () => {});
```
### Limitations
The plugin looks at the literal function names within test code, so will not
catch more complex examples of commented out tests, such as:
```js
// const testSkip = test.skip;
// testSkip('skipped test', () => {});
// const myTest = test;
// myTest('does not have function body');
```

View file

@ -0,0 +1,81 @@
# Prevent calling `expect` conditionally (`no-conditional-expect`)
This rule prevents the use of `expect` in conditional blocks, such as `if`s &
`catch`s.
This includes using `expect` in callbacks to functions named `catch`, which are
assumed to be promises.
## Rule Details
Jest considered a test to have failed if it throws an error, rather than on if
any particular function is called, meaning conditional calls to `expect` could
result in tests silently being skipped.
Additionally, conditionals tend to make tests more brittle and complex, as they
increase the amount of mental thinking needed to understand what is actually
being tested.
While `expect.assertions` & `expect.hasAssertions` can help prevent tests from
silently being skipped, when combined with conditionals they typically result in
even more complexity being introduced.
The following patterns are warnings:
```js
it('foo', () => {
doTest && expect(1).toBe(2);
});
it('bar', () => {
if (!skipTest) {
expect(1).toEqual(2);
}
});
it('baz', async () => {
try {
await foo();
} catch (err) {
expect(err).toMatchObject({ code: 'MODULE_NOT_FOUND' });
}
});
it('throws an error', async () => {
await foo().catch(error => expect(error).toBeInstanceOf(error));
});
```
The following patterns are not warnings:
```js
it('foo', () => {
expect(!value).toBe(false);
});
function getValue() {
if (process.env.FAIL) {
return 1;
}
return 2;
}
it('foo', () => {
expect(getValue()).toBe(2);
});
it('validates the request', () => {
try {
processRequest(request);
} catch {
// ignore errors
} finally {
expect(validRequest).toHaveBeenCalledWith(request);
}
});
it('throws an error', async () => {
await expect(foo).rejects.toThrow(Error);
});
```

View file

@ -0,0 +1,46 @@
# Disallow use of deprecated functions (`no-deprecated-functions`)
Over the years Jest has accrued some debt in the form of functions that have
either been renamed for clarity, or replaced with more powerful APIs.
While typically these deprecated functions are kept in the codebase for a number
of majors, eventually they are removed completely.
## Rule details
This rule warns about calls to deprecated functions, and provides details on
what to replace them with, based on the version of Jest that is installed.
This rule can also autofix a number of these deprecations for you.
### `jest.resetModuleRegistry`
This function was renamed to `resetModules` in Jest 15, and is scheduled for
removal in Jest 27.
### `jest.addMatchers`
This function was replaced with `expect.extend` in Jest 17, and is scheduled for
removal in Jest 27.
### `require.requireActual` & `require.requireMock`
These functions were replaced in Jest 21 and removed in Jest 26.
Originally, the `requireActual` & `requireMock` the `requireActual`&
`requireMock` functions were placed onto the `require` function.
These functions were later moved onto the `jest` object in order to be easier
for type checkers to handle, and their use via `require` deprecated. Finally,
the release of Jest 26 saw them removed from the `require` function all
together.
### `jest.runTimersToTime`
This function was renamed to `advanceTimersByTime` in Jest 22, and is scheduled
for removal in Jest 27.
### `jest.genMockFromModule`
This function was renamed to `createMockFromModule` in Jest 26, and is scheduled
for removal in a future version of Jest.

View file

@ -0,0 +1,65 @@
# Disallow disabled tests (`no-disabled-tests`)
Jest has a feature that allows you to temporarily mark tests as disabled. This
feature is often helpful while debugging or to create placeholders for future
tests. Before committing changes we may want to check that all tests are
running.
This rule raises a warning about disabled tests.
## Rule Details
There are a number of ways to disable tests in Jest:
- by appending `.skip` to the test-suite or test-case
- by prepending the test function name with `x`
- by declaring a test with a name but no function body
- by making a call to `pending()` anywhere within the test
The following patterns are considered warnings:
```js
describe.skip('foo', () => {});
it.skip('foo', () => {});
test.skip('foo', () => {});
describe['skip']('bar', () => {});
it['skip']('bar', () => {});
test['skip']('bar', () => {});
xdescribe('foo', () => {});
xit('foo', () => {});
xtest('foo', () => {});
it('bar');
test('bar');
it('foo', () => {
pending();
});
```
These patterns would not be considered warnings:
```js
describe('foo', () => {});
it('foo', () => {});
test('foo', () => {});
describe.only('bar', () => {});
it.only('bar', () => {});
test.only('bar', () => {});
```
### Limitations
The plugin looks at the literal function names within test code, so will not
catch more complex examples of disabled tests, such as:
```js
const testSkip = test.skip;
testSkip('skipped test', () => {});
const myTest = test;
myTest('does not have function body');
```

View file

@ -0,0 +1,90 @@
# Avoid using a callback in asynchronous tests and hooks (`no-done-callback`)
When calling asynchronous code in hooks and tests, `jest` needs to know when the
asynchronous work is complete to progress the current run.
Originally the most common pattern to archive this was to use callbacks:
```js
test('the data is peanut butter', done => {
function callback(data) {
try {
expect(data).toBe('peanut butter');
done();
} catch (error) {
done(error);
}
}
fetchData(callback);
});
```
This can be very error prone however, as it requires careful understanding of
how assertions work in tests or otherwise tests won't behave as expected.
For example, if the `try/catch` was left out of the above code, the test would
timeout rather than fail. Even with the `try/catch`, forgetting to pass the
caught error to `done` will result in `jest` believing the test has passed.
A more straightforward way to handle asynchronous code is to use Promises:
```js
test('the data is peanut butter', () => {
return fetchData().then(data => {
expect(data).toBe('peanut butter');
});
});
```
When a test or hook returns a promise, `jest` waits for that promise to resolve,
as well as automatically failing should the promise reject.
If your environment supports `async/await`, this becomes even simpler:
```js
test('the data is peanut butter', async () => {
const data = await fetchData();
expect(data).toBe('peanut butter');
});
```
## Rule details
This rule checks the function parameter of hooks & tests for use of the `done`
argument, suggesting you return a promise instead.
The following patterns are considered warnings:
```js
beforeEach(done => {
// ...
});
test('myFunction()', done => {
// ...
});
test('myFunction()', function (done) {
// ...
});
```
The following patterns are not considered warnings:
```js
beforeEach(async () => {
await setupUsTheBomb();
});
test('myFunction()', () => {
expect(myFunction()).toBeTruthy();
});
test('myFunction()', () => {
return new Promise(done => {
expect(myFunction()).toBeTruthy();
done();
});
});
```

View file

@ -0,0 +1,75 @@
# Disallow duplicate setup and teardown hooks (`no-duplicate-hooks`)
A `describe` block should not contain duplicate hooks.
## Rule Details
Examples of **incorrect** code for this rule
```js
/* eslint jest/no-duplicate-hooks: "error" */
describe('foo', () => {
beforeEach(() => {
// some setup
});
beforeEach(() => {
// some setup
});
test('foo_test', () => {
// some test
});
});
// Nested describe scenario
describe('foo', () => {
beforeEach(() => {
// some setup
});
test('foo_test', () => {
// some test
});
describe('bar', () => {
test('bar_test', () => {
afterAll(() => {
// some teardown
});
afterAll(() => {
// some teardown
});
});
});
});
```
Examples of **correct** code for this rule
```js
/* eslint jest/no-duplicate-hooks: "error" */
describe('foo', () => {
beforeEach(() => {
// some setup
});
test('foo_test', () => {
// some test
});
});
// Nested describe scenario
describe('foo', () => {
beforeEach(() => {
// some setup
});
test('foo_test', () => {
// some test
});
describe('bar', () => {
test('bar_test', () => {
beforeEach(() => {
// some setup
});
});
});
});
```

View file

@ -0,0 +1,47 @@
# Avoid using `expect().resolves` (`no-expect-resolves`)
## Deprecated
This rule has been deprecated in favor of
[`no-restricted-matchers`](no-restricted-matchers.md) with the following config:
```json
{
"rules": {
"jest/no-restricted-matchers": [
"error",
{ "resolves": "Use `expect(await promise)` instead." }
]
}
}
```
---
Jest allows you to test a promise resolve value using `await expect().resolves`.
For consistency and readability this rule bans `expect().resolves` in favor of
`expect(await promise)`.
## Rule details
This rule triggers a warning if `expect().resolves` is used.
This rule is disabled by default.
### Default configuration
The following patterns is considered warning:
```js
test('some test', async () => {
await expect(Promise.resolve(1)).resolves.toBe(1);
});
```
The following pattern is not considered warning:
```js
test('some test', async () => {
expect(await Promise.resolve(1)).toBe(1);
});
```

View file

@ -0,0 +1,45 @@
# Disallow using `exports` in files containing tests (`no-export`)
Prevents using `exports` if a file has one or more tests in it.
## Rule Details
This rule aims to eliminate duplicate runs of tests by exporting things from
test files. If you import from a test file, then all the tests in that file will
be run in each imported instance, so bottom line, don't export from a test, but
instead move helper functions into a separate file when they need to be shared
across tests.
Examples of **incorrect** code for this rule:
```js
export function myHelper() {}
module.exports = function () {};
module.exports = {
something: 'that should be moved to a non-test file',
};
describe('a test', () => {
expect(1).toBe(1);
});
```
Examples of **correct** code for this rule:
```js
function myHelper() {}
const myThing = {
something: 'that can live here',
};
describe('a test', () => {
expect(1).toBe(1);
});
```
## When Not To Use It
Don't use this rule on non-jest test files.

View file

@ -0,0 +1,56 @@
# Disallow focused tests (`no-focused-tests`)
Jest has a feature that allows you to focus tests by appending `.only` or
prepending `f` to a test-suite or a test-case. This feature is really helpful to
debug a failing test, so you dont have to execute all of your tests. After you
have fixed your test and before committing the changes you have to remove
`.only` to ensure all tests are executed on your build system.
This rule reminds you to remove `.only` from your tests by raising a warning
whenever you are using the exclusivity feature.
## Rule Details
This rule looks for every `describe.only`, `it.only`, `test.only`, `fdescribe`,
and `fit` occurrences within the source code. Of course there are some
edge-cases which cant be detected by this rule e.g.:
```js
const describeOnly = describe.only;
describeOnly.apply(describe);
```
The following patterns are considered warnings:
```js
describe.only('foo', () => {});
it.only('foo', () => {});
describe['only']('bar', () => {});
it['only']('bar', () => {});
test.only('foo', () => {});
test['only']('bar', () => {});
fdescribe('foo', () => {});
fit('foo', () => {});
fit.each`
table
`();
```
These patterns would not be considered warnings:
```js
describe('foo', () => {});
it('foo', () => {});
describe.skip('bar', () => {});
it.skip('bar', () => {});
test('foo', () => {});
test.skip('bar', () => {});
it.each()();
it.each`
table
`();
test.each()();
test.each`
table
`();
```

View file

@ -0,0 +1,174 @@
# Disallow setup and teardown hooks (`no-hooks`)
Jest provides global functions for setup and teardown tasks, which are called
before/after each test case and each test suite. The use of these hooks promotes
shared state between tests.
## Rule Details
This rule reports for the following function calls:
- `beforeAll`
- `beforeEach`
- `afterAll`
- `afterEach`
Examples of **incorrect** code for this rule:
```js
/* eslint jest/no-hooks: "error" */
function setupFoo(options) {
/* ... */
}
function setupBar(options) {
/* ... */
}
describe('foo', () => {
let foo;
beforeEach(() => {
foo = setupFoo();
});
afterEach(() => {
foo = null;
});
it('does something', () => {
expect(foo.doesSomething()).toBe(true);
});
describe('with bar', () => {
let bar;
beforeEach(() => {
bar = setupBar();
});
afterEach(() => {
bar = null;
});
it('does something with bar', () => {
expect(foo.doesSomething(bar)).toBe(true);
});
});
});
```
Examples of **correct** code for this rule:
```js
/* eslint jest/no-hooks: "error" */
function setupFoo(options) {
/* ... */
}
function setupBar(options) {
/* ... */
}
describe('foo', () => {
it('does something', () => {
const foo = setupFoo();
expect(foo.doesSomething()).toBe(true);
});
it('does something with bar', () => {
const foo = setupFoo();
const bar = setupBar();
expect(foo.doesSomething(bar)).toBe(true);
});
});
```
## Options
```json
{
"jest/no-hooks": [
"error",
{
"allow": ["afterEach", "afterAll"]
}
]
}
```
### `allow`
This array option controls which Jest hooks are checked by this rule. There are
four possible values:
- `"beforeAll"`
- `"beforeEach"`
- `"afterAll"`
- `"afterEach"`
By default, none of these options are enabled (the equivalent of
`{ "allow": [] }`).
Examples of **incorrect** code for the `{ "allow": ["afterEach"] }` option:
```js
/* eslint jest/no-hooks: ["error", { "allow": ["afterEach"] }] */
function setupFoo(options) {
/* ... */
}
let foo;
beforeEach(() => {
foo = setupFoo();
});
afterEach(() => {
jest.resetModules();
});
test('foo does this', () => {
// ...
});
test('foo does that', () => {
// ...
});
```
Examples of **correct** code for the `{ "allow": ["afterEach"] }` option:
```js
/* eslint jest/no-hooks: ["error", { "allow": ["afterEach"] }] */
function setupFoo(options) {
/* ... */
}
afterEach(() => {
jest.resetModules();
});
test('foo does this', () => {
const foo = setupFoo();
// ...
});
test('foo does that', () => {
const foo = setupFoo();
// ...
});
```
## When Not To Use It
If you prefer using the setup and teardown hooks provided by Jest, you can
safely disable this rule.
## Further Reading
- [Jest docs - Setup and Teardown](https://facebook.github.io/jest/docs/en/setup-teardown.html)

View file

@ -0,0 +1,52 @@
# Disallow identical titles (`no-identical-title`)
Having identical titles for two different tests or test suites may create
confusion. For example, when a test with the same title as another test in the
same test suite fails, it is harder to know which one failed and thus harder to
fix.
## Rule Details
This rule looks at the title of every test and test suites. It will report when
two test suites or two test cases at the same level of a test suite have the
same title.
The following patterns are considered warnings:
```js
describe('foo', () => {
it('should do bar', () => {});
it('should do bar', () => {}); // Has the same title as the previous test
describe('baz', () => {
// ...
});
describe('baz', () => {
// Has the same title as a previous test suite
// ...
});
});
```
These patterns would not be considered warnings:
```js
describe('foo', () => {
it('should do foo', () => {});
it('should do bar', () => {});
// Has the same name as a parent test suite, which is fine
describe('foo', () => {
// Has the same name as a test in a parent test suite, which is fine
it('should do foo', () => {});
it('should work', () => {});
});
describe('baz', () => {
// Has the same title as a previous test suite
// Has the same name as a test in a sibling test suite, which is fine
it('should work', () => {});
});
});
```

View file

@ -0,0 +1,53 @@
# Disallow conditional logic (`no-if`)
Conditional logic in tests is usually an indication that a test is attempting to
cover too much, and not testing the logic it intends to. Each branch of code
executing within an if statement will usually be better served by a test devoted
to it.
Conditionals are often used to satisfy the typescript type checker. In these
cases, using the non-null assertion operator (!) would be best.
## Rule Details
This rule prevents the use of if/ else statements and conditional (ternary)
operations in tests.
The following patterns are considered warnings:
```js
it('foo', () => {
if ('bar') {
// an if statement here is invalid
// you are probably testing too much
}
});
it('foo', () => {
const bar = foo ? 'bar' : null;
});
```
These patterns would not be considered warnings:
```js
it('foo', () => {
// only test the 'foo' case
});
it('bar', () => {
// test the 'bar' case separately
});
it('foo', () => {
function foo(bar) {
// nested functions are valid
return foo ? bar : null;
}
});
```
## When Not To Use It
If you do not wish to prevent the use of if statements in tests, you can safely
disable this rule.

View file

@ -0,0 +1,60 @@
# Disallow string interpolation inside snapshots (`no-interpolation-in-snapshots`)
Prevents the use of string interpolations in snapshots.
## Rule Details
Interpolation prevents snapshots from being updated. Instead, properties should
be overloaded with a matcher by using
[property matchers](https://jestjs.io/docs/en/snapshot-testing#property-matchers).
Examples of **incorrect** code for this rule:
```js
expect(something).toMatchInlineSnapshot(
`Object {
property: ${interpolated}
}`,
);
expect(something).toMatchInlineSnapshot(
{ other: expect.any(Number) },
`Object {
other: Any<Number>,
property: ${interpolated}
}`,
);
expect(errorThrowingFunction).toThrowErrorMatchingInlineSnapshot(
`${interpolated}`,
);
```
Examples of **correct** code for this rule:
```js
expect(something).toMatchInlineSnapshot();
expect(something).toMatchInlineSnapshot(
`Object {
property: 1
}`,
);
expect(something).toMatchInlineSnapshot(
{ property: expect.any(Date) },
`Object {
property: Any<Date>
}`,
);
expect(errorThrowingFunction).toThrowErrorMatchingInlineSnapshot();
expect(errorThrowingFunction).toThrowErrorMatchingInlineSnapshot(
`Error Message`,
);
```
## When Not To Use It
Don't use this rule on non-jest test files.

View file

@ -0,0 +1,59 @@
# Disallow Jasmine globals (`no-jasmine-globals`)
`jest` uses `jasmine` as a test runner. A side effect of this is that both a
`jasmine` object, and some jasmine-specific globals, are exposed to the test
environment. Most functionality offered by Jasmine has been ported to Jest, and
the Jasmine globals will stop working in the future. Developers should therefore
migrate to Jest's documented API instead of relying on the undocumented Jasmine
API.
### Rule details
This rule reports on any usage of Jasmine globals which is not ported to Jest,
and suggests alternative from Jest's own API.
### Default configuration
The following patterns are considered warnings:
```js
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
test('my test', () => {
pending();
});
test('my test', () => {
fail();
});
test('my test', () => {
spyOn(some, 'object');
});
test('my test', () => {
jasmine.createSpy();
});
test('my test', () => {
expect('foo').toEqual(jasmine.anything());
});
```
The following patterns would not be considered warnings:
```js
jest.setTimeout(5000);
test('my test', () => {
jest.spyOn(some, 'object');
});
test('my test', () => {
jest.fn();
});
test('my test', () => {
expect('foo').toEqual(expect.anything());
});
```

View file

@ -0,0 +1,20 @@
# Disallow importing Jest (`no-jest-import`)
The `jest` object is automatically in scope within every test file. The methods
in the `jest` object help create mocks and let you control Jest's overall
behavior. It is therefore completely unnecessary to import in `jest`, as Jest
doesn't export anything in the first place.
### Rule details
This rule reports on any importing of Jest.
To name a few: `var jest = require('jest');` `const jest = require('jest');`
`import jest from 'jest';` `import {jest as test} from 'jest';`
There is no correct usage of this code, other than to not import `jest` in the
first place.
## Further Reading
\*[The Jest Object](https://facebook.github.io/jest/docs/en/jest-object.html)

View file

@ -0,0 +1,172 @@
# disallow large snapshots (`no-large-snapshots`)
When using Jest's snapshot capability one should be mindful of the size of
created snapshots. As a general best practice snapshots should be limited in
size in order to be more manageable and reviewable. A stored snapshot is only as
good as its review and as such keeping it short, sweet, and readable is
important to allow for thorough reviews.
## Usage
Because Jest snapshots are written with back-ticks (\` \`) which are only valid
with
[ES2015 onwards](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
you should set `parserOptions` in your config to at least allow ES2015 in order
to use this rule:
```js
module.exports = {
parserOptions: {
ecmaVersion: 2015,
},
};
```
## Rule Details
This rule looks at all Jest inline and external snapshots (files with `.snap`
extension) and validates that each stored snapshot within those files does not
exceed 50 lines (by default, this is configurable as explained in `Options`
section below).
Example of **incorrect** code for this rule:
```js
exports[`a large snapshot 1`] = `
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10
line 11
line 12
line 13
line 14
line 15
line 16
line 17
line 18
line 19
line 20
line 21
line 22
line 23
line 24
line 25
line 26
line 27
line 28
line 29
line 30
line 31
line 32
line 33
line 34
line 35
line 36
line 37
line 38
line 39
line 40
line 41
line 42
line 43
line 44
line 45
line 46
line 47
line 48
line 49
line 50
line 51
`;
```
Example of **correct** code for this rule:
```js
exports[`a more manageable and readable snapshot 1`] = `
line 1
line 2
line 3
line 4
`;
```
## Options
This rule has options for modifying the max number of lines allowed for a
snapshot:
In an `eslintrc` file:
```json
{
"rules": {
"jest/no-large-snapshots": ["warn", { "maxSize": 12, "inlineMaxSize": 6 }]
}
}
```
Max number of lines allowed could be defined by snapshot type (Inline and
External). Use `inlineMaxSize` for
[Inline Snapshots](https://jestjs.io/docs/en/snapshot-testing#inline-snapshots)
size and `maxSize` for
[External Snapshots](https://jestjs.io/docs/en/snapshot-testing#snapshot-testing-with-jest).
If only `maxSize` is provided on options, the value of `maxSize` will be used to
both snapshot types (Inline and External).
Since `eslint-disable` comments are not preserved by Jest when updating
snapshots, you can use the `allowedSnapshots` option to have specific snapshots
allowed regardless of their size.
This option takes a map, with the key being the absolute filepath to a snapshot
file, and the value an array of values made up of strings and regular
expressions to compare to the names of the snapshots in the `.snap` file when
checking if the snapshots size should be allowed.
Note that regular expressions can only be passed in via `.eslintrc.js` as
instances of `RegExp`.
In an `.eslintrc.js` file:
```javascript
module.exports = {
rules: {
'jest/no-large-snapshots': [
'error',
{
allowedSnapshots: {
'/path/to/file.js.snap': ['snapshot name 1', /a big snapshot \d+/],
},
},
],
},
};
```
Since absolute paths are typically not very portable, you can use the builtin
`path.resolve` function to expand relative paths into absolutes like so:
```javascript
const path = require('path');
module.exports = {
rules: {
'jest/no-large-snapshots': [
'error',
{
allowedSnapshots: {
[path.resolve('test/__snapshots__/get.js.snap')]: ['full request'],
[path.resolve('test/__snapshots__/put.js.snap')]: ['full request'],
},
},
],
},
};
```

View file

@ -0,0 +1,27 @@
# Disallow manually importing from `__mocks__` (`no-mocks-import`)
When using `jest.mock`, your tests (just like the code being tested) should
import from `./x`, not `./__mocks__/x`. Not following this rule can lead to
confusion, because you will have multiple instances of the mocked module:
```js
jest.mock('./x');
const x1 = require('./x');
const x2 = require('./__mocks__/x');
test('x', () => {
expect(x1).toBe(x2); // fails! They are both instances of `./__mocks__/x`, but not referentially equal
});
```
### Rule details
This rule reports imports from a path containing a `__mocks__` component.
Example violations:
```js
import thing from './__mocks__/index';
require('./__mocks__/index');
require('__mocks__');
```

View file

@ -0,0 +1,47 @@
# Disallow specific matchers & modifiers (`no-restricted-matchers`)
This rule bans specific matchers & modifiers from being used, and can suggest
alternatives.
## Rule Details
Bans are expressed in the form of a map, with the value being either a string
message to be shown, or `null` if the default rule message should be used.
Both matchers, modifiers, and chains of the two are checked, allowing for
specific variations of a matcher to be banned if desired.
By default, this map is empty, meaning no matchers or modifiers are banned.
For example:
```json
{
"jest/no-restricted-matchers": [
"error",
{
"toBeFalsy": null,
"resolves": "Use `expect(await promise)` instead.",
"not.toHaveBeenCalledWith": null
}
]
}
```
Examples of **incorrect** code for this rule with the above configuration
```js
it('is false', () => {
expect(a).toBeFalsy();
});
it('resolves', async () => {
await expect(myPromise()).resolves.toBe(true);
});
describe('when an error happens', () => {
it('does not upload the file', async () => {
expect(uploadFileMock).not.toHaveBeenCalledWith('file.name');
});
});
```

View file

@ -0,0 +1,99 @@
# Disallow using `expect` outside of `it` or `test` blocks (`no-standalone-expect`)
Prevents `expect` statements outside of a `test` or `it` block. An `expect`
within a helper function (but outside of a `test` or `it` block) will not
trigger this rule.
## Rule Details
This rule aims to eliminate `expect` statements that will not be executed. An
`expect` inside of a `describe` block but outside of a `test` or `it` block or
outside of a `describe` will not execute and therefore will trigger this rule.
It is viable, however, to have an `expect` in a helper function that is called
from within a `test` or `it` block so `expect` statements in a function will not
trigger this rule.
Statements like `expect.hasAssertions()` will NOT trigger this rule since these
calls will execute if they are not in a test block.
Examples of **incorrect** code for this rule:
```js
// in describe
describe('a test', () => {
expect(1).toBe(1);
});
// below other tests
describe('a test', () => {
it('an it', () => {
expect(1).toBe(1);
});
expect(1).toBe(1);
});
```
Examples of **correct** code for this rule:
```js
// in it block
describe('a test', () => {
it('an it', () => {
expect(1).toBe(1);
});
});
// in helper function
describe('a test', () => {
const helper = () => {
expect(1).toBe(1);
};
it('an it', () => {
helper();
});
});
describe('a test', () => {
expect.hasAssertions(1);
});
```
\*Note that this rule will not trigger if the helper function is never used even
thought the `expect` will not execute. Rely on a rule like no-unused-vars for
this case.
### Options
#### `additionalTestBlockFunctions`
This array can be used to specify the names of functions that should also be
treated as test blocks:
```json
{
"rules": {
"jest/no-standalone-expect": [
"error",
{ "additionalTestBlockFunctions": ["each.test"] }
]
}
}
```
The following is _correct_ when using the above configuration:
```js
each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
]).test('returns the result of adding %d to %d', (a, b, expected) => {
expect(a + b).toBe(expected);
});
```
## When Not To Use It
Don't use this rule on non-jest test files.

View file

@ -0,0 +1,32 @@
# Use `.only` and `.skip` over `f` and `x` (`no-test-prefixes`)
Jest allows you to choose how you want to define focused and skipped tests, with
multiple permutations for each:
- **only & skip:** `it.only`, `test.only`, `describe.only`, `it.skip`,
`test.skip`, `describe.skip`.
- **'f' & 'x':** `fit`, `fdescribe`, `xit`, `xtest`, `xdescribe`.
This rule enforces usages from the **only & skip** list.
## Rule details
This rule triggers a warning if you use one of the keywords from the **'f' &
'x'** list to focus/skip a test.
```js
/*eslint jest/no-test-prefixes: "error"*/
it.only('foo'); // valid
test.only('foo'); // valid
describe.only('foo'); // valid
it.skip('foo'); // valid
test.skip('foo'); // valid
describe.skip('foo'); // valid
fit('foo'); // invalid
fdescribe('foo'); // invalid
xit('foo'); // invalid
xtest('foo'); // invalid
xdescribe('foo'); // invalid
```

View file

@ -0,0 +1,47 @@
# Disallow explicitly returning from tests (`no-test-return-statement`)
Tests in Jest should be void and not return values.
If you are returning Promises then you should update the test to use
`async/await`.
## Rule details
This rule triggers a warning if you use a return statement inside of a test
body.
```js
/*eslint jest/no-test-return-statement: "error"*/
// valid:
it('noop', function () {});
test('noop', () => {});
test('one arrow', () => expect(1).toBe(1));
test('empty');
test('one', () => {
expect(1).toBe(1);
});
it('one', function () {
expect(1).toBe(1);
});
it('returning a promise', async () => {
await new Promise(res => setTimeout(res, 100));
expect(1).toBe(1);
});
// invalid:
test('return an expect', () => {
return expect(1).toBe(1);
});
it('returning a promise', function () {
return new Promise(res => setTimeout(res, 100)).then(() => expect(1).toBe(1));
});
```

View file

@ -0,0 +1,53 @@
# Disallow using `toBeTruthy()` & `toBeFalsy()` (`no-truthy-falsy`)
## Deprecated
This rule has been deprecated in favor of
[`no-restricted-matchers`](no-restricted-matchers.md) with the following config:
```json
{
"rules": {
"jest/no-restricted-matchers": [
"error",
{
"toBeTruthy": "Avoid `toBeTruthy`",
"toBeFalsy": "Avoid `toBeFalsy`"
}
]
}
}
```
---
Tests against boolean values should assert true or false. Asserting `toBeTruthy`
or `toBeFalsy` matches non-boolean values as well and encourages weaker tests.
For example, `expect(someBoolean).toBeFalsy()` passes when
`someBoolean === null`, and when `someBoolean === false`.
Similarly, `expect(someBoolean).toBeTruthy()` passes when `someBoolean === []`,
and when `someBoolean === 'false'` (note that `'false'` is a string).
## Rule details
This rule triggers a warning if `toBeTruthy()` or `toBeFalsy()` are used.
This rule is disabled by default.
### Default configuration
The following patterns are considered warnings:
```js
expect(someValue).toBeTruthy();
expect(someValue).toBeFalsy();
```
The following patterns are not considered warnings:
```js
expect(someValue).toBe(true);
expect(someValue).toBe(false);
```

View file

@ -0,0 +1,63 @@
# Prevent catch assertions in tests (`no-try-expect`)
## Deprecated
This rule has been deprecated in favor of
[`no-conditional-expect`](no-conditional-expect.md).
---
This rule prevents the use of `expect` inside `catch` blocks.
## Rule Details
Expectations inside a `catch` block can be silently skipped. While Jest provides
an `expect.assertions(number)` helper, it might be cumbersome to add this to
every single test. Using `toThrow` concisely guarantees that an exception was
thrown, and that its contents match expectations.
The following patterns are warnings:
```js
it('foo', () => {
try {
foo(); // `foo` may be refactored to not throw exceptions, yet still appears to be tested here.
} catch (err) {
expect(err).toMatch(/foo error/);
}
});
it('bar', async () => {
try {
await foo();
} catch (err) {
expect(err).toMatch(/foo error/);
}
});
it('baz', async () => {
try {
await foo();
} catch (err) {
expect(err).toMatchObject({ code: 'MODULE_NOT_FOUND' });
}
});
```
The following patterns are not warnings:
```js
it('foo', () => {
expect(() => foo()).toThrow(/foo error/);
});
it('bar', async () => {
await expect(fooPromise).rejects.toThrow(/foo error/);
});
it('baz', async () => {
await expect(() => foo()).rejects.toThrow(
expect.objectContaining({ code: 'MODULE_NOT_FOUND' }),
);
});
```

View file

@ -0,0 +1,32 @@
# Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()` (`prefer-called-with`)
The `toBeCalled()` matcher is used to assert that a mock function has been
called one or more times, without checking the arguments passed. The assertion
is stronger when arguments are also validated using the `toBeCalledWith()`
matcher. When some arguments are difficult to check, using generic match like
`expect.anything()` at least enforces number and position of arguments.
This rule warns if the form without argument checking is used, except for `.not`
enforcing a function has never been called.
## Rule details
The following patterns are warnings:
```js
expect(someFunction).toBeCalled();
expect(someFunction).toHaveBeenCalled();
```
The following patterns are not warnings:
```js
expect(noArgsFunction).toBeCalledWith();
expect(roughArgsFunction).toBeCalledWith(expect.anything(), expect.any(Date));
expect(anyArgsFunction).toBeCalledTimes(1);
expect(uncalledFunction).not.toBeCalled();
```

View file

@ -0,0 +1,99 @@
# Suggest using `expect.assertions()` OR `expect.hasAssertions()` (`prefer-expect-assertions`)
Ensure every test to have either `expect.assertions(<number of assertions>)` OR
`expect.hasAssertions()` as its first expression.
## Rule details
This rule triggers a warning if,
- `expect.assertions(<number of assertions>)` OR `expect.hasAssertions()` is not
present as first statement in a test, e.g.:
```js
test('my test', () => {
expect(someThing()).toEqual('foo');
});
```
- `expect.assertions(<number of assertions>)` is the first statement in a test
where argument passed to `expect.assertions(<number of assertions>)` is not a
valid number, e.g.:
```js
test('my test', () => {
expect.assertions('1');
expect(someThing()).toEqual('foo');
});
```
### Default configuration
The following patterns are considered warnings:
```js
test('my test', () => {
expect.assertions('1');
expect(someThing()).toEqual('foo');
});
test('my test', () => {
expect(someThing()).toEqual('foo');
});
```
The following patterns would not be considered warnings:
```js
test('my test', () => {
expect.assertions(1);
expect(someThing()).toEqual('foo');
});
test('my test', () => {
expect.hasAssertions();
expect(someThing()).toEqual('foo');
});
```
## Options
#### `onlyFunctionsWithAsyncKeyword`
When `true`, this rule will only warn for tests that use the `async` keyword.
```json
{
"rules": {
"jest/prefer-expect-assertions": [
"warn",
{ "onlyFunctionsWithAsyncKeyword": true }
]
}
}
```
When `onlyFunctionsWithAsyncKeyword` option is set to `true`, the following
pattern would be a warning:
```js
test('my test', async () => {
const result = await someAsyncFunc();
expect(result).toBe('foo');
});
```
While the following patterns would not be considered warnings:
```js
test('my test', () => {
const result = someFunction();
expect(result).toBe('foo');
});
test('my test', async () => {
expect.assertions(1);
const result = await someAsyncFunc();
expect(result).toBe('foo');
});
```

View file

@ -0,0 +1,96 @@
# Suggest having hooks before any test cases (`prefer-hooks-on-top`)
All hooks should be defined before the start of the tests
## Rule Details
Examples of **incorrect** code for this rule
```js
/* eslint jest/prefer-hooks-on-top: "error" */
describe('foo', () => {
beforeEach(() => {
//some hook code
});
test('bar', () => {
some_fn();
});
beforeAll(() => {
//some hook code
});
test('bar', () => {
some_fn();
});
});
// Nested describe scenario
describe('foo', () => {
beforeAll(() => {
//some hook code
});
test('bar', () => {
some_fn();
});
describe('inner_foo', () => {
beforeEach(() => {
//some hook code
});
test('inner bar', () => {
some_fn();
});
test('inner bar', () => {
some_fn();
});
beforeAll(() => {
//some hook code
});
afterAll(() => {
//some hook code
});
test('inner bar', () => {
some_fn();
});
});
});
```
Examples of **correct** code for this rule
```js
/* eslint jest/prefer-hooks-on-top: "error" */
describe('foo', () => {
beforeEach(() => {
//some hook code
});
// Not affected by rule
someSetup();
afterEach(() => {
//some hook code
});
test('bar', () => {
some_fn();
});
});
// Nested describe scenario
describe('foo', () => {
beforeEach(() => {
//some hook code
});
test('bar', () => {
some_fn();
});
describe('inner_foo', () => {
beforeEach(() => {
//some hook code
});
test('inner bar', () => {
some_fn();
});
});
});
```

View file

@ -0,0 +1,51 @@
# Suggest using inline snapshots (`prefer-inline-snapshots`)
## Deprecated
This rule has been deprecated in favor of
[`no-restricted-matchers`](no-restricted-matchers.md) with the following config:
```json
{
"rules": {
"jest/no-restricted-matchers": [
"error",
{
"toThrowErrorMatchingSnapshot": "Use `toThrowErrorMatchingInlineSnapshot()` instead",
"toMatchSnapshot": "Use `toMatchInlineSnapshot()` instead"
}
]
}
}
```
---
In order to make snapshot tests more manageable and reviewable
`toMatchInlineSnapshot()` and `toThrowErrorMatchingInlineSnapshot` should be
used to write the snapshots' inline in the test file.
## Rule details
This rule triggers a warning if `toMatchSnapshot()` or
`toThrowErrorMatchingSnapshot` is used to capture a snapshot.
The following pattern is considered warning:
```js
expect(obj).toMatchSnapshot();
```
```js
expect(error).toThrowErrorMatchingSnapshot();
```
The following pattern is not warning:
```js
expect(obj).toMatchInlineSnapshot();
```
```js
expect(error).toThrowErrorMatchingInlineSnapshot();
```

View file

@ -0,0 +1,41 @@
# Suggest using `jest.spyOn()` (`prefer-spy-on`)
When mocking a function by overwriting a property you have to manually restore
the original implementation when cleaning up. When using `jest.spyOn()` Jest
keeps track of changes, and they can be restored with `jest.restoreAllMocks()`,
`mockFn.mockRestore()` or by setting `restoreMocks` to `true` in the Jest
config.
Note: The mock created by `jest.spyOn()` still behaves the same as the original
function. The original function can be overwritten with
`mockFn.mockImplementation()` or by some of the
[other mock functions](https://jestjs.io/docs/en/mock-function-api).
```js
Date.now = jest.fn(); // Original behaviour lost, returns undefined
jest.spyOn(Date, 'now'); // Turned into a mock function but behaviour hasn't changed
jest.spyOn(Date, 'now').mockImplementation(() => 10); // Will always return 10
jest.spyOn(Date, 'now').mockReturnValue(10); // Will always return 10
```
## Rule details
This rule triggers a warning if an object's property is overwritten with a jest
mock.
### Default configuration
The following patterns are considered warnings:
```js
Date.now = jest.fn();
Date.now = jest.fn(() => 10);
```
These patterns would not be considered warnings:
```js
jest.spyOn(Date, 'now');
jest.spyOn(Date, 'now').mockImplementation(() => 10);
```

View file

@ -0,0 +1,24 @@
# Suggest using `toStrictEqual()` (`prefer-strict-equal`)
`toStrictEqual` not only checks that two objects contain the same data but also
that they have the same structure. It is common to expect objects to not only
have identical values but also to have identical keys. A stricter equality will
catch cases where two objects do not have identical keys.
## Rule details
This rule triggers a warning if `toEqual()` is used to assert equality.
### Default configuration
The following pattern is considered warning:
```js
expect({ a: 'a', b: undefined }).toEqual({ a: 'a' }); // true
```
The following pattern is not warning:
```js
expect({ a: 'a', b: undefined }).toStrictEqual({ a: 'a' }); // false
```

View file

@ -0,0 +1,33 @@
# Suggest using `toBeNull()` (`prefer-to-be-null`)
In order to have a better failure message, `toBeNull()` should be used upon
asserting expectations on null value.
## Rule details
This rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is
used to assert a null value.
```js
expect(null).toBe(null);
```
This rule is enabled by default.
### Default configuration
The following patterns are considered warnings:
```js
expect(null).toBe(null);
expect(null).toEqual(null);
expect(null).toStrictEqual(null);
```
The following pattern is not warning:
```js
expect(null).toBeNull();
```

View file

@ -0,0 +1,33 @@
# Suggest using `toBeUndefined()` (`prefer-to-be-undefined`)
In order to have a better failure message, `toBeUndefined()` should be used upon
asserting expectations on undefined value.
## Rule details
This rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is
used to assert an undefined value.
```js
expect(undefined).toBe(undefined);
```
This rule is enabled by default.
### Default configuration
The following patterns are considered warnings:
```js
expect(undefined).toBe(undefined);
expect(undefined).toEqual(undefined);
expect(undefined).toStrictEqual(undefined);
```
The following pattern is not warning:
```js
expect(undefined).toBeUndefined();
```

View file

@ -0,0 +1,45 @@
# Suggest using `toContain()` (`prefer-to-contain`)
In order to have a better failure message, `toContain()` should be used upon
asserting expectations on an array containing an object.
## Rule details
This rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is
used to assert object inclusion in an array
```js
expect(a.includes(b)).toBe(true);
```
```js
expect(a.includes(b)).not.toBe(true);
```
```js
expect(a.includes(b)).toBe(false);
```
### Default configuration
The following patterns are considered warnings:
```js
expect(a.includes(b)).toBe(true);
expect(a.includes(b)).not.toBe(true);
expect(a.includes(b)).toBe(false);
expect(a.includes(b)).toEqual(true);
expect(a.includes(b)).toStrictEqual(true);
```
The following patterns are not considered warnings:
```js
expect(a).toContain(b);
expect(a).not.toContain(b);
```

View file

@ -0,0 +1,33 @@
# Suggest using `toHaveLength()` (`prefer-to-have-length`)
In order to have a better failure message, `toHaveLength()` should be used upon
asserting expectations on objects length property.
## Rule details
This rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is
used to assert objects length property.
```js
expect(files.length).toBe(1);
```
This rule is enabled by default.
### Default configuration
The following patterns are considered warnings:
```js
expect(files.length).toBe(1);
expect(files.length).toEqual(1);
expect(files.length).toStrictEqual(1);
```
The following pattern is not warning:
```js
expect(files).toHaveLength(1);
```

View file

@ -0,0 +1,28 @@
# Suggest using `test.todo` (`prefer-todo`)
When test cases are empty then it is better to mark them as `test.todo` as it
will be highlighted in the summary output.
## Rule details
This rule triggers a warning if empty test cases are used without 'test.todo'.
```js
test('i need to write this test');
```
### Default configuration
The following pattern is considered warning:
```js
test('i need to write this test'); // Unimplemented test case
test('i need to write this test', () => {}); // Empty test case body
test.skip('i need to write this test', () => {}); // Empty test case body
```
The following pattern is not warning:
```js
test.todo('i need to write this test');
```

View file

@ -0,0 +1,41 @@
# Require a message for `toThrow()` (`require-to-throw-message`)
`toThrow()` (and its alias `toThrowError()`) is used to check if an error is
thrown by a function call, such as in `expect(() => a()).toThrow()`. However, if
no message is defined, then the test will pass for any thrown error. Requiring a
message ensures that the intended error is thrown.
## Rule details
This rule triggers a warning if `toThrow()` or `toThrowError()` is used without
an error message.
### Default configuration
The following patterns are considered warnings:
```js
test('all the things', async () => {
expect(() => a()).toThrow();
expect(() => a()).toThrowError();
await expect(a()).rejects.toThrow();
await expect(a()).rejects.toThrowError();
});
```
The following patterns are not considered warnings:
```js
test('all the things', async () => {
expect(() => a()).toThrow('a');
expect(() => a()).toThrowError('a');
await expect(a()).rejects.toThrow('a');
await expect(a()).rejects.toThrowError('a');
});
```

View file

@ -0,0 +1,52 @@
# Require test cases and hooks to be inside a `describe` block (`require-top-level-describe`)
Jest allows you to organise your test files the way you want it. However, the
more your codebase grows, the more it becomes hard to navigate in your test
files. This rule makes sure you provide at least a top-level `describe` block in
your test file.
## Rule Details
This rule triggers a warning if a test case (`test` and `it`) or a hook
(`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) is not located in a
top-level `describe` block.
The following patterns are considered warnings:
```js
// Above a describe block
test('my test', () => {});
describe('test suite', () => {
it('test', () => {});
});
// Below a describe block
describe('test suite', () => {});
test('my test', () => {});
// Same for hooks
beforeAll('my beforeAll', () => {});
describe('test suite', () => {});
afterEach('my afterEach', () => {});
```
The following patterns are **not** considered warnings:
```js
// In a describe block
describe('test suite', () => {
test('my test', () => {});
});
// In a nested describe block
describe('test suite', () => {
test('my test', () => {});
describe('another test suite', () => {
test('my other test', () => {});
});
});
```
## When Not To Use It
Don't use this rule on non-jest test files.

View file

@ -0,0 +1,54 @@
# Enforces unbound methods are called with their expected scope (`unbound-method`)
## Rule Details
This rule extends the base [`@typescript-eslint/unbound-method`][original-rule]
rule, meaning you must depend on `@typescript-eslint/eslint-plugin` for it to
work. It adds support for understanding when it's ok to pass an unbound method
to `expect` calls.
See the [`@typescript-eslint` documentation][original-rule] for more details on
the `unbound-method` rule.
Note that while this rule requires type information to work, it will fail
silently when not available allowing you to safely enable it on projects that
are not using TypeScript.
## How to use
```json5
{
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
ecmaVersion: 2020,
sourceType: 'module',
},
overrides: [
{
files: ['test/**'],
plugins: ['jest'],
rules: {
// you should turn the original rule off *only* for test files
'@typescript-eslint/unbound-method': 'off',
'jest/unbound-method': 'error',
},
},
],
rules: {
'@typescript-eslint/unbound-method': 'error',
},
}
```
This rule should be applied to your test files in place of the original rule,
which should be applied to the rest of your codebase.
## Options
See [`@typescript-eslint/unbound-method`][original-rule] options.
<sup>Taken with ❤️ [from `@typescript-eslint` core][original-rule]</sup>
[original-rule]:
https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/unbound-method.md

View file

@ -0,0 +1,62 @@
# Enforce valid `describe()` callback (`valid-describe`)
Using an improper `describe()` callback function can lead to unexpected test
errors.
## Rule Details
This rule validates that the second parameter of a `describe()` function is a
callback function. This callback function:
- should not be
[async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
- should not contain any parameters
- should not contain any `return` statements
The following `describe` function aliases are also validated:
- `describe`
- `describe.only`
- `describe.skip`
- `fdescribe`
- `xdescribe`
The following patterns are considered warnings:
```js
// Async callback functions are not allowed
describe('myFunction()', async () => {
// ...
});
// Callback function parameters are not allowed
describe('myFunction()', done => {
// ...
});
//
describe('myFunction', () => {
// No return statements are allowed in block of a callback function
return Promise.resolve().then(() => {
it('breaks', () => {
throw new Error('Fail');
});
});
});
// Returning a value from a describe block is not allowed
describe('myFunction', () =>
it('returns a truthy value', () => {
expect(myFunction()).toBeTruthy();
}));
```
The following patterns are not considered warnings:
```js
describe('myFunction()', () => {
it('returns a truthy value', () => {
expect(myFunction()).toBeTruthy();
});
});
```

View file

@ -0,0 +1,31 @@
# Enforce having return statement when testing with promises (`valid-expect-in-promise`)
Ensure to return promise when having assertions in `then` or `catch` block of
promise
## Rule details
This rule looks for tests that have assertions in `then` and `catch` methods on
promises that are not returned by the test.
### Default configuration
The following pattern is considered warning:
```js
it('promise test', () => {
somePromise.then(data => {
expect(data).toEqual('foo');
});
});
```
The following pattern is not warning:
```js
it('promise test', () => {
return somePromise.then(data => {
expect(data).toEqual('foo');
});
});
```

View file

@ -0,0 +1,131 @@
# Enforce valid `expect()` usage (`valid-expect`)
Ensure `expect()` is called with a single argument and there is an actual
expectation made.
## Rule details
This rule triggers a warning if `expect()` is called with more than one argument
or without arguments. It would also issue a warning if there is nothing called
on `expect()`, e.g.:
```js
expect();
expect('something');
```
or when a matcher function was not called, e.g.:
```js
expect(true).toBeDefined;
```
or when an async assertion was not `await`ed or returned, e.g.:
```js
expect(Promise.resolve('Hi!')).resolves.toBe('Hi!');
```
This rule is enabled by default.
## Options
```json5
{
type: 'object',
properties: {
alwaysAwait: {
type: 'boolean',
default: false,
},
minArgs: {
type: 'number',
minimum: 1,
},
maxArgs: {
type: 'number',
minimum: 1,
},
},
additionalProperties: false,
}
```
### `alwaysAwait`
Enforces to use `await` inside block statements. Using `return` will trigger a
warning. Returning one line statements with arrow functions is _always allowed_.
Examples of **incorrect** code for the { "alwaysAwait": **true** } option:
```js
// alwaysAwait: true
test('test1', async () => {
await expect(Promise.resolve(2)).resolves.toBeDefined();
return expect(Promise.resolve(1)).resolves.toBe(1); // `return` statement will trigger a warning
});
```
Examples of **correct** code for the { "alwaysAwait": **true** } option:
```js
// alwaysAwait: true
test('test1', async () => {
await expect(Promise.resolve(2)).resolves.toBeDefined();
await expect(Promise.resolve(1)).resolves.toBe(1);
});
test('test2', () => expect(Promise.resolve(2)).resolves.toBe(2));
```
### `minArgs` & `maxArgs`
Enforces the minimum and maximum number of arguments that `expect` can take, and
is required to take.
Both of these properties have a default value of `1`, which is the number of
arguments supported by vanilla `expect`.
This is useful when you're using libraries that increase the number of arguments
supported by `expect`, such as
[`jest-expect-message`](https://www.npmjs.com/package/jest-expect-message).
### Default configuration
The following patterns are considered warnings:
```js
test('all the things', async () => {
expect();
expect().toEqual('something');
expect('something', 'else');
expect('something');
await expect('something');
expect(true).toBeDefined;
expect(Promise.resolve('hello')).resolves;
expect(Promise.resolve('hello')).resolves.toEqual('hello');
Promise.resolve(expect(Promise.resolve('hello')).resolves.toEqual('hello'));
Promise.all([
expect(Promise.resolve('hello')).resolves.toEqual('hello'),
expect(Promise.resolve('hi')).resolves.toEqual('hi'),
]);
});
```
The following patterns are not warnings:
```js
test('all the things', async () => {
expect('something').toEqual('something');
expect([1, 2, 3]).toEqual([1, 2, 3]);
expect(true).toBeDefined();
await expect(Promise.resolve('hello')).resolves.toEqual('hello');
await Promise.resolve(
expect(Promise.resolve('hello')).resolves.toEqual('hello'),
);
await Promise.all(
expect(Promise.resolve('hello')).resolves.toEqual('hello'),
expect(Promise.resolve('hi')).resolves.toEqual('hi'),
);
});
```

View file

@ -0,0 +1,228 @@
# Enforce valid titles (`valid-title`)
Checks that the title of Jest blocks are valid by ensuring that titles are:
- not empty,
- is a string,
- not prefixed with their block name,
- have no leading or trailing spaces
## Rule Details
**emptyTitle**
An empty title is not informative, and serves little purpose.
Examples of **incorrect** code for this rule:
```js
describe('', () => {});
describe('foo', () => {
it('', () => {});
});
it('', () => {});
test('', () => {});
xdescribe('', () => {});
xit('', () => {});
xtest('', () => {});
```
Examples of **correct** code for this rule:
```js
describe('foo', () => {});
describe('foo', () => {
it('bar', () => {});
});
test('foo', () => {});
it('foo', () => {});
xdescribe('foo', () => {});
xit('foo', () => {});
xtest('foo', () => {});
```
**titleMustBeString**
Titles for test blocks should always be a string.
This is also applied to `describe` blocks by default, but can be turned off via
the `ignoreTypeOfDescribeName` option:
Examples of **incorrect** code for this rule:
```js
it(123, () => {});
describe(String(/.+/), () => {});
describe(myFunction, () => {});
xdescribe(myFunction, () => {});
describe(6, function () {});
```
Examples of **correct** code for this rule:
```js
it('is a string', () => {});
test('is a string', () => {});
xtest('is a string', () => {});
describe('is a string', () => {});
describe.skip('is a string', () => {});
fdescribe('is a string', () => {});
```
Examples of **correct** code when `ignoreTypeOfDescribeName` is `true`:
```js
it('is a string', () => {});
test('is a string', () => {});
xtest('is a string', () => {});
describe('is a string', () => {});
describe.skip('is a string', () => {});
fdescribe('is a string', () => {});
describe(String(/.+/), () => {});
describe(myFunction, () => {});
xdescribe(myFunction, () => {});
describe(6, function () {});
```
**duplicatePrefix**
A `describe` / `test` block should not start with `duplicatePrefix`
Examples of **incorrect** code for this rule
```js
test('test foo', () => {});
it('it foo', () => {});
describe('foo', () => {
test('test bar', () => {});
});
describe('describe foo', () => {
test('bar', () => {});
});
```
Examples of **correct** code for this rule
```js
test('foo', () => {});
it('foo', () => {});
describe('foo', () => {
test('bar', () => {});
});
```
**accidentalSpace**
A `describe` / `test` block should not contain accidentalSpace
Examples of **incorrect** code for this rule
```js
test(' foo', () => {});
it(' foo', () => {});
describe('foo', () => {
test(' bar', () => {});
});
describe(' foo', () => {
test('bar', () => {});
});
describe('foo ', () => {
test('bar', () => {});
});
```
Examples of **correct** code for this rule
```js
test('foo', () => {});
it('foo', () => {});
describe('foo', () => {
test('bar', () => {});
});
```
## Options
```ts
interface Options {
ignoreTypeOfDescribeName?: boolean;
disallowedWords?: string[];
mustNotMatch?: Partial<Record<'describe' | 'test' | 'it', string>> | string;
mustMatch?: Partial<Record<'describe' | 'test' | 'it', string>> | string;
}
```
#### `ignoreTypeOfDescribeName`
Default: `false`
When enabled, the type of the first argument to `describe` blocks won't be
checked.
#### `disallowedWords`
Default: `[]`
A string array of words that are not allowed to be used in test titles. Matching
is not case-sensitive, and looks for complete words:
Examples of **incorrect** code when using `disallowedWords`:
```js
// with disallowedWords: ['correct', 'all', 'every', 'properly']
describe('the correct way to do things', () => {});
it('has ALL the things', () => {});
xdescribe('every single one of them', () => {});
test(`that the value is set properly`, () => {});
```
Examples of **correct** code when using `disallowedWords`:
```js
// with disallowedWords: ['correct', 'all', 'every', 'properly']
it('correctly sets the value', () => {});
test('that everything is as it should be', () => {});
describe('the proper way to handle things', () => {});
```
#### `mustMatch` & `mustNotMatch`
Defaults: `{}`
Allows enforcing that titles must match or must not match a given Regular
Expression. An object can be provided to apply different Regular Expressions to
specific Jest test function groups (`describe`, `test`, and `it`).
Examples of **incorrect** code when using `mustMatch`:
```js
// with mustMatch: '$that'
describe('the correct way to do things', () => {});
fit('this there!', () => {});
// with mustMatch: { test: '$that' }
describe('the tests that will be run', () => {});
test('the stuff works', () => {});
xtest('errors that are thrown have messages', () => {});
```
Examples of **correct** code when using `mustMatch`:
```js
// with mustMatch: '$that'
describe('that thing that needs to be done', () => {});
fit('that this there!', () => {});
// with mustMatch: { test: '$that' }
describe('the tests that will be run', () => {});
test('that the stuff works', () => {});
xtest('that errors that thrown have messages', () => {});
```