eslint-plugin-jest 29.4.1 → 29.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -351,6 +351,7 @@ Manually fixable by
351
351
  | [no-standalone-expect](docs/rules/no-standalone-expect.md) | Disallow using `expect` outside of `it` or `test` blocks | ✅ | | | |
352
352
  | [no-test-prefixes](docs/rules/no-test-prefixes.md) | Require using `.only` and `.skip` over `f` and `x` | ✅ | | 🔧 | |
353
353
  | [no-test-return-statement](docs/rules/no-test-return-statement.md) | Disallow explicitly returning from tests | | | | |
354
+ | [no-unneeded-async-expect-function](docs/rules/no-unneeded-async-expect-function.md) | Disallow unnecessary async function wrapper for expected promises | | | 🔧 | |
354
355
  | [no-untyped-mock-factory](docs/rules/no-untyped-mock-factory.md) | Disallow using `jest.mock()` factories without an explicit type parameter | | | 🔧 | |
355
356
  | [padding-around-after-all-blocks](docs/rules/padding-around-after-all-blocks.md) | Enforce padding around `afterAll` blocks | | | 🔧 | |
356
357
  | [padding-around-after-each-blocks](docs/rules/padding-around-after-each-blocks.md) | Enforce padding around `afterEach` blocks | | | 🔧 | |
@@ -393,9 +394,10 @@ Manually fixable by
393
394
 
394
395
  ### Requires Type Checking
395
396
 
396
- | Name           | Description | 💼 | ⚠️ | 🔧 | 💡 |
397
- | :--------------------------------------------- | :----------------------------------------------------------- | :-- | :-- | :-- | :-- |
398
- | [unbound-method](docs/rules/unbound-method.md) | Enforce unbound methods are called with their expected scope | | | | |
397
+ | Name                     | Description | 💼 | ⚠️ | 🔧 | 💡 |
398
+ | :----------------------------------------------------------------- | :----------------------------------------------------------- | :-- | :-- | :-- | :-- |
399
+ | [no-unnecessary-assertion](docs/rules/no-unnecessary-assertion.md) | Disallow unnecessary assertions based on types | | | | |
400
+ | [unbound-method](docs/rules/unbound-method.md) | Enforce unbound methods are called with their expected scope | | | | |
399
401
 
400
402
  <!-- end auto-generated rules list -->
401
403
 
