@vitest/eslint-plugin 1.1.7 → 1.1.9

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/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import { isAbsolute, posix } from 'node:path';
4
4
  import ts from 'typescript';
5
5
  import { createRequire } from 'node:module';
6
6
 
7
- const version = "1.1.6";
7
+ const version = "1.1.8";
8
8
 
9
9
  function createEslintRule(rule) {
10
10
  const createRule = ESLintUtils.RuleCreator(
@@ -346,7 +346,7 @@ const getFirstMatcherArg = (expectFnCall) => {
346
346
  const isTypeCastExpression$1 = (node) => node.type === AST_NODE_TYPES.TSAsExpression || node.type === AST_NODE_TYPES.TSTypeAssertion;
347
347
  const followTypeAssertionChain$1 = (expression) => isTypeCastExpression$1(expression) ? followTypeAssertionChain$1(expression.expression) : expression;
348
348
 
349
- const RULE_NAME$Y = "prefer-lowercase-title";
349
+ const RULE_NAME$Z = "prefer-lowercase-title";
350
350
  const hasStringAsFirstArgument = (node) => node.arguments[0] && isStringNode(node.arguments[0]);
351
351
  const populateIgnores = (ignore) => {
352
352
  const ignores = [];
@@ -365,7 +365,7 @@ const populateIgnores = (ignore) => {
365
365
  return ignores;
366
366
  };
367
367
  const lowerCaseTitle = createEslintRule({
368
- name: RULE_NAME$Y,
368
+ name: RULE_NAME$Z,
369
369
  meta: {
370
370
  type: "problem",
371
371
  docs: {
@@ -462,9 +462,9 @@ const lowerCaseTitle = createEslintRule({
462
462
  }
463
463
  });
464
464
 
465
- const RULE_NAME$X = "max-nested-describe";
465
+ const RULE_NAME$Y = "max-nested-describe";
466
466
  const maxNestedDescribe = createEslintRule({
467
- name: RULE_NAME$X,
467
+ name: RULE_NAME$Y,
468
468
  meta: {
469
469
  type: "problem",
470
470
  docs: {
@@ -522,13 +522,13 @@ const maxNestedDescribe = createEslintRule({
522
522
  }
523
523
  });
524
524
 
525
- const RULE_NAME$W = "no-identical-title";
525
+ const RULE_NAME$X = "no-identical-title";
526
526
  const newDescribeContext = () => ({
527
527
  describeTitles: [],
528
528
  testTitles: []
529
529
  });
530
530
  const noIdenticalTitle = createEslintRule({
531
- name: RULE_NAME$W,
531
+ name: RULE_NAME$X,
532
532
  meta: {
533
533
  type: "problem",
534
534
  docs: {
@@ -586,7 +586,7 @@ const noIdenticalTitle = createEslintRule({
586
586
  }
587
587
  });
588
588
 
589
- const RULE_NAME$V = "no-focused-tests";
589
+ const RULE_NAME$W = "no-focused-tests";
590
590
  const isTestOrDescribe = (node) => {
591
591
  return node.type === "Identifier" && ["it", "test", "describe"].includes(node.name);
592
592
  };
@@ -594,7 +594,7 @@ const isOnly = (node) => {
594
594
  return node.type === "Identifier" && node.name === "only";
595
595
  };
596
596
  const noFocusedTests = createEslintRule({
597
- name: RULE_NAME$V,
597
+ name: RULE_NAME$W,
598
598
  meta: {
599
599
  type: "problem",
600
600
  docs: {
@@ -666,9 +666,9 @@ const noFocusedTests = createEslintRule({
666
666
  }
667
667
  });
668
668
 
669
- const RULE_NAME$U = "no-conditional-tests";
669
+ const RULE_NAME$V = "no-conditional-tests";
670
670
  const noConditionalTest = createEslintRule({
671
- name: RULE_NAME$U,
671
+ name: RULE_NAME$V,
672
672
  meta: {
673
673
  type: "problem",
674
674
  docs: {
@@ -708,7 +708,7 @@ function parsePluginSettings(settings) {
708
708
  };
709
709
  }
710
710
 
711
- const RULE_NAME$T = "expect-expect";
711
+ const RULE_NAME$U = "expect-expect";
712
712
  function matchesAssertFunctionName(nodeName, patterns) {
713
713
  return patterns.some(
714
714
  (p) => new RegExp(
@@ -722,7 +722,7 @@ function matchesAssertFunctionName(nodeName, patterns) {
722
722
  );
723
723
  }
724
724
  const expectExpect = createEslintRule({
725
- name: RULE_NAME$T,
725
+ name: RULE_NAME$U,
726
726
  meta: {
727
727
  type: "suggestion",
728
728
  docs: {
@@ -735,7 +735,7 @@ const expectExpect = createEslintRule({
735
735
  properties: {
736
736
  assertFunctionNames: {
737
737
  type: "array",
738
- items: [{ type: "string" }]
738
+ items: { type: "string" }
739
739
  },
740
740
  additionalTestBlockFunctions: {
741
741
  type: "array",
@@ -798,7 +798,7 @@ const expectExpect = createEslintRule({
798
798
  }
799
799
  });
800
800
 
801
- const RULE_NAME$S = "consistent-test-it";
801
+ const RULE_NAME$T = "consistent-test-it";
802
802
  const buildFixer = (callee, nodeName, preferredTestKeyword) => (fixer) => [
803
803
  fixer.replaceText(
804
804
  callee.type === AST_NODE_TYPES.MemberExpression ? callee.object : callee,
@@ -816,7 +816,7 @@ function getOppositeTestKeyword(test) {
816
816
  return TestCaseName.test;
817
817
  }
818
818
  const consistentTestIt = createEslintRule({
819
- name: RULE_NAME$S,
819
+ name: RULE_NAME$T,
820
820
  meta: {
821
821
  type: "suggestion",
822
822
  fixable: "code",
@@ -914,7 +914,7 @@ const consistentTestIt = createEslintRule({
914
914
  }
915
915
  });
916
916
 
917
- const RULE_NAME$R = "prefer-to-be";
917
+ const RULE_NAME$S = "prefer-to-be";
918
918
  const isNullLiteral = (node) => node.type === AST_NODE_TYPES.Literal && node.value === null;
919
919
  const isNullEqualityMatcher = (expectFnCall) => isNullLiteral(getFirstMatcherArg(expectFnCall));
920
920
  const isFirstArgumentIdentifier = (expectFnCall, name) => isIdentifier(getFirstMatcherArg(expectFnCall), name);
@@ -950,7 +950,7 @@ const reportPreferToBe = (context, whatToBe, expectFnCall, func, modifierNode) =
950
950
  });
951
951
  };
952
952
  const preferToBe = createEslintRule({
953
- name: RULE_NAME$R,
953
+ name: RULE_NAME$S,
954
954
  meta: {
955
955
  type: "suggestion",
956
956
  docs: {
@@ -1002,9 +1002,9 @@ const preferToBe = createEslintRule({
1002
1002
  }
1003
1003
  });
1004
1004
 
1005
- const RULE_NAME$Q = "no-hooks";
1005
+ const RULE_NAME$R = "no-hooks";
1006
1006
  const noHooks = createEslintRule({
1007
- name: RULE_NAME$Q,
1007
+ name: RULE_NAME$R,
1008
1008
  meta: {
1009
1009
  type: "suggestion",
1010
1010
  docs: {
@@ -1043,9 +1043,9 @@ const noHooks = createEslintRule({
1043
1043
  }
1044
1044
  });
1045
1045
 
1046
- const RULE_NAME$P = "no-restricted-vi-methods";
1046
+ const RULE_NAME$Q = "no-restricted-vi-methods";
1047
1047
  const noRestrictedViMethods = createEslintRule({
1048
- name: RULE_NAME$P,
1048
+ name: RULE_NAME$Q,
1049
1049
  meta: {
1050
1050
  type: "suggestion",
1051
1051
  docs: {
@@ -1085,11 +1085,11 @@ const noRestrictedViMethods = createEslintRule({
1085
1085
  }
1086
1086
  });
1087
1087
 
1088
- const RULE_NAME$O = "consistent-test-filename";
1088
+ const RULE_NAME$P = "consistent-test-filename";
1089
1089
  const defaultPattern = /.*\.test\.[tj]sx?$/;
1090
1090
  const defaultTestsPattern = /.*\.(test|spec)\.[tj]sx?$/;
1091
1091
  const consistentTestFilename = createEslintRule({
1092
- name: RULE_NAME$O,
1092
+ name: RULE_NAME$P,
1093
1093
  meta: {
1094
1094
  type: "problem",
1095
1095
  docs: {
@@ -1144,9 +1144,9 @@ const consistentTestFilename = createEslintRule({
1144
1144
  }
1145
1145
  });
1146
1146
 
1147
- const RULE_NAME$N = "max-expects";
1147
+ const RULE_NAME$O = "max-expects";
1148
1148
  const maxExpect = createEslintRule({
1149
- name: RULE_NAME$N,
1149
+ name: RULE_NAME$O,
1150
1150
  meta: {
1151
1151
  docs: {
1152
1152
  requiresTypeChecking: false,
@@ -1202,9 +1202,9 @@ const maxExpect = createEslintRule({
1202
1202
  }
1203
1203
  });
1204
1204
 
1205
- const RULE_NAME$M = "no-alias-methods";
1205
+ const RULE_NAME$N = "no-alias-methods";
1206
1206
  const noAliasMethod = createEslintRule({
1207
- name: RULE_NAME$M,
1207
+ name: RULE_NAME$N,
1208
1208
  meta: {
1209
1209
  docs: {
1210
1210
  description: "disallow alias methods",
@@ -1254,12 +1254,12 @@ const noAliasMethod = createEslintRule({
1254
1254
  }
1255
1255
  });
1256
1256
 
1257
- const RULE_NAME$L = "no-commented-out-tests";
1257
+ const RULE_NAME$M = "no-commented-out-tests";
1258
1258
  function hasTests(node) {
1259
1259
  return /^\s*[xf]?(test|it|describe)(\.\w+|\[['"]\w+['"]\])?\s*\(/mu.test(node.value);
1260
1260
  }
1261
1261
  const noCommentedOutTests = createEslintRule({
1262
- name: RULE_NAME$L,
1262
+ name: RULE_NAME$M,
1263
1263
  meta: {
1264
1264
  docs: {
1265
1265
  description: "disallow commented out tests",
@@ -1289,10 +1289,10 @@ const noCommentedOutTests = createEslintRule({
1289
1289
  }
1290
1290
  });
1291
1291
 
1292
- const RULE_NAME$K = "no-conditional-expect";
1292
+ const RULE_NAME$L = "no-conditional-expect";
1293
1293
  const isCatchCall = (node) => node.callee.type === AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.callee.property, "catch");
1294
1294
  const noConditionalExpect = createEslintRule({
1295
- name: RULE_NAME$K,
1295
+ name: RULE_NAME$L,
1296
1296
  meta: {
1297
1297
  type: "problem",
1298
1298
  docs: {
@@ -1358,9 +1358,9 @@ const noConditionalExpect = createEslintRule({
1358
1358
  }
1359
1359
  });
1360
1360
 
1361
- const RULE_NAME$J = "no-import-node-test";
1361
+ const RULE_NAME$K = "no-import-node-test";
1362
1362
  const noImportNodeTest = createEslintRule({
1363
- name: RULE_NAME$J,
1363
+ name: RULE_NAME$K,
1364
1364
  meta: {
1365
1365
  docs: {
1366
1366
  description: "disallow importing `node:test`",
@@ -1392,9 +1392,9 @@ const noImportNodeTest = createEslintRule({
1392
1392
  }
1393
1393
  });
1394
1394
 
1395
- const RULE_NAME$I = "no-conditional-in-test";
1395
+ const RULE_NAME$J = "no-conditional-in-test";
1396
1396
  const noConditionalInTest = createEslintRule({
1397
- name: RULE_NAME$I,
1397
+ name: RULE_NAME$J,
1398
1398
  meta: {
1399
1399
  docs: {
1400
1400
  description: "disallow conditional tests",
@@ -1422,9 +1422,9 @@ const noConditionalInTest = createEslintRule({
1422
1422
  }
1423
1423
  });
1424
1424
 
1425
- const RULE_NAME$H = "no-disabled-tests";
1425
+ const RULE_NAME$I = "no-disabled-tests";
1426
1426
  const noDisabledTests = createEslintRule({
1427
- name: RULE_NAME$H,
1427
+ name: RULE_NAME$I,
1428
1428
  meta: {
1429
1429
  type: "suggestion",
1430
1430
  docs: {
@@ -1493,7 +1493,7 @@ const noDisabledTests = createEslintRule({
1493
1493
  }
1494
1494
  });
1495
1495
 
1496
- const RULE_NAME$G = "no-done-callback";
1496
+ const RULE_NAME$H = "no-done-callback";
1497
1497
  const findCallbackArg = (node, isVitestEach, context) => {
1498
1498
  if (isVitestEach)
1499
1499
  return node.arguments[1];
@@ -1505,7 +1505,7 @@ const findCallbackArg = (node, isVitestEach, context) => {
1505
1505
  return null;
1506
1506
  };
1507
1507
  const noDoneCallback = createEslintRule({
1508
- name: RULE_NAME$G,
1508
+ name: RULE_NAME$H,
1509
1509
  meta: {
1510
1510
  type: "suggestion",
1511
1511
  docs: {
@@ -1605,9 +1605,9 @@ const noDoneCallback = createEslintRule({
1605
1605
  }
1606
1606
  });
1607
1607
 
1608
- const RULE_NAME$F = "no-duplicate-hooks";
1608
+ const RULE_NAME$G = "no-duplicate-hooks";
1609
1609
  const noDuplicateHooks = createEslintRule({
1610
- name: RULE_NAME$F,
1610
+ name: RULE_NAME$G,
1611
1611
  meta: {
1612
1612
  docs: {
1613
1613
  recommended: false,
@@ -1650,7 +1650,7 @@ const noDuplicateHooks = createEslintRule({
1650
1650
  }
1651
1651
  });
1652
1652
 
1653
- const RULE_NAME$E = "no-large-snapshots";
1653
+ const RULE_NAME$F = "no-large-snapshots";
1654
1654
  const reportOnViolation = (context, node, { maxSize: lineLimit = 50, allowedSnapshots = {} }) => {
1655
1655
  const startLine = node.loc.start.line;
1656
1656
  const endLine = node.loc.end.line;
@@ -1683,7 +1683,7 @@ const reportOnViolation = (context, node, { maxSize: lineLimit = 50, allowedSnap
1683
1683
  }
1684
1684
  };
1685
1685
  const noLargeSnapshots = createEslintRule({
1686
- name: RULE_NAME$E,
1686
+ name: RULE_NAME$F,
1687
1687
  meta: {
1688
1688
  docs: {
1689
1689
  description: "disallow large snapshots",
@@ -1741,9 +1741,9 @@ const noLargeSnapshots = createEslintRule({
1741
1741
  }
1742
1742
  });
1743
1743
 
1744
- const RULE_NAME$D = "no-interpolation-in-snapshots";
1744
+ const RULE_NAME$E = "no-interpolation-in-snapshots";
1745
1745
  const nonInterpolationInSnapShots = createEslintRule({
1746
- name: RULE_NAME$D,
1746
+ name: RULE_NAME$E,
1747
1747
  meta: {
1748
1748
  type: "problem",
1749
1749
  docs: {
@@ -1784,9 +1784,9 @@ const nonInterpolationInSnapShots = createEslintRule({
1784
1784
  const mocksDirName = "__mocks__";
1785
1785
  const isMockPath = (path) => path.split(posix.sep).includes(mocksDirName);
1786
1786
  const isMockImportLiteral = (expression) => isStringNode(expression) && isMockPath(getStringValue(expression));
1787
- const RULE_NAME$C = "no-mocks-import";
1787
+ const RULE_NAME$D = "no-mocks-import";
1788
1788
  const noMocksImport = createEslintRule({
1789
- name: RULE_NAME$C,
1789
+ name: RULE_NAME$D,
1790
1790
  meta: {
1791
1791
  type: "problem",
1792
1792
  docs: {
@@ -1814,14 +1814,14 @@ const noMocksImport = createEslintRule({
1814
1814
  }
1815
1815
  });
1816
1816
 
1817
- const RULE_NAME$B = "no-restricted-matchers";
1817
+ const RULE_NAME$C = "no-restricted-matchers";
1818
1818
  const isChainRestricted = (chain, restriction) => {
1819
1819
  if (ModifierName.hasOwnProperty(restriction) || restriction.endsWith(".not"))
1820
1820
  return chain.startsWith(restriction);
1821
1821
  return chain === restriction;
1822
1822
  };
1823
1823
  const noRestrictedMatchers = createEslintRule({
1824
- name: RULE_NAME$B,
1824
+ name: RULE_NAME$C,
1825
1825
  meta: {
1826
1826
  docs: {
1827
1827
  description: "disallow the use of certain matchers",
@@ -1867,7 +1867,7 @@ const noRestrictedMatchers = createEslintRule({
1867
1867
  }
1868
1868
  });
1869
1869
 
1870
- const RULE_NAME$A = "no-standalone-expect";
1870
+ const RULE_NAME$B = "no-standalone-expect";
1871
1871
  const getBlockType = (statement, context) => {
1872
1872
  const func = statement.parent;
1873
1873
  if (!func)
@@ -1884,7 +1884,7 @@ const getBlockType = (statement, context) => {
1884
1884
  return null;
1885
1885
  };
1886
1886
  const noStandaloneExpect = createEslintRule({
1887
- name: RULE_NAME$A,
1887
+ name: RULE_NAME$B,
1888
1888
  meta: {
1889
1889
  docs: {
1890
1890
  description: "disallow using `expect` outside of `it` or `test` blocks",
@@ -1957,9 +1957,9 @@ const noStandaloneExpect = createEslintRule({
1957
1957
  }
1958
1958
  });
1959
1959
 
1960
- const RULE_NAME$z = "no-test-prefixes";
1960
+ const RULE_NAME$A = "no-test-prefixes";
1961
1961
  const noTestPrefixes = createEslintRule({
1962
- name: RULE_NAME$z,
1962
+ name: RULE_NAME$A,
1963
1963
  meta: {
1964
1964
  docs: {
1965
1965
  description: "disallow using `test` as a prefix",
@@ -1998,7 +1998,7 @@ const noTestPrefixes = createEslintRule({
1998
1998
  }
1999
1999
  });
2000
2000
 
2001
- const RULE_NAME$y = "no-test-return-statement";
2001
+ const RULE_NAME$z = "no-test-return-statement";
2002
2002
  const getBody = (args) => {
2003
2003
  const [, secondArg] = args;
2004
2004
  if (secondArg && isFunction(secondArg) && secondArg.body.type === AST_NODE_TYPES.BlockStatement)
@@ -2006,7 +2006,7 @@ const getBody = (args) => {
2006
2006
  return [];
2007
2007
  };
2008
2008
  const noTestReturnStatement = createEslintRule({
2009
- name: RULE_NAME$y,
2009
+ name: RULE_NAME$z,
2010
2010
  meta: {
2011
2011
  type: "problem",
2012
2012
  docs: {
@@ -2044,9 +2044,9 @@ const noTestReturnStatement = createEslintRule({
2044
2044
  }
2045
2045
  });
2046
2046
 
2047
- const RULE_NAME$x = "prefer-called-with";
2047
+ const RULE_NAME$y = "prefer-called-with";
2048
2048
  const preferCalledWith = createEslintRule({
2049
- name: RULE_NAME$x,
2049
+ name: RULE_NAME$y,
2050
2050
  meta: {
2051
2051
  docs: {
2052
2052
  description: "enforce using `toBeCalledWith()` or `toHaveBeenCalledWith()`",
@@ -2085,7 +2085,7 @@ const preferCalledWith = createEslintRule({
2085
2085
  }
2086
2086
  });
2087
2087
 
2088
- const RULE_NAME$w = "valid-title";
2088
+ const RULE_NAME$x = "valid-title";
2089
2089
  const trimFXPrefix = (word) => ["f", "x"].includes(word.charAt(0)) ? word.substring(1) : word;
2090
2090
  const quoteStringValue = (node) => node.type === AST_NODE_TYPES.TemplateLiteral ? `\`${node.quasis[0].value.raw}\`` : node.raw;
2091
2091
  const MatcherAndMessageSchema = {
@@ -2135,7 +2135,7 @@ const doesBinaryExpressionContainStringNode = (binaryExp) => {
2135
2135
  return isStringNode(binaryExp.left);
2136
2136
  };
2137
2137
  const validTitle = createEslintRule({
2138
- name: RULE_NAME$w,
2138
+ name: RULE_NAME$x,
2139
2139
  meta: {
2140
2140
  docs: {
2141
2141
  description: "enforce valid titles",
@@ -2315,8 +2315,8 @@ const validTitle = createEslintRule({
2315
2315
  }
2316
2316
  });
2317
2317
 
2318
- const RULE_NAME$v = "valid-expect";
2319
- const defaultAsyncMatchers = ["toReject", "toResolve"];
2318
+ const RULE_NAME$w = "valid-expect";
2319
+ const defaultAsyncMatchers$1 = ["toReject", "toResolve"];
2320
2320
  const getPromiseCallExpressionNode = (node) => {
2321
2321
  if (node.type === AST_NODE_TYPES.ArrayExpression && node.parent && node.parent.type === AST_NODE_TYPES.CallExpression)
2322
2322
  node = node.parent;
@@ -2345,7 +2345,7 @@ const isAcceptableReturnNode = (node, allowReturn) => {
2345
2345
  ].includes(node.type);
2346
2346
  };
2347
2347
  const validExpect = createEslintRule({
2348
- name: RULE_NAME$v,
2348
+ name: RULE_NAME$w,
2349
2349
  meta: {
2350
2350
  docs: {
2351
2351
  description: "enforce valid `expect()` usage",
@@ -2388,11 +2388,11 @@ const validExpect = createEslintRule({
2388
2388
  },
2389
2389
  defaultOptions: [{
2390
2390
  alwaysAwait: false,
2391
- asyncMatchers: defaultAsyncMatchers,
2391
+ asyncMatchers: defaultAsyncMatchers$1,
2392
2392
  minArgs: 1,
2393
2393
  maxArgs: 1
2394
2394
  }],
2395
- create: (context, [{ alwaysAwait, asyncMatchers = defaultAsyncMatchers, minArgs = 1, maxArgs = 1 }]) => {
2395
+ create: (context, [{ alwaysAwait, asyncMatchers = defaultAsyncMatchers$1, minArgs = 1, maxArgs = 1 }]) => {
2396
2396
  const arrayExceptions = /* @__PURE__ */ new Set();
2397
2397
  const pushPromiseArrayException = (loc) => arrayExceptions.add(promiseArrayExceptionKey(loc));
2398
2398
  const promiseArrayExceptionExists = (loc) => arrayExceptions.has(promiseArrayExceptionKey(loc));
@@ -2519,9 +2519,9 @@ const isBooleanEqualityMatcher = (expectFnCall) => {
2519
2519
  const isInstanceOfBinaryExpression = (node, className) => node.type === AST_NODE_TYPES.BinaryExpression && node.operator === "instanceof" && isSupportedAccessor(node.right, className);
2520
2520
  const hasOnlyOneArgument = (call) => call.arguments.length === 1;
2521
2521
 
2522
- const RULE_NAME$u = "prefer-to-be-object";
2522
+ const RULE_NAME$v = "prefer-to-be-object";
2523
2523
  const preferToBeObject = createEslintRule({
2524
- name: RULE_NAME$u,
2524
+ name: RULE_NAME$v,
2525
2525
  meta: {
2526
2526
  type: "suggestion",
2527
2527
  docs: {
@@ -2594,10 +2594,10 @@ const preferToBeObject = createEslintRule({
2594
2594
  }
2595
2595
  });
2596
2596
 
2597
- const RULE_NAME$t = "prefer-to-be-truthy";
2597
+ const RULE_NAME$u = "prefer-to-be-truthy";
2598
2598
  const isTrueLiteral = (node) => node.type === AST_NODE_TYPES.Literal && node.value === true;
2599
2599
  const preferToBeTruthy = createEslintRule({
2600
- name: RULE_NAME$t,
2600
+ name: RULE_NAME$u,
2601
2601
  meta: {
2602
2602
  type: "suggestion",
2603
2603
  docs: {
@@ -2632,10 +2632,10 @@ const preferToBeTruthy = createEslintRule({
2632
2632
  }
2633
2633
  });
2634
2634
 
2635
- const RULE_NAME$s = "prefer-to-be-falsy";
2635
+ const RULE_NAME$t = "prefer-to-be-falsy";
2636
2636
  const isFalseLiteral = (node) => node.type === AST_NODE_TYPES.Literal && node.value === false;
2637
2637
  const preferToBeFalsy = createEslintRule({
2638
- name: RULE_NAME$s,
2638
+ name: RULE_NAME$t,
2639
2639
  meta: {
2640
2640
  type: "suggestion",
2641
2641
  docs: {
@@ -2670,9 +2670,9 @@ const preferToBeFalsy = createEslintRule({
2670
2670
  }
2671
2671
  });
2672
2672
 
2673
- const RULE_NAME$r = "prefer-to-have-length";
2673
+ const RULE_NAME$s = "prefer-to-have-length";
2674
2674
  const preferToHaveLength = createEslintRule({
2675
- name: RULE_NAME$r,
2675
+ name: RULE_NAME$s,
2676
2676
  meta: {
2677
2677
  type: "suggestion",
2678
2678
  docs: {
@@ -2720,9 +2720,9 @@ const preferToHaveLength = createEslintRule({
2720
2720
  }
2721
2721
  });
2722
2722
 
2723
- const RULE_NAME$q = "prefer-equality-matcher";
2723
+ const RULE_NAME$r = "prefer-equality-matcher";
2724
2724
  const preferEqualityMatcher = createEslintRule({
2725
- name: RULE_NAME$q,
2725
+ name: RULE_NAME$r,
2726
2726
  meta: {
2727
2727
  type: "suggestion",
2728
2728
  docs: {
@@ -2794,9 +2794,9 @@ const preferEqualityMatcher = createEslintRule({
2794
2794
  }
2795
2795
  });
2796
2796
 
2797
- const RULE_NAME$p = "prefer-strict-equal";
2797
+ const RULE_NAME$q = "prefer-strict-equal";
2798
2798
  const preferStrictEqual = createEslintRule({
2799
- name: RULE_NAME$p,
2799
+ name: RULE_NAME$q,
2800
2800
  meta: {
2801
2801
  type: "suggestion",
2802
2802
  docs: {
@@ -2837,9 +2837,9 @@ const preferStrictEqual = createEslintRule({
2837
2837
  }
2838
2838
  });
2839
2839
 
2840
- const RULE_NAME$o = "prefer-expect-resolves";
2840
+ const RULE_NAME$p = "prefer-expect-resolves";
2841
2841
  const preferExpectResolves = createEslintRule({
2842
- name: RULE_NAME$o,
2842
+ name: RULE_NAME$p,
2843
2843
  meta: {
2844
2844
  type: "suggestion",
2845
2845
  docs: {
@@ -2882,9 +2882,9 @@ const preferExpectResolves = createEslintRule({
2882
2882
  })
2883
2883
  });
2884
2884
 
2885
- const RULE_NAME$n = "prefer-each";
2885
+ const RULE_NAME$o = "prefer-each";
2886
2886
  const preferEach = createEslintRule({
2887
- name: RULE_NAME$n,
2887
+ name: RULE_NAME$o,
2888
2888
  meta: {
2889
2889
  type: "suggestion",
2890
2890
  docs: {
@@ -2943,9 +2943,9 @@ const preferEach = createEslintRule({
2943
2943
  }
2944
2944
  });
2945
2945
 
2946
- const RULE_NAME$m = "prefer-hooks-on-top";
2946
+ const RULE_NAME$n = "prefer-hooks-on-top";
2947
2947
  const preferHooksOnTop = createEslintRule({
2948
- name: RULE_NAME$m,
2948
+ name: RULE_NAME$n,
2949
2949
  meta: {
2950
2950
  type: "suggestion",
2951
2951
  docs: {
@@ -2979,10 +2979,10 @@ const preferHooksOnTop = createEslintRule({
2979
2979
  }
2980
2980
  });
2981
2981
 
2982
- const RULE_NAME$l = "prefer-hooks-in-order";
2982
+ const RULE_NAME$m = "prefer-hooks-in-order";
2983
2983
  const HooksOrder = ["beforeAll", "beforeEach", "afterEach", "afterAll"];
2984
2984
  const preferHooksInOrder = createEslintRule({
2985
- name: RULE_NAME$l,
2985
+ name: RULE_NAME$m,
2986
2986
  meta: {
2987
2987
  type: "suggestion",
2988
2988
  docs: {
@@ -3037,7 +3037,7 @@ const preferHooksInOrder = createEslintRule({
3037
3037
  }
3038
3038
  });
3039
3039
 
3040
- const RULE_NAME$k = "prefer-mock-promise-shorthand";
3040
+ const RULE_NAME$l = "prefer-mock-promise-shorthand";
3041
3041
  const withOnce = (name, addOnce) => {
3042
3042
  return `${name}${addOnce ? "Once" : ""}`;
3043
3043
  };
@@ -3049,7 +3049,7 @@ const findSingleReturnArgumentNode = (fnNode) => {
3049
3049
  return null;
3050
3050
  };
3051
3051
  const preferMockPromiseShorthand = createEslintRule({
3052
- name: RULE_NAME$k,
3052
+ name: RULE_NAME$l,
3053
3053
  meta: {
3054
3054
  type: "suggestion",
3055
3055
  docs: {
@@ -3151,10 +3151,10 @@ const areTokensOnSameLine = (left, right) => left.loc.end.line === right.loc.sta
3151
3151
  const isTypeCastExpression = (node) => node.type === AST_NODE_TYPES.TSAsExpression || node.type === AST_NODE_TYPES.TSTypeAssertion;
3152
3152
  const followTypeAssertionChain = (expression) => isTypeCastExpression(expression) ? followTypeAssertionChain(expression.expression) : expression;
3153
3153
 
3154
- const RULE_NAME$j = "prefer-vi-mocked";
3154
+ const RULE_NAME$k = "prefer-vi-mocked";
3155
3155
  const mockTypes = ["Mock", "MockedFunction", "MockedClass", "MockedObject"];
3156
3156
  const preferViMocked = createEslintRule({
3157
- name: RULE_NAME$j,
3157
+ name: RULE_NAME$k,
3158
3158
  meta: {
3159
3159
  type: "suggestion",
3160
3160
  docs: {
@@ -3203,7 +3203,7 @@ const preferViMocked = createEslintRule({
3203
3203
  }
3204
3204
  });
3205
3205
 
3206
- const RULE_NAME$i = "prefer-snapshot-hint";
3206
+ const RULE_NAME$j = "prefer-snapshot-hint";
3207
3207
  const snapshotMatchers = ["toMatchSnapshot", "toThrowErrorMatchingSnapshot"];
3208
3208
  const snapshotMatcherNames = snapshotMatchers;
3209
3209
  const isSnapshotMatcherWithoutHint = (expectFnCall) => {
@@ -3217,7 +3217,7 @@ const isSnapshotMatcherWithoutHint = (expectFnCall) => {
3217
3217
  return !isStringNode(arg);
3218
3218
  };
3219
3219
  const preferSnapshotHint = createEslintRule({
3220
- name: RULE_NAME$i,
3220
+ name: RULE_NAME$j,
3221
3221
  meta: {
3222
3222
  type: "suggestion",
3223
3223
  docs: {
@@ -3295,7 +3295,7 @@ const preferSnapshotHint = createEslintRule({
3295
3295
  }
3296
3296
  });
3297
3297
 
3298
- const RULE_NAME$h = "valid-describe-callback";
3298
+ const RULE_NAME$i = "valid-describe-callback";
3299
3299
  const paramsLocation = (params) => {
3300
3300
  const [first] = params;
3301
3301
  const last = params[params.length - 1];
@@ -3305,7 +3305,7 @@ const paramsLocation = (params) => {
3305
3305
  };
3306
3306
  };
3307
3307
  const validDescribeCallback = createEslintRule({
3308
- name: RULE_NAME$h,
3308
+ name: RULE_NAME$i,
3309
3309
  meta: {
3310
3310
  type: "problem",
3311
3311
  docs: {
@@ -3377,9 +3377,9 @@ const validDescribeCallback = createEslintRule({
3377
3377
  }
3378
3378
  });
3379
3379
 
3380
- const RULE_NAME$g = "require-top-level-describe";
3380
+ const RULE_NAME$h = "require-top-level-describe";
3381
3381
  const requireTopLevelDescribe = createEslintRule({
3382
- name: RULE_NAME$g,
3382
+ name: RULE_NAME$h,
3383
3383
  meta: {
3384
3384
  docs: {
3385
3385
  description: "enforce that all tests are in a top-level describe",
@@ -3448,9 +3448,9 @@ const requireTopLevelDescribe = createEslintRule({
3448
3448
  }
3449
3449
  });
3450
3450
 
3451
- const RULE_NAME$f = "require-to-throw-message";
3451
+ const RULE_NAME$g = "require-to-throw-message";
3452
3452
  const requireToThrowMessage = createEslintRule({
3453
- name: RULE_NAME$f,
3453
+ name: RULE_NAME$g,
3454
3454
  meta: {
3455
3455
  type: "suggestion",
3456
3456
  docs: {
@@ -3483,7 +3483,7 @@ const requireToThrowMessage = createEslintRule({
3483
3483
  }
3484
3484
  });
3485
3485
 
3486
- const RULE_NAME$e = "require-hook";
3486
+ const RULE_NAME$f = "require-hook";
3487
3487
  const isVitestFnCall = (node, context) => {
3488
3488
  if (parseVitestFnCall(node, context))
3489
3489
  return true;
@@ -3510,7 +3510,7 @@ const shouldBeInHook = (node, context, allowedFunctionCalls = []) => {
3510
3510
  }
3511
3511
  };
3512
3512
  const requireHook = createEslintRule({
3513
- name: RULE_NAME$e,
3513
+ name: RULE_NAME$f,
3514
3514
  meta: {
3515
3515
  docs: {
3516
3516
  description: "require setup and teardown to be within a hook",
@@ -3566,9 +3566,9 @@ const requireHook = createEslintRule({
3566
3566
  }
3567
3567
  });
3568
3568
 
3569
- const RULE_NAME$d = "require-local-test-context-for-concurrent-snapshots";
3569
+ const RULE_NAME$e = "require-local-test-context-for-concurrent-snapshots";
3570
3570
  const requireLocalTestContextForConcurrentSnapshots = createEslintRule({
3571
- name: RULE_NAME$d,
3571
+ name: RULE_NAME$e,
3572
3572
  meta: {
3573
3573
  docs: {
3574
3574
  description: "require local Test Context for concurrent snapshot tests",
@@ -3617,7 +3617,7 @@ const requireLocalTestContextForConcurrentSnapshots = createEslintRule({
3617
3617
  }
3618
3618
  });
3619
3619
 
3620
- const RULE_NAME$c = "prefer-todo";
3620
+ const RULE_NAME$d = "prefer-todo";
3621
3621
  const isTargetedTestCase = (vitestFnCall) => {
3622
3622
  if (vitestFnCall.members.some((s) => getAccessorValue(s) !== "skip"))
3623
3623
  return false;
@@ -3636,7 +3636,7 @@ function createTodoFixer(vitestFnCall, fixer) {
3636
3636
  return fixer.replaceText(vitestFnCall.head.node, `${vitestFnCall.head.local}.todo`);
3637
3637
  }
3638
3638
  const preferTodo = createEslintRule({
3639
- name: RULE_NAME$c,
3639
+ name: RULE_NAME$d,
3640
3640
  meta: {
3641
3641
  type: "layout",
3642
3642
  docs: {
@@ -3680,7 +3680,7 @@ const preferTodo = createEslintRule({
3680
3680
  }
3681
3681
  });
3682
3682
 
3683
- const RULE_NAME$b = "prefer-spy-on";
3683
+ const RULE_NAME$c = "prefer-spy-on";
3684
3684
  const findNodeObject = (node) => {
3685
3685
  if ("object" in node)
3686
3686
  return node.object;
@@ -3708,7 +3708,7 @@ const getAutoFixMockImplementation = (vitestFnCall, context) => {
3708
3708
  return argSource ? `.mockImplementation(${argSource})` : ".mockImplementation()";
3709
3709
  };
3710
3710
  const preferSpyOn = createEslintRule({
3711
- name: RULE_NAME$b,
3711
+ name: RULE_NAME$c,
3712
3712
  meta: {
3713
3713
  type: "suggestion",
3714
3714
  docs: {
@@ -3755,7 +3755,7 @@ const preferSpyOn = createEslintRule({
3755
3755
  }
3756
3756
  });
3757
3757
 
3758
- const RULE_NAME$a = "prefer-comparison-matcher";
3758
+ const RULE_NAME$b = "prefer-comparison-matcher";
3759
3759
  const isString = (node) => {
3760
3760
  return isStringNode(node) || node?.type === AST_NODE_TYPES.TemplateLiteral;
3761
3761
  };
@@ -3790,7 +3790,7 @@ const determineMatcher = (operator, negated) => {
3790
3790
  return null;
3791
3791
  };
3792
3792
  const preferComparisonMatcher = createEslintRule({
3793
- name: RULE_NAME$a,
3793
+ name: RULE_NAME$b,
3794
3794
  meta: {
3795
3795
  type: "suggestion",
3796
3796
  docs: {
@@ -3854,10 +3854,10 @@ const preferComparisonMatcher = createEslintRule({
3854
3854
  }
3855
3855
  });
3856
3856
 
3857
- const RULE_NAME$9 = "prefer-to-contain";
3857
+ const RULE_NAME$a = "prefer-to-contain";
3858
3858
  const isFixableIncludesCallExpression = (node) => node.type === AST_NODE_TYPES.CallExpression && node.callee.type === AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.callee.property, "includes") && hasOnlyOneArgument(node) && node.arguments[0].type !== AST_NODE_TYPES.SpreadElement;
3859
3859
  const preferToContain = createEslintRule({
3860
- name: RULE_NAME$9,
3860
+ name: RULE_NAME$a,
3861
3861
  meta: {
3862
3862
  docs: {
3863
3863
  description: "enforce using toContain()",
@@ -3916,7 +3916,7 @@ const preferToContain = createEslintRule({
3916
3916
  }
3917
3917
  });
3918
3918
 
3919
- const RULE_NAME$8 = "prefer-expect-assertions";
3919
+ const RULE_NAME$9 = "prefer-expect-assertions";
3920
3920
  const isFirstStatement = (node) => {
3921
3921
  let parent = node;
3922
3922
  while (parent) {
@@ -4289,7 +4289,7 @@ const createPaddingRule = (name, description, configs, deprecated = false) => {
4289
4289
  });
4290
4290
  };
4291
4291
 
4292
- const RULE_NAME$7 = "padding-around-after-all-blocks";
4292
+ const RULE_NAME$8 = "padding-around-after-all-blocks";
4293
4293
  const config$6 = [
4294
4294
  {
4295
4295
  paddingType: PaddingType.Always,
@@ -4302,9 +4302,9 @@ const config$6 = [
4302
4302
  nextStatementType: StatementType.Any
4303
4303
  }
4304
4304
  ];
4305
- const paddingAroundAfterAllBlocks = createPaddingRule(RULE_NAME$7, "Enforce padding around `afterAll` blocks", config$6);
4305
+ const paddingAroundAfterAllBlocks = createPaddingRule(RULE_NAME$8, "Enforce padding around `afterAll` blocks", config$6);
4306
4306
 
4307
- const RULE_NAME$6 = "padding-around-after-each-blocks";
4307
+ const RULE_NAME$7 = "padding-around-after-each-blocks";
4308
4308
  const config$5 = [
4309
4309
  {
4310
4310
  paddingType: PaddingType.Always,
@@ -4317,9 +4317,9 @@ const config$5 = [
4317
4317
  nextStatementType: StatementType.Any
4318
4318
  }
4319
4319
  ];
4320
- const paddingAroundAfterEachBlocks = createPaddingRule(RULE_NAME$6, "Enforce padding around `afterEach` blocks", config$5);
4320
+ const paddingAroundAfterEachBlocks = createPaddingRule(RULE_NAME$7, "Enforce padding around `afterEach` blocks", config$5);
4321
4321
 
4322
- const RULE_NAME$5 = "padding-around-before-all-blocks";
4322
+ const RULE_NAME$6 = "padding-around-before-all-blocks";
4323
4323
  const config$4 = [
4324
4324
  {
4325
4325
  paddingType: PaddingType.Always,
@@ -4332,9 +4332,9 @@ const config$4 = [
4332
4332
  nextStatementType: StatementType.Any
4333
4333
  }
4334
4334
  ];
4335
- const paddingAroundBeforeAllBlocks = createPaddingRule(RULE_NAME$5, "Enforce padding around `beforeAll` blocks", config$4);
4335
+ const paddingAroundBeforeAllBlocks = createPaddingRule(RULE_NAME$6, "Enforce padding around `beforeAll` blocks", config$4);
4336
4336
 
4337
- const RULE_NAME$4 = "padding-around-before-each-blocks";
4337
+ const RULE_NAME$5 = "padding-around-before-each-blocks";
4338
4338
  const config$3 = [
4339
4339
  {
4340
4340
  paddingType: PaddingType.Always,
@@ -4348,12 +4348,12 @@ const config$3 = [
4348
4348
  }
4349
4349
  ];
4350
4350
  const paddingAroundBeforeEachBlocks = createPaddingRule(
4351
- RULE_NAME$4,
4351
+ RULE_NAME$5,
4352
4352
  "Enforce padding around `beforeEach` blocks",
4353
4353
  config$3
4354
4354
  );
4355
4355
 
4356
- const RULE_NAME$3 = "padding-around-describe-blocks";
4356
+ const RULE_NAME$4 = "padding-around-describe-blocks";
4357
4357
  const config$2 = [
4358
4358
  {
4359
4359
  paddingType: PaddingType.Always,
@@ -4375,12 +4375,12 @@ const config$2 = [
4375
4375
  }
4376
4376
  ];
4377
4377
  const paddingAroundDescribeBlocks = createPaddingRule(
4378
- RULE_NAME$3,
4378
+ RULE_NAME$4,
4379
4379
  "Enforce padding around `describe` blocks",
4380
4380
  config$2
4381
4381
  );
4382
4382
 
4383
- const RULE_NAME$2 = "padding-around-expect-groups";
4383
+ const RULE_NAME$3 = "padding-around-expect-groups";
4384
4384
  const config$1 = [
4385
4385
  {
4386
4386
  paddingType: PaddingType.Always,
@@ -4399,12 +4399,12 @@ const config$1 = [
4399
4399
  }
4400
4400
  ];
4401
4401
  const paddingAroundExpectGroups = createPaddingRule(
4402
- RULE_NAME$2,
4402
+ RULE_NAME$3,
4403
4403
  "Enforce padding around `expect` groups",
4404
4404
  config$1
4405
4405
  );
4406
4406
 
4407
- const RULE_NAME$1 = "padding-around-test-blocks";
4407
+ const RULE_NAME$2 = "padding-around-test-blocks";
4408
4408
  const config = [
4409
4409
  {
4410
4410
  paddingType: PaddingType.Always,
@@ -4430,14 +4430,14 @@ const config = [
4430
4430
  }
4431
4431
  ];
4432
4432
  const paddingAroundTestBlocks = createPaddingRule(
4433
- RULE_NAME$1,
4433
+ RULE_NAME$2,
4434
4434
  "Enforce padding around afterAll blocks",
4435
4435
  config
4436
4436
  );
4437
4437
 
4438
- const RULE_NAME = "padding-around-all";
4438
+ const RULE_NAME$1 = "padding-around-all";
4439
4439
  const paddingAroundAll = createPaddingRule(
4440
- RULE_NAME,
4440
+ RULE_NAME$1,
4441
4441
  "Enforce padding around vitest functions",
4442
4442
  [
4443
4443
  ...config$6,
@@ -4450,6 +4450,256 @@ const paddingAroundAll = createPaddingRule(
4450
4450
  ]
4451
4451
  );
4452
4452
 
4453
+ const RULE_NAME = "valid-expect-in-promise";
4454
+ const defaultAsyncMatchers = ["toRejectWith", "toResolveWith"];
4455
+ const isPromiseChainCall = (node) => {
4456
+ if (node.type === AST_NODE_TYPES.CallExpression && node.callee.type === AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.callee.property)) {
4457
+ if (node.arguments.length === 0) {
4458
+ return false;
4459
+ }
4460
+ switch (getAccessorValue(node.callee.property)) {
4461
+ case "then":
4462
+ return node.arguments.length < 3;
4463
+ case "catch":
4464
+ case "finally":
4465
+ return node.arguments.length < 2;
4466
+ }
4467
+ }
4468
+ return false;
4469
+ };
4470
+ const isTestCaseCallWithCallbackArg = (node, context) => {
4471
+ const vitestCallFn = parseVitestFnCall(node, context);
4472
+ if (vitestCallFn?.type !== "test") {
4473
+ return false;
4474
+ }
4475
+ const isVitestEach = vitestCallFn.members.some(
4476
+ (s) => getAccessorValue(s) === "each"
4477
+ );
4478
+ if (isVitestEach && node.callee.type !== AST_NODE_TYPES.TaggedTemplateExpression) {
4479
+ return true;
4480
+ }
4481
+ const [, callback] = node.arguments;
4482
+ const callbackArgIndex = Number(isVitestEach);
4483
+ return callback && isFunction(callback) && callback.params.length === 1 + callbackArgIndex;
4484
+ };
4485
+ const isPromiseMethodThatUsesValue = (node, identifier) => {
4486
+ const { name } = identifier;
4487
+ if (node.argument === null) {
4488
+ return false;
4489
+ }
4490
+ if (node.argument.type === AST_NODE_TYPES.CallExpression && node.argument.arguments.length > 0) {
4491
+ const nodeName = getNodeName(node.argument);
4492
+ if (["Promise.all", "Promise.allSettled"].includes(nodeName)) {
4493
+ const [firstArg] = node.argument.arguments;
4494
+ if (firstArg.type === AST_NODE_TYPES.ArrayExpression && firstArg.elements.some((nod) => nod && isIdentifier(nod, name))) {
4495
+ return true;
4496
+ }
4497
+ }
4498
+ if (["Promise.resolve", "Promise.reject"].includes(nodeName) && node.argument.arguments.length === 1) {
4499
+ return isIdentifier(node.argument.arguments[0], name);
4500
+ }
4501
+ }
4502
+ return isIdentifier(node.argument, name);
4503
+ };
4504
+ const isValueAwaitedInElements = (name, elements) => {
4505
+ for (const element of elements) {
4506
+ if (element?.type === AST_NODE_TYPES.AwaitExpression && isIdentifier(element.argument, name)) {
4507
+ return true;
4508
+ }
4509
+ if (element?.type === AST_NODE_TYPES.ArrayExpression && isValueAwaitedInElements(name, element.elements)) {
4510
+ return true;
4511
+ }
4512
+ }
4513
+ return false;
4514
+ };
4515
+ const isValueAwaitedInArguments = (name, call) => {
4516
+ let node = call;
4517
+ while (node) {
4518
+ if (node.type === AST_NODE_TYPES.CallExpression) {
4519
+ if (isValueAwaitedInElements(name, node.arguments)) {
4520
+ return true;
4521
+ }
4522
+ node = node.callee;
4523
+ }
4524
+ if (node.type !== AST_NODE_TYPES.MemberExpression) {
4525
+ break;
4526
+ }
4527
+ node = node.object;
4528
+ }
4529
+ return false;
4530
+ };
4531
+ const getLeftMostCallExpression = (call) => {
4532
+ let leftMostCallExpression = call;
4533
+ let node = call;
4534
+ while (node) {
4535
+ if (node.type === AST_NODE_TYPES.CallExpression) {
4536
+ leftMostCallExpression = node;
4537
+ node = node.callee;
4538
+ }
4539
+ if (node.type !== AST_NODE_TYPES.MemberExpression) {
4540
+ break;
4541
+ }
4542
+ node = node.object;
4543
+ }
4544
+ return leftMostCallExpression;
4545
+ };
4546
+ const isValueAwaitedOrReturned = (identifier, body, context) => {
4547
+ const { name } = identifier;
4548
+ for (const node of body) {
4549
+ if (node.range[0] <= identifier.range[0]) {
4550
+ continue;
4551
+ }
4552
+ if (node.type === AST_NODE_TYPES.ReturnStatement) {
4553
+ return isPromiseMethodThatUsesValue(node, identifier);
4554
+ }
4555
+ if (node.type === AST_NODE_TYPES.ExpressionStatement) {
4556
+ if (node.expression.type === AST_NODE_TYPES.CallExpression) {
4557
+ if (isValueAwaitedInArguments(name, node.expression)) {
4558
+ return true;
4559
+ }
4560
+ const leftMostCall = getLeftMostCallExpression(node.expression);
4561
+ const vitestFnCall = parseVitestFnCall(node.expression, context);
4562
+ if (vitestFnCall?.type === "expect" && leftMostCall.arguments.length > 0 && isIdentifier(leftMostCall.arguments[0], name)) {
4563
+ if (vitestFnCall.members.some((m) => {
4564
+ const v = getAccessorValue(m);
4565
+ return v === ModifierName.resolves || v === ModifierName.rejects;
4566
+ })) {
4567
+ return true;
4568
+ }
4569
+ }
4570
+ }
4571
+ if (node.expression.type === AST_NODE_TYPES.AwaitExpression && isPromiseMethodThatUsesValue(node.expression, identifier)) {
4572
+ return true;
4573
+ }
4574
+ if (node.expression.type === AST_NODE_TYPES.AssignmentExpression) {
4575
+ if (isIdentifier(node.expression.left, name) && getNodeName(node.expression.right)?.startsWith(`${name}.`) && isPromiseChainCall(node.expression.right)) {
4576
+ continue;
4577
+ }
4578
+ break;
4579
+ }
4580
+ }
4581
+ if (node.type === AST_NODE_TYPES.BlockStatement && isValueAwaitedOrReturned(identifier, node.body, context)) {
4582
+ return true;
4583
+ }
4584
+ }
4585
+ return false;
4586
+ };
4587
+ const findFirstBlockBodyUp = (node) => {
4588
+ let parent = node;
4589
+ while (parent) {
4590
+ if (parent.type === AST_NODE_TYPES.BlockStatement) {
4591
+ return parent.body;
4592
+ }
4593
+ parent = parent.parent;
4594
+ }
4595
+ throw new Error(
4596
+ `Could not find BlockStatement - please file a github issue at https://github.com/vitest-dev/eslint-plugin-vitest`
4597
+ );
4598
+ };
4599
+ const isDirectlyWithinTestCaseCall = (node, context) => {
4600
+ let parent = node;
4601
+ while (parent) {
4602
+ if (isFunction(parent)) {
4603
+ parent = parent.parent;
4604
+ return parent?.type === AST_NODE_TYPES.CallExpression && isTypeOfVitestFnCall(parent, context, ["test"]);
4605
+ }
4606
+ parent = parent.parent;
4607
+ }
4608
+ return false;
4609
+ };
4610
+ const isVariableAwaitedOrReturned = (variable, context) => {
4611
+ const body = findFirstBlockBodyUp(variable);
4612
+ if (!isIdentifier(variable.id)) {
4613
+ return true;
4614
+ }
4615
+ return isValueAwaitedOrReturned(variable.id, body, context);
4616
+ };
4617
+ const validExpectInPromise = createEslintRule({
4618
+ name: __filename,
4619
+ meta: {
4620
+ docs: {
4621
+ description: "Require promises that have expectations in their chain to be valid"
4622
+ },
4623
+ messages: {
4624
+ expectInFloatingPromise: "This promise should either be returned or awaited to ensure the expects in its chain are called"
4625
+ },
4626
+ type: "suggestion",
4627
+ schema: []
4628
+ },
4629
+ defaultOptions: [{
4630
+ alwaysAwait: false,
4631
+ asyncMatchers: defaultAsyncMatchers,
4632
+ minArgs: 1,
4633
+ maxArgs: 1
4634
+ }],
4635
+ create(context) {
4636
+ let inTestCaseWithDoneCallback = false;
4637
+ const chains = [];
4638
+ return {
4639
+ CallExpression(node) {
4640
+ if (isTestCaseCallWithCallbackArg(node, context)) {
4641
+ inTestCaseWithDoneCallback = true;
4642
+ return;
4643
+ }
4644
+ if (isPromiseChainCall(node)) {
4645
+ chains.unshift(false);
4646
+ return;
4647
+ }
4648
+ if (chains.length > 0 && isTypeOfVitestFnCall(node, context, ["expect"])) {
4649
+ chains[0] = true;
4650
+ }
4651
+ },
4652
+ "CallExpression:exit"(node) {
4653
+ if (inTestCaseWithDoneCallback) {
4654
+ if (isTypeOfVitestFnCall(node, context, ["test"])) {
4655
+ inTestCaseWithDoneCallback = false;
4656
+ }
4657
+ return;
4658
+ }
4659
+ if (!isPromiseChainCall(node)) {
4660
+ return;
4661
+ }
4662
+ const hasExpectCall = chains.shift();
4663
+ if (!hasExpectCall) {
4664
+ return;
4665
+ }
4666
+ const { parent } = findTopMostCallExpression(node);
4667
+ if (!parent || !isDirectlyWithinTestCaseCall(parent, context)) {
4668
+ return;
4669
+ }
4670
+ switch (parent.type) {
4671
+ case AST_NODE_TYPES.VariableDeclarator: {
4672
+ if (isVariableAwaitedOrReturned(parent, context)) {
4673
+ return;
4674
+ }
4675
+ break;
4676
+ }
4677
+ case AST_NODE_TYPES.AssignmentExpression: {
4678
+ if (parent.left.type === AST_NODE_TYPES.Identifier && isValueAwaitedOrReturned(
4679
+ parent.left,
4680
+ findFirstBlockBodyUp(parent),
4681
+ context
4682
+ )) {
4683
+ return;
4684
+ }
4685
+ break;
4686
+ }
4687
+ case AST_NODE_TYPES.ExpressionStatement:
4688
+ break;
4689
+ case AST_NODE_TYPES.ReturnStatement:
4690
+ case AST_NODE_TYPES.AwaitExpression:
4691
+ default:
4692
+ return;
4693
+ }
4694
+ context.report({
4695
+ messageId: "expectInFloatingPromise",
4696
+ node: parent
4697
+ });
4698
+ }
4699
+ };
4700
+ }
4701
+ });
4702
+
4453
4703
  const createConfig = (rules) => Object.keys(rules).reduce((acc, ruleName) => {
4454
4704
  return {
4455
4705
  ...acc,
@@ -4466,17 +4716,18 @@ const createConfigLegacy = (rules) => ({
4466
4716
  }, {})
4467
4717
  });
4468
4718
  const allRules = {
4719
+ [RULE_NAME$Z]: "warn",
4469
4720
  [RULE_NAME$Y]: "warn",
4470
- [RULE_NAME$X]: "warn",
4721
+ [RULE_NAME$W]: "warn",
4471
4722
  [RULE_NAME$V]: "warn",
4472
- [RULE_NAME$U]: "warn",
4473
- [RULE_NAME$S]: "warn",
4723
+ [RULE_NAME$T]: "warn",
4724
+ [RULE_NAME$R]: "warn",
4474
4725
  [RULE_NAME$Q]: "warn",
4475
4726
  [RULE_NAME$P]: "warn",
4476
4727
  [RULE_NAME$O]: "warn",
4477
4728
  [RULE_NAME$N]: "warn",
4478
- [RULE_NAME$M]: "warn",
4479
- [RULE_NAME$K]: "warn",
4729
+ [RULE_NAME$L]: "warn",
4730
+ [RULE_NAME$J]: "warn",
4480
4731
  [RULE_NAME$I]: "warn",
4481
4732
  [RULE_NAME$H]: "warn",
4482
4733
  [RULE_NAME$G]: "warn",
@@ -4488,10 +4739,10 @@ const allRules = {
4488
4739
  [RULE_NAME$A]: "warn",
4489
4740
  [RULE_NAME$z]: "warn",
4490
4741
  [RULE_NAME$y]: "warn",
4491
- [RULE_NAME$x]: "warn",
4492
- [RULE_NAME$s]: "warn",
4493
- [RULE_NAME$u]: "warn",
4494
4742
  [RULE_NAME$t]: "warn",
4743
+ [RULE_NAME$v]: "warn",
4744
+ [RULE_NAME$u]: "warn",
4745
+ [RULE_NAME$s]: "warn",
4495
4746
  [RULE_NAME$r]: "warn",
4496
4747
  [RULE_NAME$q]: "warn",
4497
4748
  [RULE_NAME$p]: "warn",
@@ -4501,34 +4752,34 @@ const allRules = {
4501
4752
  [RULE_NAME$l]: "warn",
4502
4753
  [RULE_NAME$k]: "warn",
4503
4754
  [RULE_NAME$j]: "warn",
4504
- [RULE_NAME$i]: "warn",
4755
+ [RULE_NAME$h]: "warn",
4505
4756
  [RULE_NAME$g]: "warn",
4506
4757
  [RULE_NAME$f]: "warn",
4507
- [RULE_NAME$e]: "warn",
4758
+ [RULE_NAME$d]: "warn",
4508
4759
  [RULE_NAME$c]: "warn",
4509
4760
  [RULE_NAME$b]: "warn",
4510
4761
  [RULE_NAME$a]: "warn",
4511
4762
  [RULE_NAME$9]: "warn",
4763
+ [RULE_NAME$S]: "warn",
4512
4764
  [RULE_NAME$8]: "warn",
4513
- [RULE_NAME$R]: "warn",
4514
4765
  [RULE_NAME$7]: "warn",
4766
+ [RULE_NAME$1]: "warn",
4515
4767
  [RULE_NAME$6]: "warn",
4516
- [RULE_NAME]: "warn",
4517
4768
  [RULE_NAME$5]: "warn",
4518
4769
  [RULE_NAME$4]: "warn",
4519
4770
  [RULE_NAME$3]: "warn",
4520
4771
  [RULE_NAME$2]: "warn",
4521
- [RULE_NAME$1]: "warn"
4772
+ [RULE_NAME]: "warn"
4522
4773
  };
4523
4774
  const recommended = {
4524
- [RULE_NAME$T]: "error",
4525
- [RULE_NAME$W]: "error",
4526
- [RULE_NAME$L]: "error",
4775
+ [RULE_NAME$U]: "error",
4776
+ [RULE_NAME$X]: "error",
4777
+ [RULE_NAME$M]: "error",
4778
+ [RULE_NAME$x]: "error",
4527
4779
  [RULE_NAME$w]: "error",
4528
- [RULE_NAME$v]: "error",
4529
- [RULE_NAME$h]: "error",
4530
- [RULE_NAME$d]: "error",
4531
- [RULE_NAME$J]: "error"
4780
+ [RULE_NAME$i]: "error",
4781
+ [RULE_NAME$e]: "error",
4782
+ [RULE_NAME$K]: "error"
4532
4783
  };
4533
4784
  const plugin = {
4534
4785
  meta: {
@@ -4536,67 +4787,68 @@ const plugin = {
4536
4787
  version
4537
4788
  },
4538
4789
  rules: {
4539
- [RULE_NAME$Y]: lowerCaseTitle,
4540
- [RULE_NAME$X]: maxNestedDescribe,
4541
- [RULE_NAME$W]: noIdenticalTitle,
4542
- [RULE_NAME$V]: noFocusedTests,
4543
- [RULE_NAME$U]: noConditionalTest,
4544
- [RULE_NAME$T]: expectExpect,
4545
- [RULE_NAME$S]: consistentTestIt,
4546
- [RULE_NAME$R]: preferToBe,
4547
- [RULE_NAME$Q]: noHooks,
4548
- [RULE_NAME$P]: noRestrictedViMethods,
4549
- [RULE_NAME$O]: consistentTestFilename,
4550
- [RULE_NAME$N]: maxExpect,
4551
- [RULE_NAME$M]: noAliasMethod,
4552
- [RULE_NAME$L]: noCommentedOutTests,
4553
- [RULE_NAME$K]: noConditionalExpect,
4554
- [RULE_NAME$I]: noConditionalInTest,
4555
- [RULE_NAME$H]: noDisabledTests,
4556
- [RULE_NAME$G]: noDoneCallback,
4557
- [RULE_NAME$F]: noDuplicateHooks,
4558
- [RULE_NAME$E]: noLargeSnapshots,
4559
- [RULE_NAME$D]: nonInterpolationInSnapShots,
4560
- [RULE_NAME$C]: noMocksImport,
4561
- [RULE_NAME$B]: noRestrictedMatchers,
4562
- [RULE_NAME$A]: noStandaloneExpect,
4563
- [RULE_NAME$z]: noTestPrefixes,
4564
- [RULE_NAME$y]: noTestReturnStatement,
4565
- [RULE_NAME$J]: noImportNodeTest,
4566
- [RULE_NAME$x]: preferCalledWith,
4567
- [RULE_NAME$w]: validTitle,
4568
- [RULE_NAME$v]: validExpect,
4569
- [RULE_NAME$s]: preferToBeFalsy,
4570
- [RULE_NAME$u]: preferToBeObject,
4571
- [RULE_NAME$t]: preferToBeTruthy,
4572
- [RULE_NAME$r]: preferToHaveLength,
4573
- [RULE_NAME$q]: preferEqualityMatcher,
4574
- [RULE_NAME$p]: preferStrictEqual,
4575
- [RULE_NAME$o]: preferExpectResolves,
4576
- [RULE_NAME$n]: preferEach,
4577
- [RULE_NAME$m]: preferHooksOnTop,
4578
- [RULE_NAME$l]: preferHooksInOrder,
4579
- [RULE_NAME$d]: requireLocalTestContextForConcurrentSnapshots,
4580
- [RULE_NAME$k]: preferMockPromiseShorthand,
4581
- [RULE_NAME$j]: preferViMocked,
4582
- [RULE_NAME$i]: preferSnapshotHint,
4583
- [RULE_NAME$h]: validDescribeCallback,
4584
- [RULE_NAME$g]: requireTopLevelDescribe,
4585
- [RULE_NAME$f]: requireToThrowMessage,
4586
- [RULE_NAME$e]: requireHook,
4587
- [RULE_NAME$c]: preferTodo,
4588
- [RULE_NAME$b]: preferSpyOn,
4589
- [RULE_NAME$a]: preferComparisonMatcher,
4590
- [RULE_NAME$9]: preferToContain,
4591
- [RULE_NAME$8]: preferExpectAssertions,
4592
- [RULE_NAME$7]: paddingAroundAfterAllBlocks,
4593
- [RULE_NAME$6]: paddingAroundAfterEachBlocks,
4594
- [RULE_NAME]: paddingAroundAll,
4595
- [RULE_NAME$5]: paddingAroundBeforeAllBlocks,
4596
- [RULE_NAME$4]: paddingAroundBeforeEachBlocks,
4597
- [RULE_NAME$3]: paddingAroundDescribeBlocks,
4598
- [RULE_NAME$2]: paddingAroundExpectGroups,
4599
- [RULE_NAME$1]: paddingAroundTestBlocks
4790
+ [RULE_NAME$Z]: lowerCaseTitle,
4791
+ [RULE_NAME$Y]: maxNestedDescribe,
4792
+ [RULE_NAME$X]: noIdenticalTitle,
4793
+ [RULE_NAME$W]: noFocusedTests,
4794
+ [RULE_NAME$V]: noConditionalTest,
4795
+ [RULE_NAME$U]: expectExpect,
4796
+ [RULE_NAME$T]: consistentTestIt,
4797
+ [RULE_NAME$S]: preferToBe,
4798
+ [RULE_NAME$R]: noHooks,
4799
+ [RULE_NAME$Q]: noRestrictedViMethods,
4800
+ [RULE_NAME$P]: consistentTestFilename,
4801
+ [RULE_NAME$O]: maxExpect,
4802
+ [RULE_NAME$N]: noAliasMethod,
4803
+ [RULE_NAME$M]: noCommentedOutTests,
4804
+ [RULE_NAME$L]: noConditionalExpect,
4805
+ [RULE_NAME$J]: noConditionalInTest,
4806
+ [RULE_NAME$I]: noDisabledTests,
4807
+ [RULE_NAME$H]: noDoneCallback,
4808
+ [RULE_NAME$G]: noDuplicateHooks,
4809
+ [RULE_NAME$F]: noLargeSnapshots,
4810
+ [RULE_NAME$E]: nonInterpolationInSnapShots,
4811
+ [RULE_NAME$D]: noMocksImport,
4812
+ [RULE_NAME$C]: noRestrictedMatchers,
4813
+ [RULE_NAME$B]: noStandaloneExpect,
4814
+ [RULE_NAME$A]: noTestPrefixes,
4815
+ [RULE_NAME$z]: noTestReturnStatement,
4816
+ [RULE_NAME$K]: noImportNodeTest,
4817
+ [RULE_NAME$y]: preferCalledWith,
4818
+ [RULE_NAME$x]: validTitle,
4819
+ [RULE_NAME$w]: validExpect,
4820
+ [RULE_NAME$t]: preferToBeFalsy,
4821
+ [RULE_NAME$v]: preferToBeObject,
4822
+ [RULE_NAME$u]: preferToBeTruthy,
4823
+ [RULE_NAME$s]: preferToHaveLength,
4824
+ [RULE_NAME$r]: preferEqualityMatcher,
4825
+ [RULE_NAME$q]: preferStrictEqual,
4826
+ [RULE_NAME$p]: preferExpectResolves,
4827
+ [RULE_NAME$o]: preferEach,
4828
+ [RULE_NAME$n]: preferHooksOnTop,
4829
+ [RULE_NAME$m]: preferHooksInOrder,
4830
+ [RULE_NAME$e]: requireLocalTestContextForConcurrentSnapshots,
4831
+ [RULE_NAME$l]: preferMockPromiseShorthand,
4832
+ [RULE_NAME$k]: preferViMocked,
4833
+ [RULE_NAME$j]: preferSnapshotHint,
4834
+ [RULE_NAME$i]: validDescribeCallback,
4835
+ [RULE_NAME$h]: requireTopLevelDescribe,
4836
+ [RULE_NAME$g]: requireToThrowMessage,
4837
+ [RULE_NAME$f]: requireHook,
4838
+ [RULE_NAME$d]: preferTodo,
4839
+ [RULE_NAME$c]: preferSpyOn,
4840
+ [RULE_NAME$b]: preferComparisonMatcher,
4841
+ [RULE_NAME$a]: preferToContain,
4842
+ [RULE_NAME$9]: preferExpectAssertions,
4843
+ [RULE_NAME$8]: paddingAroundAfterAllBlocks,
4844
+ [RULE_NAME$7]: paddingAroundAfterEachBlocks,
4845
+ [RULE_NAME$1]: paddingAroundAll,
4846
+ [RULE_NAME$6]: paddingAroundBeforeAllBlocks,
4847
+ [RULE_NAME$5]: paddingAroundBeforeEachBlocks,
4848
+ [RULE_NAME$4]: paddingAroundDescribeBlocks,
4849
+ [RULE_NAME$3]: paddingAroundExpectGroups,
4850
+ [RULE_NAME$2]: paddingAroundTestBlocks,
4851
+ [RULE_NAME]: validExpectInPromise
4600
4852
  },
4601
4853
  configs: {
4602
4854
  "legacy-recommended": createConfigLegacy(recommended),