diff --git a/README.md b/README.md index d1093295e..a53b4556f 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,7 @@ installations requiring long-term consistency. | [no-focused-tests](docs/rules/no-focused-tests.md) | Disallow focused tests | ![recommended][] | ![suggest][] | | [no-hooks](docs/rules/no-hooks.md) | Disallow setup and teardown hooks | | | | [no-identical-title](docs/rules/no-identical-title.md) | Disallow identical titles | ![recommended][] | | +| [no-if](docs/rules/no-if.md) | Disallow conditional logic | ![deprecated][] | | | [no-interpolation-in-snapshots](docs/rules/no-interpolation-in-snapshots.md) | Disallow string interpolation inside snapshots | ![recommended][] | | | [no-jasmine-globals](docs/rules/no-jasmine-globals.md) | Disallow Jasmine globals | ![recommended][] | ![fixable][] | | [no-large-snapshots](docs/rules/no-large-snapshots.md) | disallow large snapshots | | | @@ -308,4 +309,5 @@ https://github.com/istanbuljs/eslint-plugin-istanbul [suggest]: https://img.shields.io/badge/-suggest-yellow.svg [fixable]: https://img.shields.io/badge/-fixable-green.svg [style]: https://img.shields.io/badge/-style-blue.svg +[deprecated]: https://img.shields.io/badge/-deprecated-red.svg [`no-deprecated-functions`]: docs/rules/no-deprecated-functions.md diff --git a/docs/rules/consistent-test-it.md b/docs/rules/consistent-test-it.md index 881073c9c..713da2fb9 100644 --- a/docs/rules/consistent-test-it.md +++ b/docs/rules/consistent-test-it.md @@ -1,11 +1,15 @@ # Have control over `test` and `it` usages (`consistent-test-it`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + Jest allows you to choose how you want to define your tests, using the `it` or the `test` keywords, with multiple permutations for each: diff --git a/docs/rules/expect-expect.md b/docs/rules/expect-expect.md index c9747ea61..22347da47 100644 --- a/docs/rules/expect-expect.md +++ b/docs/rules/expect-expect.md @@ -1,8 +1,12 @@ # Enforce assertion to be made in a test body (`expect-expect`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + Ensure that there is at least one `expect` call made in a test. ## Rule Details diff --git a/docs/rules/max-expects.md b/docs/rules/max-expects.md index d5fa1f752..fe9175101 100644 --- a/docs/rules/max-expects.md +++ b/docs/rules/max-expects.md @@ -1,8 +1,12 @@ # Enforces a maximum number assertion calls in a test body (`max-expects`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + As more assertions are made, there is a possible tendency for the test to be more likely to mix multiple objectives. To avoid this, this rule reports when the maximum number of assertions is exceeded. diff --git a/docs/rules/max-nested-describe.md b/docs/rules/max-nested-describe.md index 0fc83553c..dbff28fd5 100644 --- a/docs/rules/max-nested-describe.md +++ b/docs/rules/max-nested-describe.md @@ -1,8 +1,12 @@ # Enforces a maximum depth to nested describe calls (`max-nested-describe`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + 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. diff --git a/docs/rules/no-alias-methods.md b/docs/rules/no-alias-methods.md index 341151124..541041d10 100644 --- a/docs/rules/no-alias-methods.md +++ b/docs/rules/no-alias-methods.md @@ -1,11 +1,15 @@ # Disallow alias methods (`no-alias-methods`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + > These aliases are going to be removed in the next major version of Jest - see > https://github.com/facebook/jest/issues/13164 for more diff --git a/docs/rules/no-commented-out-tests.md b/docs/rules/no-commented-out-tests.md index adce60fed..ba17dc838 100644 --- a/docs/rules/no-commented-out-tests.md +++ b/docs/rules/no-commented-out-tests.md @@ -1,8 +1,12 @@ # Disallow commented out tests (`no-commented-out-tests`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + This rule raises a warning about commented out tests. It's similar to no-disabled-tests rule. diff --git a/docs/rules/no-conditional-expect.md b/docs/rules/no-conditional-expect.md index 14d5ae6c3..a51212cb0 100644 --- a/docs/rules/no-conditional-expect.md +++ b/docs/rules/no-conditional-expect.md @@ -1,8 +1,12 @@ # Prevent calling `expect` conditionally (`no-conditional-expect`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. + + This rule prevents the use of `expect` in conditional blocks, such as `if`s & `catch`s. diff --git a/docs/rules/no-conditional-in-test.md b/docs/rules/no-conditional-in-test.md index 073724019..06e6bf12c 100644 --- a/docs/rules/no-conditional-in-test.md +++ b/docs/rules/no-conditional-in-test.md @@ -1,8 +1,12 @@ # Disallow conditional logic in tests (`no-conditional-in-test`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + 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 a conditional statement will usually be better served by a test diff --git a/docs/rules/no-deprecated-functions.md b/docs/rules/no-deprecated-functions.md index 8f21028fe..f3258d8cc 100644 --- a/docs/rules/no-deprecated-functions.md +++ b/docs/rules/no-deprecated-functions.md @@ -1,11 +1,15 @@ # Disallow use of deprecated functions (`no-deprecated-functions`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + 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. diff --git a/docs/rules/no-disabled-tests.md b/docs/rules/no-disabled-tests.md index 1e08ff1ac..8e2706a65 100644 --- a/docs/rules/no-disabled-tests.md +++ b/docs/rules/no-disabled-tests.md @@ -1,8 +1,12 @@ # Disallow disabled tests (`no-disabled-tests`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + 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 diff --git a/docs/rules/no-done-callback.md b/docs/rules/no-done-callback.md index 9c4bfe4c5..e063e1a0c 100644 --- a/docs/rules/no-done-callback.md +++ b/docs/rules/no-done-callback.md @@ -1,11 +1,15 @@ # Avoid using a callback in asynchronous tests and hooks (`no-done-callback`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. πŸ’‘ This rule is manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). + + When calling asynchronous code in hooks and tests, `jest` needs to know when the asynchronous work is complete to progress the current run. diff --git a/docs/rules/no-duplicate-hooks.md b/docs/rules/no-duplicate-hooks.md index 78397e354..6130cd5a9 100644 --- a/docs/rules/no-duplicate-hooks.md +++ b/docs/rules/no-duplicate-hooks.md @@ -1,8 +1,12 @@ # Disallow duplicate setup and teardown hooks (`no-duplicate-hooks`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + A `describe` block should not contain duplicate hooks. ## Rule Details diff --git a/docs/rules/no-export.md b/docs/rules/no-export.md index b3b29d2d4..8200764d8 100644 --- a/docs/rules/no-export.md +++ b/docs/rules/no-export.md @@ -1,8 +1,12 @@ # Disallow using `exports` in files containing tests (`no-export`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. + + Prevents using `exports` if a file has one or more tests in it. ## Rule Details diff --git a/docs/rules/no-focused-tests.md b/docs/rules/no-focused-tests.md index 456c09596..4131ed93e 100644 --- a/docs/rules/no-focused-tests.md +++ b/docs/rules/no-focused-tests.md @@ -1,11 +1,16 @@ # Disallow focused tests (`no-focused-tests`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. πŸ’‘ This rule is manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). + + + 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 don’t have to execute all of your tests. After you diff --git a/docs/rules/no-hooks.md b/docs/rules/no-hooks.md index 11f040158..cd953f10a 100644 --- a/docs/rules/no-hooks.md +++ b/docs/rules/no-hooks.md @@ -1,8 +1,12 @@ # Disallow setup and teardown hooks (`no-hooks`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + 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. diff --git a/docs/rules/no-identical-title.md b/docs/rules/no-identical-title.md index ee9b88e41..c62e589fc 100644 --- a/docs/rules/no-identical-title.md +++ b/docs/rules/no-identical-title.md @@ -1,8 +1,12 @@ # Disallow identical titles (`no-identical-title`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. + + 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 diff --git a/docs/rules/no-if.md b/docs/rules/no-if.md index b03a066e0..0e3c61fba 100644 --- a/docs/rules/no-if.md +++ b/docs/rules/no-if.md @@ -1,7 +1,11 @@ # Disallow conditional logic (`no-if`) + + ❌ This rule is deprecated. + + This rule has been deprecated in favor of [`no-conditional-in-test`](no-conditional-in-test.md). diff --git a/docs/rules/no-interpolation-in-snapshots.md b/docs/rules/no-interpolation-in-snapshots.md index 128e07258..0539a42ff 100644 --- a/docs/rules/no-interpolation-in-snapshots.md +++ b/docs/rules/no-interpolation-in-snapshots.md @@ -1,8 +1,12 @@ # Disallow string interpolation inside snapshots (`no-interpolation-in-snapshots`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. + + Prevents the use of string interpolations in snapshots. ## Rule Details diff --git a/docs/rules/no-jasmine-globals.md b/docs/rules/no-jasmine-globals.md index 299e11e3c..950b66e32 100644 --- a/docs/rules/no-jasmine-globals.md +++ b/docs/rules/no-jasmine-globals.md @@ -1,11 +1,15 @@ # Disallow Jasmine globals (`no-jasmine-globals`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + `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 diff --git a/docs/rules/no-large-snapshots.md b/docs/rules/no-large-snapshots.md index 0c2416ef8..2b0c2c7f8 100644 --- a/docs/rules/no-large-snapshots.md +++ b/docs/rules/no-large-snapshots.md @@ -1,8 +1,12 @@ # disallow large snapshots (`no-large-snapshots`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + 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 diff --git a/docs/rules/no-mocks-import.md b/docs/rules/no-mocks-import.md index 483ee7851..54be7133b 100644 --- a/docs/rules/no-mocks-import.md +++ b/docs/rules/no-mocks-import.md @@ -1,8 +1,12 @@ # Disallow manually importing from `__mocks__` (`no-mocks-import`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. + + 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: diff --git a/docs/rules/no-restricted-matchers.md b/docs/rules/no-restricted-matchers.md index 844d308fe..03573ad4e 100644 --- a/docs/rules/no-restricted-matchers.md +++ b/docs/rules/no-restricted-matchers.md @@ -1,8 +1,12 @@ # Disallow specific matchers & modifiers (`no-restricted-matchers`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + You may want to ban specific matchers & modifiers from being used. ## Rule Details diff --git a/docs/rules/no-standalone-expect.md b/docs/rules/no-standalone-expect.md index 36cbf5221..d221d3b43 100644 --- a/docs/rules/no-standalone-expect.md +++ b/docs/rules/no-standalone-expect.md @@ -1,8 +1,12 @@ # Disallow using `expect` outside of `it` or `test` blocks (`no-standalone-expect`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. + + 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. diff --git a/docs/rules/no-test-prefixes.md b/docs/rules/no-test-prefixes.md index 65405f8b7..ab1581826 100644 --- a/docs/rules/no-test-prefixes.md +++ b/docs/rules/no-test-prefixes.md @@ -1,11 +1,15 @@ # Use `.only` and `.skip` over `f` and `x` (`no-test-prefixes`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + Jest allows you to choose how you want to define focused and skipped tests, with multiple permutations for each: diff --git a/docs/rules/no-test-return-statement.md b/docs/rules/no-test-return-statement.md index e3f7a3694..b744eaed1 100644 --- a/docs/rules/no-test-return-statement.md +++ b/docs/rules/no-test-return-statement.md @@ -1,8 +1,12 @@ # Disallow explicitly returning from tests (`no-test-return-statement`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + Tests in Jest should be void and not return values. If you are returning Promises then you should update the test to use diff --git a/docs/rules/prefer-called-with.md b/docs/rules/prefer-called-with.md index f38eda7e7..1753ae27b 100644 --- a/docs/rules/prefer-called-with.md +++ b/docs/rules/prefer-called-with.md @@ -1,8 +1,12 @@ # Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()` (`prefer-called-with`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + 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()` diff --git a/docs/rules/prefer-comparison-matcher.md b/docs/rules/prefer-comparison-matcher.md index 3757d8340..a9199eabe 100644 --- a/docs/rules/prefer-comparison-matcher.md +++ b/docs/rules/prefer-comparison-matcher.md @@ -1,11 +1,15 @@ # Suggest using the built-in comparison matchers (`prefer-comparison-matcher`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + Jest has a number of built-in matchers for comparing numbers, which allow for more readable tests and error messages if an expectation fails. diff --git a/docs/rules/prefer-each.md b/docs/rules/prefer-each.md index 4d42b9060..fa6ab8e2f 100644 --- a/docs/rules/prefer-each.md +++ b/docs/rules/prefer-each.md @@ -1,8 +1,12 @@ # Prefer using `.each` rather than manual loops (`prefer-each`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + Reports where you might be able to use `.each` instead of native loops. ## Rule Details diff --git a/docs/rules/prefer-equality-matcher.md b/docs/rules/prefer-equality-matcher.md index 938ad3f8e..c2d0f1ace 100644 --- a/docs/rules/prefer-equality-matcher.md +++ b/docs/rules/prefer-equality-matcher.md @@ -1,11 +1,15 @@ # Suggest using the built-in equality matchers (`prefer-equality-matcher`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ’‘ This rule is manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). + + Jest has built-in matchers for expecting equality, which allow for more readable tests and error messages if an expectation fails. diff --git a/docs/rules/prefer-expect-assertions.md b/docs/rules/prefer-expect-assertions.md index 2638368c1..2b2194947 100644 --- a/docs/rules/prefer-expect-assertions.md +++ b/docs/rules/prefer-expect-assertions.md @@ -1,11 +1,15 @@ # Suggest using `expect.assertions()` OR `expect.hasAssertions()` (`prefer-expect-assertions`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ’‘ This rule is manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). + + Ensure every test to have either `expect.assertions()` OR `expect.hasAssertions()` as its first expression. diff --git a/docs/rules/prefer-expect-resolves.md b/docs/rules/prefer-expect-resolves.md index f5f633f30..c01dc46f3 100644 --- a/docs/rules/prefer-expect-resolves.md +++ b/docs/rules/prefer-expect-resolves.md @@ -1,11 +1,15 @@ # Prefer `await expect(...).resolves` over `expect(await ...)` syntax (`prefer-expect-resolves`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + When working with promises, there are two primary ways you can test the resolved value: diff --git a/docs/rules/prefer-hooks-in-order.md b/docs/rules/prefer-hooks-in-order.md index e3aa81805..10f9d338a 100644 --- a/docs/rules/prefer-hooks-in-order.md +++ b/docs/rules/prefer-hooks-in-order.md @@ -1,8 +1,12 @@ # Prefer having hooks in a consistent order (`prefer-hooks-in-order`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + While hooks can be setup in any order, they're always called by `jest` in this specific order: diff --git a/docs/rules/prefer-hooks-on-top.md b/docs/rules/prefer-hooks-on-top.md index 03956a57a..aa3f636f7 100644 --- a/docs/rules/prefer-hooks-on-top.md +++ b/docs/rules/prefer-hooks-on-top.md @@ -1,8 +1,12 @@ # Suggest having hooks before any test cases (`prefer-hooks-on-top`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + While hooks can be setup anywhere in a test file, they are always called in a specific order, which means it can be confusing if they're intermixed with test cases. diff --git a/docs/rules/prefer-lowercase-title.md b/docs/rules/prefer-lowercase-title.md index fb4c7a77d..2f45edbcc 100644 --- a/docs/rules/prefer-lowercase-title.md +++ b/docs/rules/prefer-lowercase-title.md @@ -1,11 +1,15 @@ # Enforce lowercase test names (`prefer-lowercase-title`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + ## Rule Details Enforce `it`, `test` and `describe` to have descriptions that begin with a diff --git a/docs/rules/prefer-mock-promise-shorthand.md b/docs/rules/prefer-mock-promise-shorthand.md index f1ff9fe56..05287bdfb 100644 --- a/docs/rules/prefer-mock-promise-shorthand.md +++ b/docs/rules/prefer-mock-promise-shorthand.md @@ -1,11 +1,15 @@ # Prefer mock resolved/rejected shorthands for promises (`prefer-mock-promise-shorthand`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + When working with mocks of functions that return promises, Jest provides some API sugar functions to reduce the amount of boilerplate you have to write. diff --git a/docs/rules/prefer-snapshot-hint.md b/docs/rules/prefer-snapshot-hint.md index fc4294721..e5fe86f10 100644 --- a/docs/rules/prefer-snapshot-hint.md +++ b/docs/rules/prefer-snapshot-hint.md @@ -1,8 +1,12 @@ # Prefer including a hint with external snapshots (`prefer-snapshot-hint`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + When working with external snapshot matchers it's considered best practice to provide a hint (as the last argument to the matcher) describing the expected snapshot content that will be included in the snapshots name by Jest. diff --git a/docs/rules/prefer-spy-on.md b/docs/rules/prefer-spy-on.md index f52eb5712..4896e4e95 100644 --- a/docs/rules/prefer-spy-on.md +++ b/docs/rules/prefer-spy-on.md @@ -1,11 +1,15 @@ # Suggest using `jest.spyOn()` (`prefer-spy-on`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + 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()`, diff --git a/docs/rules/prefer-strict-equal.md b/docs/rules/prefer-strict-equal.md index fe62ef3b4..8ad042472 100644 --- a/docs/rules/prefer-strict-equal.md +++ b/docs/rules/prefer-strict-equal.md @@ -1,11 +1,15 @@ # Suggest using `toStrictEqual()` (`prefer-strict-equal`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ’‘ This rule is manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). + + `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 diff --git a/docs/rules/prefer-to-be.md b/docs/rules/prefer-to-be.md index 130b0c90d..1b6043843 100644 --- a/docs/rules/prefer-to-be.md +++ b/docs/rules/prefer-to-be.md @@ -1,11 +1,15 @@ # Suggest using `toBe()` for primitive literals (`prefer-to-be`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `style`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + When asserting against primitive literals such as numbers and strings, the equality matchers all operate the same, but read slightly differently in code. diff --git a/docs/rules/prefer-to-contain.md b/docs/rules/prefer-to-contain.md index 899e719f6..37d2465ba 100644 --- a/docs/rules/prefer-to-contain.md +++ b/docs/rules/prefer-to-contain.md @@ -1,11 +1,15 @@ # Suggest using `toContain()` (`prefer-to-contain`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `style`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + In order to have a better failure message, `toContain()` should be used upon asserting expectations on an array containing an object. diff --git a/docs/rules/prefer-to-have-length.md b/docs/rules/prefer-to-have-length.md index 625170963..f480fad9f 100644 --- a/docs/rules/prefer-to-have-length.md +++ b/docs/rules/prefer-to-have-length.md @@ -1,11 +1,15 @@ # Suggest using `toHaveLength()` (`prefer-to-have-length`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `style`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + In order to have a better failure message, `toHaveLength()` should be used upon asserting expectations on objects length property. diff --git a/docs/rules/prefer-todo.md b/docs/rules/prefer-todo.md index 7b22a590b..959911572 100644 --- a/docs/rules/prefer-todo.md +++ b/docs/rules/prefer-todo.md @@ -1,11 +1,15 @@ # Suggest using `test.todo` (`prefer-todo`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + When test cases are empty then it is better to mark them as `test.todo` as it will be highlighted in the summary output. diff --git a/docs/rules/require-hook.md b/docs/rules/require-hook.md index 29563d3b4..e56036cb7 100644 --- a/docs/rules/require-hook.md +++ b/docs/rules/require-hook.md @@ -1,8 +1,12 @@ # Require setup and teardown code to be within a hook (`require-hook`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + Often while writing tests you have some setup work that needs to happen before tests run, and you have some finishing work that needs to happen after tests run. Jest provides helper functions to handle this. diff --git a/docs/rules/require-to-throw-message.md b/docs/rules/require-to-throw-message.md index c9f6c5a17..ec1f59cd0 100644 --- a/docs/rules/require-to-throw-message.md +++ b/docs/rules/require-to-throw-message.md @@ -1,8 +1,12 @@ # Require a message for `toThrow()` (`require-to-throw-message`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + `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 diff --git a/docs/rules/require-top-level-describe.md b/docs/rules/require-top-level-describe.md index 146de24da..c9d310c8c 100644 --- a/docs/rules/require-top-level-describe.md +++ b/docs/rules/require-top-level-describe.md @@ -1,8 +1,12 @@ # Require test cases and hooks to be inside a `describe` block (`require-top-level-describe`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + 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 diff --git a/docs/rules/unbound-method.md b/docs/rules/unbound-method.md index f8b25a4c7..a562ff29a 100644 --- a/docs/rules/unbound-method.md +++ b/docs/rules/unbound-method.md @@ -1,8 +1,12 @@ # Enforce unbound methods are called with their expected scope (`unbound-method`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`. + + ## Rule Details This rule extends the base [`@typescript-eslint/unbound-method`][original-rule] diff --git a/docs/rules/valid-describe-callback.md b/docs/rules/valid-describe-callback.md index 7993660e5..1fca6fcb7 100644 --- a/docs/rules/valid-describe-callback.md +++ b/docs/rules/valid-describe-callback.md @@ -1,8 +1,12 @@ # Enforce valid `describe()` callback (`valid-describe-callback`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. + + Using an improper `describe()` callback function can lead to unexpected test errors. diff --git a/docs/rules/valid-expect-in-promise.md b/docs/rules/valid-expect-in-promise.md index ea1b442c3..4f4ea86e0 100644 --- a/docs/rules/valid-expect-in-promise.md +++ b/docs/rules/valid-expect-in-promise.md @@ -1,8 +1,12 @@ # Ensure promises that have expectations in their chain are valid (`valid-expect-in-promise`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. + + Ensure promises that include expectations are returned or awaited. ## Rule Details diff --git a/docs/rules/valid-expect.md b/docs/rules/valid-expect.md index ae3b9fc17..46bfc9e43 100644 --- a/docs/rules/valid-expect.md +++ b/docs/rules/valid-expect.md @@ -1,8 +1,12 @@ # Enforce valid `expect()` usage (`valid-expect`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. + + Ensure `expect()` is called with a single argument and there is an actual expectation made. diff --git a/docs/rules/valid-title.md b/docs/rules/valid-title.md index 261b5b6b8..a6027ecaf 100644 --- a/docs/rules/valid-title.md +++ b/docs/rules/valid-title.md @@ -1,11 +1,15 @@ # Enforce valid titles (`valid-title`) + + πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations): `all`, `recommended`. πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + Checks that the title of Jest blocks are valid by ensuring that titles are: - not empty, diff --git a/src/__tests__/rules.test.ts b/src/__tests__/rules.test.ts index d53697b0c..2a39916d8 100644 --- a/src/__tests__/rules.test.ts +++ b/src/__tests__/rules.test.ts @@ -2,6 +2,11 @@ import { existsSync, readFileSync } from 'fs'; import { EOL } from 'os'; import { join, resolve } from 'path'; import plugin from '../'; +import { + MESSAGES, + getNoticesForRule, + getRuleNoticeLines, +} from '../../tools/rule-notices'; const numberOfRules = 50; const ruleNames = Object.keys(plugin.rules); @@ -79,46 +84,6 @@ describe('rules', () => { }); describe('rule documentation files have the correct content', () => { - enum MESSAGE_TYPE { - CONFIGS = 1, - DEPRECATED = 2, - FIXABLE = 3, - HAS_SUGGESTIONS = 4, - } - const MESSAGES = { - [MESSAGE_TYPE.CONFIGS]: - 'πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations):', - [MESSAGE_TYPE.DEPRECATED]: '❌ This rule is deprecated.', - [MESSAGE_TYPE.FIXABLE]: - 'πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line.', - [MESSAGE_TYPE.HAS_SUGGESTIONS]: - 'πŸ’‘ This rule is manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).', - }; - - function getConfigsForRule(ruleName: keyof typeof plugin.rules) { - const { configs } = plugin; - const configNames: Array = []; - let configName: keyof typeof configs; - - for (configName in configs) { - const config = configs[configName]; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- we don't have a static type for rule names - // @ts-ignore - const value = config.rules[`jest/${ruleName}`]; - const isEnabled = [2, 'error'].includes(value); - - if (isEnabled) { - configNames.push(configName); - } - } - - return configNames.sort(); - } - - function configNamesToList(configNames: string[]) { - return `\`${configNames.join('`, `')}\``; - } - it.each(ruleNames)('%s', ruleName => { const rule = plugin.rules[ruleName]; const documentPath = join('docs', 'rules', `${ruleName}.md`); @@ -128,63 +93,21 @@ describe('rules', () => { // Check title. const expectedTitle = `# ${rule.meta.docs.description} (\`${ruleName}\`)`; - expect(documentLines[0]).toStrictEqual(expectedTitle); // Includes the rule description and name in title. - - // Decide which notices should be shown at the top of the doc. - const expectedNotices: MESSAGE_TYPE[] = []; - const unexpectedNotices: MESSAGE_TYPE[] = []; - - if (rule.meta.deprecated) { - expectedNotices.push(MESSAGE_TYPE.DEPRECATED); - unexpectedNotices.push(MESSAGE_TYPE.CONFIGS); - } else { - unexpectedNotices.push(MESSAGE_TYPE.DEPRECATED); - expectedNotices.push(MESSAGE_TYPE.CONFIGS); - } - if (rule.meta.fixable) { - expectedNotices.push(MESSAGE_TYPE.FIXABLE); - } else { - unexpectedNotices.push(MESSAGE_TYPE.FIXABLE); - } - if (rule.meta.hasSuggestions) { - expectedNotices.push(MESSAGE_TYPE.HAS_SUGGESTIONS); - } else { - unexpectedNotices.push(MESSAGE_TYPE.HAS_SUGGESTIONS); - } + expect(documentLines[0]).toStrictEqual(expectedTitle); // Ensure that expected notices are present in the correct order. - let currentLineNumber = 1; - - expectedNotices.forEach(expectedNotice => { - expect(documentLines[currentLineNumber]).toStrictEqual(''); // Blank line first. - - if ( - documentLines[currentLineNumber + 1] === '' - ) { - // Ignore any Prettier ignore comment that may be needed so that the notice doesn't get split onto multiple lines. - currentLineNumber++; - } - - if (expectedNotice === MESSAGE_TYPE.CONFIGS) { - // Check that the rule has a notice with a list of its configs. - const configsEnabled = getConfigsForRule(ruleName); - const expectedMessage = `${ - MESSAGES[MESSAGE_TYPE.CONFIGS] - } ${configNamesToList(configsEnabled)}.`; - - expect(documentLines[currentLineNumber + 1]).toStrictEqual( - expectedMessage, - ); - } else { - // For other notice types, just check the whole line. - expect(documentLines[currentLineNumber + 1]).toStrictEqual( - MESSAGES[expectedNotice], - ); - } - currentLineNumber += 2; - }); + const noticeLines = getRuleNoticeLines(ruleName); + const NOTICE_START_LINE = 3; + + noticeLines.forEach((noticeLine, index) => + expect(documentLines[index + NOTICE_START_LINE]).toStrictEqual( + noticeLine, + ), + ); // Ensure that unexpected notices are not present. + const { unexpectedNotices } = getNoticesForRule(rule); + unexpectedNotices.forEach(unexpectedNotice => { expect( documentContents.includes(MESSAGES[unexpectedNotice]), diff --git a/tools/regenerate-docs.ts b/tools/regenerate-docs.ts index 4f404da04..8cfcd6d01 100644 --- a/tools/regenerate-docs.ts +++ b/tools/regenerate-docs.ts @@ -5,7 +5,12 @@ import * as path from 'path'; import { TSESLint } from '@typescript-eslint/utils'; import prettier, { Options } from 'prettier'; import { prettier as prettierRC } from '../package.json'; -import config from '../src/index'; +import plugin from '../src/index'; +import { + RULE_NOTICE_MARK_END, + RULE_NOTICE_MARK_START, + getRuleNoticeLines, +} from './rule-notices'; const pathTo = { readme: path.resolve(__dirname, '../README.md'), @@ -23,6 +28,7 @@ interface RuleDetails { description: string; fixable: FixType | false; requiresTypeChecking: boolean; + deprecated: boolean; } type RuleModule = TSESLint.RuleModule & { @@ -35,14 +41,18 @@ const staticElements = { }; const getConfigurationColumnValueForRule = (rule: RuleDetails): string => { - if (`jest/${rule.name}` in config.configs.recommended.rules) { + if (`jest/${rule.name}` in plugin.configs.recommended.rules) { return '![recommended][]'; } - if (`jest/${rule.name}` in config.configs.style.rules) { + if (`jest/${rule.name}` in plugin.configs.style.rules) { return '![style][]'; } + if (rule.deprecated) { + return '![deprecated][]'; + } + return ''; }; @@ -89,6 +99,30 @@ const updateRulesList = ( ].join('\n'); }; +const updateRuleNotices = (contents, ruleName) => { + // Determine where to insert rule notices. + let ruleNoticeMarkStartLine = contents.findIndex( + line => line === RULE_NOTICE_MARK_START, + ); + let ruleNoticeMarkEndLine = contents.findIndex( + line => line === RULE_NOTICE_MARK_END, + ); + + // Add rule notice markers if they don't exist + if (ruleNoticeMarkStartLine === -1) { + contents.splice(2, 0, RULE_NOTICE_MARK_START, RULE_NOTICE_MARK_END); + ruleNoticeMarkStartLine = 2; + ruleNoticeMarkEndLine = 3; + } + + // Insert rule notices between markers. + contents.splice( + ruleNoticeMarkStartLine + 1, + ruleNoticeMarkEndLine - ruleNoticeMarkStartLine - 1, + ...getRuleNoticeLines(ruleName), + ); +}; + // copied from https://github.com/babel/babel/blob/d8da63c929f2d28c401571e2a43166678c555bc4/packages/babel-helpers/src/helpers.js#L602-L606 /* istanbul ignore next */ const interopRequireDefault = (obj: any): { default: any } => @@ -101,12 +135,11 @@ const importDefault = (moduleName: string) => const requireJestRule = (name: string): RuleModule => importDefault(path.join(pathTo.rules, name)) as RuleModule; -const details: RuleDetails[] = Object.keys(config.configs.all.rules) - .map(name => name.split('/')[1]) +const details: RuleDetails[] = Object.keys(plugin.rules) .map(name => [name, requireJestRule(name)] as const) .filter( (nameAndRule): nameAndRule is [string, Required] => - !!nameAndRule[1].meta && !nameAndRule[1].meta.deprecated, + !!nameAndRule[1].meta, ) .map( ([name, rule]): RuleDetails => ({ @@ -118,6 +151,7 @@ const details: RuleDetails[] = Object.keys(config.configs.all.rules) ? 'suggest' : false, requiresTypeChecking: rule.meta.docs.requiresTypeChecking ?? false, + deprecated: rule.meta.deprecated ?? false, }), ); @@ -126,8 +160,11 @@ details.forEach(({ name, description }) => { const contents = fs.readFileSync(pathToDoc).toString().split('\n'); + // Replace the title. contents[0] = `# ${description} (\`${name}\`)`; + updateRuleNotices(contents, name); + fs.writeFileSync(pathToDoc, format(contents.join('\n'))); }); diff --git a/tools/rule-notices.ts b/tools/rule-notices.ts new file mode 100644 index 000000000..dffc144cb --- /dev/null +++ b/tools/rule-notices.ts @@ -0,0 +1,115 @@ +import plugin from '../src'; + +// Markers so that notices and be automatically generated and written to rule doc. +export const RULE_NOTICE_MARK_START = + ''; +export const RULE_NOTICE_MARK_END = ''; + +enum MESSAGE_TYPE { + CONFIGS = 1, + DEPRECATED = 2, + FIXABLE = 3, + HAS_SUGGESTIONS = 4, +} + +export const MESSAGES = { + [MESSAGE_TYPE.CONFIGS]: + 'πŸ’Ό This rule is enabled in the following [configs](https://github.com/jest-community/eslint-plugin-jest#shareable-configurations):', + [MESSAGE_TYPE.DEPRECATED]: '❌ This rule is deprecated.', + [MESSAGE_TYPE.FIXABLE]: + 'πŸ”§ This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line.', + [MESSAGE_TYPE.HAS_SUGGESTIONS]: + 'πŸ’‘ This rule is manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).', +}; + +const PRETTIER_MAX_LINE_LENGTH = 80; + +type RuleName = keyof typeof plugin.rules; +type Rule = typeof plugin.rules[RuleName]; + +function getConfigsForRule(ruleName: RuleName) { + const { configs } = plugin; + const configNames: Array = []; + let configName: keyof typeof configs; + + for (configName in configs) { + const config = configs[configName]; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- we don't have a static type for rule names + // @ts-ignore + const value = config.rules[`jest/${ruleName}`]; + const isEnabled = [2, 'error'].includes(value); + + if (isEnabled) { + configNames.push(configName); + } + } + + return configNames.sort(); +} + +function configNamesToList(configNames: string[]) { + return `\`${configNames.join('`, `')}\``; +} + +/** + * Determine which notices should and should not be included at the top of a rule doc. + */ +export function getNoticesForRule(rule: Rule) { + const expectedNotices: MESSAGE_TYPE[] = []; + const unexpectedNotices: MESSAGE_TYPE[] = []; + + if (rule.meta.deprecated) { + expectedNotices.push(MESSAGE_TYPE.DEPRECATED); + unexpectedNotices.push(MESSAGE_TYPE.CONFIGS); + } else { + unexpectedNotices.push(MESSAGE_TYPE.DEPRECATED); + expectedNotices.push(MESSAGE_TYPE.CONFIGS); + } + if (rule.meta.fixable) { + expectedNotices.push(MESSAGE_TYPE.FIXABLE); + } else { + unexpectedNotices.push(MESSAGE_TYPE.FIXABLE); + } + if (rule.meta.hasSuggestions) { + expectedNotices.push(MESSAGE_TYPE.HAS_SUGGESTIONS); + } else { + unexpectedNotices.push(MESSAGE_TYPE.HAS_SUGGESTIONS); + } + + return { + expectedNotices, + unexpectedNotices, + }; +} + +/** + * Get the lines for the notice section at the top of a rule doc. + */ +export function getRuleNoticeLines(ruleName: RuleName) { + const lines: string[] = []; + + const { expectedNotices } = getNoticesForRule(plugin.rules[ruleName]); + + expectedNotices.forEach(expectedNotice => { + lines.push(''); // Blank line first. + + if (expectedNotice === MESSAGE_TYPE.CONFIGS) { + // This notice should have a list of the rule's configs. + const configsEnabled = getConfigsForRule(ruleName); + const message = `${MESSAGES[MESSAGE_TYPE.CONFIGS]} ${configNamesToList( + configsEnabled, + )}.`; + + lines.push(message); + } else { + lines.push(MESSAGES[expectedNotice]); + } + + if (lines[lines.length - 1].length > PRETTIER_MAX_LINE_LENGTH) { + // Insert Prettier ignore comment so that the notice doesn't get split onto multiple lines. + lines.splice(lines.length - 1, 0, ''); + } + }); + + return lines; +}