@@ -0,0 +1,35 @@
1
+ # Disallow unnecessary assertions based on types (`no-unnecessary-assertion`)
2
+
3
+ 💭 This rule requires
4
+ [type information](https://typescript-eslint.io/linting/typed-linting).
5
+
6
+ <!-- end auto-generated rule header -->
7
+
8
+ When using TypeScript, runtime assertions based on types can often be omitted
9
+ provided that the types are accurate.
10
+
11
+ ## Rule details
12
+
13
+ This rule warns when you do an assertion about being `null` or `undefined` on
14
+ something that cannot be those types, as that indicates either the assertion can
15
+ be removed or the types need to be adjusted.
16
+
17
+ The following patterns are considered warnings:
18
+
19
+ ```ts
20
+ expect('hello world'.match('sunshine') ?? []).toBeNull();
21
+
22
+ expect(User.findOrThrow(1)).toBeDefined();
23
+
24
+ expect(map.getOrInsert('key', 'default')).not.toBeUndefined();
25
+ ```
26
+
27
+ The following patterns are not considered warnings:
28
+
29
+ ```ts
30
+ expect('hello world'.match('sunshine')).toBeNull();
31
+
32
+ expect(User.findOrNull(1)).toBeDefined();
33
+
34
+ expect(map.get('key')).not.toBeUndefined();
35
+ ```
@@ -0,0 +1,39 @@
1
+ # Disallow unnecessary async function wrapper for expected promises (`no-unneeded-async-expect-function`)
2
+
3
+ 🔧 This rule is automatically fixable by the
4
+ [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
5
+
6
+ <!-- end auto-generated rule header -->
7
+
8
+ `Jest` can handle fulfilled/rejected promisified function call normally but
9
+ occassionally, engineers wrap said function in another `async` function that is
10
+ excessively verbose and make the tests harder to read.
11
+
12
+ ## Rule details
13
+
14
+ This rule triggers a warning if `expect` is passed with an an `async` function
15
+ that has a single `await` call.
16
+
17
+ Examples of **incorrect** code for this rule
18
+
19
+ ```js
20
+ it('wrong1', async () => {
21
+ await expect(async () => {
22
+ await doSomethingAsync();
23
+ }).rejects.toThrow();
24
+ });
25
+
26
+ it('wrong2', async () => {
27
+ await expect(async function () {
28
+ await doSomethingAsync();
29
+ }).rejects.toThrow();
30
+ });
31
+ ```
32
+
33
+ Examples of **correct** code for this rule
34
+
35
+ ```js
36
+ it('right1', async () => {
37
+ await expect(doSomethingAsync()).rejects.toThrow();
38
+ });
39
+ ```
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("@typescript-eslint/utils");
8
+ var _utils2 = require("./utils");
9
+ const canBe = (firstArgumentType, flag) => {
10
+ if (firstArgumentType.isUnion()) {
11
+ return firstArgumentType.types.some(typ => typ.flags & flag);
12
+ }
13
+ return firstArgumentType.flags & flag;
14
+ };
15
+ var _default = exports.default = (0, _utils2.createRule)({
16
+ name: __filename,
17
+ meta: {
18
+ docs: {
19
+ description: 'Disallow unnecessary assertions based on types',
20
+ requiresTypeChecking: true
21
+ },
22
+ messages: {
23
+ unnecessaryAssertion: 'Unnecessary assertion, subject cannot be {{ thing }}',
24
+ noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.'
25
+ },
26
+ type: 'suggestion',
27
+ schema: []
28
+ },
29
+ defaultOptions: [],
30
+ create(context) {
31
+ const services = _utils.ESLintUtils.getParserServices(context);
32
+ const compilerOptions = services.program.getCompilerOptions();
33
+ const isStrictNullChecks = compilerOptions.strictNullChecks || compilerOptions.strict && compilerOptions.strictNullChecks !== false;
34
+ if (!isStrictNullChecks) {
35
+ context.report({
36
+ loc: {
37
+ start: {
38
+ column: 0,
39
+ line: 0
40
+ },
41
+ end: {
42
+ column: 0,
43
+ line: 0
44
+ }
45
+ },
46
+ messageId: 'noStrictNullCheck'
47
+ });
48
+ }
49
+
50
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
51
+ const {
52
+ TypeFlags
53
+ } = require('typescript');
54
+ return {
55
+ CallExpression(node) {
56
+ const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
57
+ if (jestFnCall?.type !== 'expect' || jestFnCall.head.node.parent.type !== _utils.AST_NODE_TYPES.CallExpression) {
58
+ return;
59
+ }
60
+ const matcherName = (0, _utils2.getAccessorValue)(jestFnCall.matcher);
61
+ if (!['toBeNull', 'toBeDefined', 'toBeUndefined'].includes(matcherName)) {
62
+ return;
63
+ }
64
+ const [argument] = jestFnCall.head.node.parent.arguments;
65
+ const isNullable = canBe(services.getTypeAtLocation(argument), matcherName === 'toBeNull' ? TypeFlags.Null : TypeFlags.Undefined);
66
+ if (!isNullable) {
67
+ context.report({
68
+ messageId: 'unnecessaryAssertion',
69
+ data: {
70
+ thing: matcherName === 'toBeNull' ? 'null' : 'undefined'
71
+ },
72
+ node
73
+ });
74
+ }
75
+ }
76
+ };
77
+ }
78
+ });
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("@typescript-eslint/utils");
8
+ var _utils2 = require("./utils");
9
+ var _default = exports.default = (0, _utils2.createRule)({
10
+ name: __filename,
11
+ meta: {
12
+ docs: {
13
+ description: 'Disallow unnecessary async function wrapper for expected promises'
14
+ },
15
+ fixable: 'code',
16
+ messages: {
17
+ noAsyncWrapperForExpectedPromise: 'Unnecessary async function wrapper'
18
+ },
19
+ schema: [],
20
+ type: 'suggestion'
21
+ },
22
+ defaultOptions: [],
23
+ create(context) {
24
+ return {
25
+ CallExpression(node) {
26
+ const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
27
+ if (jestFnCall?.type !== 'expect') {
28
+ return;
29
+ }
30
+ const {
31
+ parent
32
+ } = jestFnCall.head.node;
33
+ if (parent?.type !== _utils.AST_NODE_TYPES.CallExpression) {
34
+ return;
35
+ }
36
+ const [awaitNode] = parent.arguments;
37
+ if (!awaitNode || !(0, _utils2.isFunction)(awaitNode) || !awaitNode?.async || awaitNode.body.type !== _utils.AST_NODE_TYPES.BlockStatement || awaitNode.body.body.length !== 1) {
38
+ return;
39
+ }
40
+ const [callback] = awaitNode.body.body;
41
+ if (callback.type === _utils.AST_NODE_TYPES.ExpressionStatement && callback.expression.type === _utils.AST_NODE_TYPES.AwaitExpression && callback.expression.argument.type === _utils.AST_NODE_TYPES.CallExpression) {
42
+ const innerAsyncFuncCall = callback.expression.argument;
43
+ context.report({
44
+ node: awaitNode,
45
+ messageId: 'noAsyncWrapperForExpectedPromise',
46
+ fix(fixer) {
47
+ const {
48
+ sourceCode
49
+ } = context;
50
+ return [fixer.replaceTextRange([awaitNode.range[0], awaitNode.range[1]], sourceCode.getText(innerAsyncFuncCall))];
51
+ }
52
+ });
53
+ }
54
+ }
55
+ };
56
+ }
57
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-jest",
3
- "version": "29.4.1",
3
+ "version": "29.6.0",
4
4
  "description": "ESLint rules for Jest",
5
5
  "keywords": [
6
6
  "eslint",