@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.cjs CHANGED
@@ -23,7 +23,7 @@ function _interopNamespaceCompat(e) {
23
23
  const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
24
24
  const ts__default = /*#__PURE__*/_interopDefaultCompat(ts);
25
25
 
26
- const version = "1.1.6";
26
+ const version = "1.1.8";
27
27
 
28
28
  function createEslintRule(rule) {
29
29
  const createRule = utils.ESLintUtils.RuleCreator(
@@ -365,7 +365,7 @@ const getFirstMatcherArg = (expectFnCall) => {
365
365
  const isTypeCastExpression$1 = (node) => node.type === utils.AST_NODE_TYPES.TSAsExpression || node.type === utils.AST_NODE_TYPES.TSTypeAssertion;
366
366
  const followTypeAssertionChain$1 = (expression) => isTypeCastExpression$1(expression) ? followTypeAssertionChain$1(expression.expression) : expression;
367
367
 
368
- const RULE_NAME$Y = "prefer-lowercase-title";
368
+ const RULE_NAME$Z = "prefer-lowercase-title";
369
369
  const hasStringAsFirstArgument = (node) => node.arguments[0] && isStringNode(node.arguments[0]);
370
370
  const populateIgnores = (ignore) => {
371
371
  const ignores = [];
@@ -384,7 +384,7 @@ const populateIgnores = (ignore) => {
384
384
  return ignores;
385
385
  };
386
386
  const lowerCaseTitle = createEslintRule({
387
- name: RULE_NAME$Y,
387
+ name: RULE_NAME$Z,
388
388
  meta: {
389
389
  type: "problem",
390
390
  docs: {
@@ -481,9 +481,9 @@ const lowerCaseTitle = createEslintRule({
481
481
  }
482
482
  });
483
483
 
484
- const RULE_NAME$X = "max-nested-describe";
484
+ const RULE_NAME$Y = "max-nested-describe";
485
485
  const maxNestedDescribe = createEslintRule({
486
- name: RULE_NAME$X,
486
+ name: RULE_NAME$Y,
487
487
  meta: {
488
488
  type: "problem",
489
489
  docs: {
@@ -541,13 +541,13 @@ const maxNestedDescribe = createEslintRule({
541
541
  }
542
542
  });
543
543
 
544
- const RULE_NAME$W = "no-identical-title";
544
+ const RULE_NAME$X = "no-identical-title";
545
545
  const newDescribeContext = () => ({
546
546
  describeTitles: [],
547
547
  testTitles: []
548
548
  });
549
549
  const noIdenticalTitle = createEslintRule({
550
- name: RULE_NAME$W,
550
+ name: RULE_NAME$X,
551
551
  meta: {
552
552
  type: "problem",
553
553
  docs: {
@@ -605,7 +605,7 @@ const noIdenticalTitle = createEslintRule({
605
605
  }
606
606
  });
607
607
 
608
- const RULE_NAME$V = "no-focused-tests";
608
+ const RULE_NAME$W = "no-focused-tests";
609
609
  const isTestOrDescribe = (node) => {
610
610
  return node.type === "Identifier" && ["it", "test", "describe"].includes(node.name);
611
611
  };
@@ -613,7 +613,7 @@ const isOnly = (node) => {
613
613
  return node.type === "Identifier" && node.name === "only";
614
614
  };
615
615
  const noFocusedTests = createEslintRule({
616
- name: RULE_NAME$V,
616
+ name: RULE_NAME$W,
617
617
  meta: {
618
618
  type: "problem",
619
619
  docs: {
@@ -685,9 +685,9 @@ const noFocusedTests = createEslintRule({
685
685
  }
686
686
  });
687
687
 
688
- const RULE_NAME$U = "no-conditional-tests";
688
+ const RULE_NAME$V = "no-conditional-tests";
689
689
  const noConditionalTest = createEslintRule({
690
- name: RULE_NAME$U,
690
+ name: RULE_NAME$V,
691
691
  meta: {
692
692
  type: "problem",
693
693
  docs: {
@@ -727,7 +727,7 @@ function parsePluginSettings(settings) {
727
727
  };
728
728
  }
729
729
 
730
- const RULE_NAME$T = "expect-expect";
730
+ const RULE_NAME$U = "expect-expect";
731
731
  function matchesAssertFunctionName(nodeName, patterns) {
732
732
  return patterns.some(
733
733
  (p) => new RegExp(
@@ -741,7 +741,7 @@ function matchesAssertFunctionName(nodeName, patterns) {
741
741
  );
742
742
  }
743
743
  const expectExpect = createEslintRule({
744
- name: RULE_NAME$T,
744
+ name: RULE_NAME$U,
745
745
  meta: {
746
746
  type: "suggestion",
747
747
  docs: {
@@ -754,7 +754,7 @@ const expectExpect = createEslintRule({
754
754
  properties: {
755
755
  assertFunctionNames: {
756
756
  type: "array",
757
- items: [{ type: "string" }]
757
+ items: { type: "string" }
758
758
  },
759
759
  additionalTestBlockFunctions: {
760
760
  type: "array",
@@ -817,7 +817,7 @@ const expectExpect = createEslintRule({
817
817
  }
818
818
  });
819
819
 
820
- const RULE_NAME$S = "consistent-test-it";
820
+ const RULE_NAME$T = "consistent-test-it";
821
821
  const buildFixer = (callee, nodeName, preferredTestKeyword) => (fixer) => [
822
822
  fixer.replaceText(
823
823
  callee.type === utils.AST_NODE_TYPES.MemberExpression ? callee.object : callee,
@@ -835,7 +835,7 @@ function getOppositeTestKeyword(test) {
835
835
  return TestCaseName.test;
836
836
  }
837
837
  const consistentTestIt = createEslintRule({
838
- name: RULE_NAME$S,
838
+ name: RULE_NAME$T,
839
839
  meta: {
840
840
  type: "suggestion",
841
841
  fixable: "code",
@@ -933,7 +933,7 @@ const consistentTestIt = createEslintRule({
933
933
  }
934
934
  });
935
935
 
936
- const RULE_NAME$R = "prefer-to-be";
936
+ const RULE_NAME$S = "prefer-to-be";
937
937
  const isNullLiteral = (node) => node.type === utils.AST_NODE_TYPES.Literal && node.value === null;
938
938
  const isNullEqualityMatcher = (expectFnCall) => isNullLiteral(getFirstMatcherArg(expectFnCall));
939
939
  const isFirstArgumentIdentifier = (expectFnCall, name) => isIdentifier(getFirstMatcherArg(expectFnCall), name);
@@ -969,7 +969,7 @@ const reportPreferToBe = (context, whatToBe, expectFnCall, func, modifierNode) =
969
969
  });
970
970
  };
971
971
  const preferToBe = createEslintRule({
972
- name: RULE_NAME$R,
972
+ name: RULE_NAME$S,
973
973
  meta: {
974
974
  type: "suggestion",
975
975
  docs: {
@@ -1021,9 +1021,9 @@ const preferToBe = createEslintRule({
1021
1021
  }
1022
1022
  });
1023
1023
 
1024
- const RULE_NAME$Q = "no-hooks";
1024
+ const RULE_NAME$R = "no-hooks";
1025
1025
  const noHooks = createEslintRule({
1026
- name: RULE_NAME$Q,
1026
+ name: RULE_NAME$R,
1027
1027
  meta: {
1028
1028
  type: "suggestion",
1029
1029
  docs: {
@@ -1062,9 +1062,9 @@ const noHooks = createEslintRule({
1062
1062
  }
1063
1063
  });
1064
1064
 
1065
- const RULE_NAME$P = "no-restricted-vi-methods";
1065
+ const RULE_NAME$Q = "no-restricted-vi-methods";
1066
1066
  const noRestrictedViMethods = createEslintRule({
1067
- name: RULE_NAME$P,
1067
+ name: RULE_NAME$Q,
1068
1068
  meta: {
1069
1069
  type: "suggestion",
1070
1070
  docs: {
@@ -1104,11 +1104,11 @@ const noRestrictedViMethods = createEslintRule({
1104
1104
  }
1105
1105
  });
1106
1106
 
1107
- const RULE_NAME$O = "consistent-test-filename";
1107
+ const RULE_NAME$P = "consistent-test-filename";
1108
1108
  const defaultPattern = /.*\.test\.[tj]sx?$/;
1109
1109
  const defaultTestsPattern = /.*\.(test|spec)\.[tj]sx?$/;
1110
1110
  const consistentTestFilename = createEslintRule({
1111
- name: RULE_NAME$O,
1111
+ name: RULE_NAME$P,
1112
1112
  meta: {
1113
1113
  type: "problem",
1114
1114
  docs: {
@@ -1163,9 +1163,9 @@ const consistentTestFilename = createEslintRule({
1163
1163
  }
1164
1164
  });
1165
1165
 
1166
- const RULE_NAME$N = "max-expects";
1166
+ const RULE_NAME$O = "max-expects";
1167
1167
  const maxExpect = createEslintRule({
1168
- name: RULE_NAME$N,
1168
+ name: RULE_NAME$O,
1169
1169
  meta: {
1170
1170
  docs: {
1171
1171
  requiresTypeChecking: false,
@@ -1221,9 +1221,9 @@ const maxExpect = createEslintRule({
1221
1221
  }
1222
1222
  });
1223
1223
 
1224
- const RULE_NAME$M = "no-alias-methods";
1224
+ const RULE_NAME$N = "no-alias-methods";
1225
1225
  const noAliasMethod = createEslintRule({
1226
- name: RULE_NAME$M,
1226
+ name: RULE_NAME$N,
1227
1227
  meta: {
1228
1228
  docs: {
1229
1229
  description: "disallow alias methods",
@@ -1273,12 +1273,12 @@ const noAliasMethod = createEslintRule({
1273
1273
  }
1274
1274
  });
1275
1275
 
1276
- const RULE_NAME$L = "no-commented-out-tests";
1276
+ const RULE_NAME$M = "no-commented-out-tests";
1277
1277
  function hasTests(node) {
1278
1278
  return /^\s*[xf]?(test|it|describe)(\.\w+|\[['"]\w+['"]\])?\s*\(/mu.test(node.value);
1279
1279
  }
1280
1280
  const noCommentedOutTests = createEslintRule({
1281
- name: RULE_NAME$L,
1281
+ name: RULE_NAME$M,
1282
1282
  meta: {
1283
1283
  docs: {
1284
1284
  description: "disallow commented out tests",
@@ -1308,10 +1308,10 @@ const noCommentedOutTests = createEslintRule({
1308
1308
  }
1309
1309
  });
1310
1310
 
1311
- const RULE_NAME$K = "no-conditional-expect";
1311
+ const RULE_NAME$L = "no-conditional-expect";
1312
1312
  const isCatchCall = (node) => node.callee.type === utils.AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.callee.property, "catch");
1313
1313
  const noConditionalExpect = createEslintRule({
1314
- name: RULE_NAME$K,
1314
+ name: RULE_NAME$L,
1315
1315
  meta: {
1316
1316
  type: "problem",
1317
1317
  docs: {
@@ -1377,9 +1377,9 @@ const noConditionalExpect = createEslintRule({
1377
1377
  }
1378
1378
  });
1379
1379
 
1380
- const RULE_NAME$J = "no-import-node-test";
1380
+ const RULE_NAME$K = "no-import-node-test";
1381
1381
  const noImportNodeTest = createEslintRule({
1382
- name: RULE_NAME$J,
1382
+ name: RULE_NAME$K,
1383
1383
  meta: {
1384
1384
  docs: {
1385
1385
  description: "disallow importing `node:test`",
@@ -1411,9 +1411,9 @@ const noImportNodeTest = createEslintRule({
1411
1411
  }
1412
1412
  });
1413
1413
 
1414
- const RULE_NAME$I = "no-conditional-in-test";
1414
+ const RULE_NAME$J = "no-conditional-in-test";
1415
1415
  const noConditionalInTest = createEslintRule({
1416
- name: RULE_NAME$I,
1416
+ name: RULE_NAME$J,
1417
1417
  meta: {
1418
1418
  docs: {
1419
1419
  description: "disallow conditional tests",
@@ -1441,9 +1441,9 @@ const noConditionalInTest = createEslintRule({
1441
1441
  }
1442
1442
  });
1443
1443
 
1444
- const RULE_NAME$H = "no-disabled-tests";
1444
+ const RULE_NAME$I = "no-disabled-tests";
1445
1445
  const noDisabledTests = createEslintRule({
1446
- name: RULE_NAME$H,
1446
+ name: RULE_NAME$I,
1447
1447
  meta: {
1448
1448
  type: "suggestion",
1449
1449
  docs: {
@@ -1512,7 +1512,7 @@ const noDisabledTests = createEslintRule({
1512
1512
  }
1513
1513
  });
1514
1514
 
1515
- const RULE_NAME$G = "no-done-callback";
1515
+ const RULE_NAME$H = "no-done-callback";
1516
1516
  const findCallbackArg = (node, isVitestEach, context) => {
1517
1517
  if (isVitestEach)
1518
1518
  return node.arguments[1];
@@ -1524,7 +1524,7 @@ const findCallbackArg = (node, isVitestEach, context) => {
1524
1524
  return null;
1525
1525
  };
1526
1526
  const noDoneCallback = createEslintRule({
1527
- name: RULE_NAME$G,
1527
+ name: RULE_NAME$H,
1528
1528
  meta: {
1529
1529
  type: "suggestion",
1530
1530
  docs: {
@@ -1624,9 +1624,9 @@ const noDoneCallback = createEslintRule({
1624
1624
  }
1625
1625
  });
1626
1626
 
1627
- const RULE_NAME$F = "no-duplicate-hooks";
1627
+ const RULE_NAME$G = "no-duplicate-hooks";
1628
1628
  const noDuplicateHooks = createEslintRule({
1629
- name: RULE_NAME$F,
1629
+ name: RULE_NAME$G,
1630
1630
  meta: {
1631
1631
  docs: {
1632
1632
  recommended: false,
@@ -1669,7 +1669,7 @@ const noDuplicateHooks = createEslintRule({
1669
1669
  }
1670
1670
  });
1671
1671
 
1672
- const RULE_NAME$E = "no-large-snapshots";
1672
+ const RULE_NAME$F = "no-large-snapshots";
1673
1673
  const reportOnViolation = (context, node, { maxSize: lineLimit = 50, allowedSnapshots = {} }) => {
1674
1674
  const startLine = node.loc.start.line;
1675
1675
  const endLine = node.loc.end.line;
@@ -1702,7 +1702,7 @@ const reportOnViolation = (context, node, { maxSize: lineLimit = 50, allowedSnap
1702
1702
  }
1703
1703
  };
1704
1704
  const noLargeSnapshots = createEslintRule({
1705
- name: RULE_NAME$E,
1705
+ name: RULE_NAME$F,
1706
1706
  meta: {
1707
1707
  docs: {
1708
1708
  description: "disallow large snapshots",
@@ -1760,9 +1760,9 @@ const noLargeSnapshots = createEslintRule({
1760
1760
  }
1761
1761
  });
1762
1762
 
1763
- const RULE_NAME$D = "no-interpolation-in-snapshots";
1763
+ const RULE_NAME$E = "no-interpolation-in-snapshots";
1764
1764
  const nonInterpolationInSnapShots = createEslintRule({
1765
- name: RULE_NAME$D,
1765
+ name: RULE_NAME$E,
1766
1766
  meta: {
1767
1767
  type: "problem",
1768
1768
  docs: {
@@ -1803,9 +1803,9 @@ const nonInterpolationInSnapShots = createEslintRule({
1803
1803
  const mocksDirName = "__mocks__";
1804
1804
  const isMockPath = (path$1) => path$1.split(path.posix.sep).includes(mocksDirName);
1805
1805
  const isMockImportLiteral = (expression) => isStringNode(expression) && isMockPath(getStringValue(expression));
1806
- const RULE_NAME$C = "no-mocks-import";
1806
+ const RULE_NAME$D = "no-mocks-import";
1807
1807
  const noMocksImport = createEslintRule({
1808
- name: RULE_NAME$C,
1808
+ name: RULE_NAME$D,
1809
1809
  meta: {
1810
1810
  type: "problem",
1811
1811
  docs: {
@@ -1833,14 +1833,14 @@ const noMocksImport = createEslintRule({
1833
1833
  }
1834
1834
  });
1835
1835
 
1836
- const RULE_NAME$B = "no-restricted-matchers";
1836
+ const RULE_NAME$C = "no-restricted-matchers";
1837
1837
  const isChainRestricted = (chain, restriction) => {
1838
1838
  if (ModifierName.hasOwnProperty(restriction) || restriction.endsWith(".not"))
1839
1839
  return chain.startsWith(restriction);
1840
1840
  return chain === restriction;
1841
1841
  };
1842
1842
  const noRestrictedMatchers = createEslintRule({
1843
- name: RULE_NAME$B,
1843
+ name: RULE_NAME$C,
1844
1844
  meta: {
1845
1845
  docs: {
1846
1846
  description: "disallow the use of certain matchers",
@@ -1886,7 +1886,7 @@ const noRestrictedMatchers = createEslintRule({
1886
1886
  }
1887
1887
  });
1888
1888
 
1889
- const RULE_NAME$A = "no-standalone-expect";
1889
+ const RULE_NAME$B = "no-standalone-expect";
1890
1890
  const getBlockType = (statement, context) => {
1891
1891
  const func = statement.parent;
1892
1892
  if (!func)
@@ -1903,7 +1903,7 @@ const getBlockType = (statement, context) => {
1903
1903
  return null;
1904
1904
  };
1905
1905
  const noStandaloneExpect = createEslintRule({
1906
- name: RULE_NAME$A,
1906
+ name: RULE_NAME$B,
1907
1907
  meta: {
1908
1908
  docs: {
1909
1909
  description: "disallow using `expect` outside of `it` or `test` blocks",
@@ -1976,9 +1976,9 @@ const noStandaloneExpect = createEslintRule({
1976
1976
  }
1977
1977
  });
1978
1978
 
1979
- const RULE_NAME$z = "no-test-prefixes";
1979
+ const RULE_NAME$A = "no-test-prefixes";
1980
1980
  const noTestPrefixes = createEslintRule({
1981
- name: RULE_NAME$z,
1981
+ name: RULE_NAME$A,
1982
1982
  meta: {
1983
1983
  docs: {
1984
1984
  description: "disallow using `test` as a prefix",
@@ -2017,7 +2017,7 @@ const noTestPrefixes = createEslintRule({
2017
2017
  }
2018
2018
  });
2019
2019
 
2020
- const RULE_NAME$y = "no-test-return-statement";
2020
+ const RULE_NAME$z = "no-test-return-statement";
2021
2021
  const getBody = (args) => {
2022
2022
  const [, secondArg] = args;
2023
2023
  if (secondArg && isFunction(secondArg) && secondArg.body.type === utils.AST_NODE_TYPES.BlockStatement)
@@ -2025,7 +2025,7 @@ const getBody = (args) => {
2025
2025
  return [];
2026
2026
  };
2027
2027
  const noTestReturnStatement = createEslintRule({
2028
- name: RULE_NAME$y,
2028
+ name: RULE_NAME$z,
2029
2029
  meta: {
2030
2030
  type: "problem",
2031
2031
  docs: {
@@ -2063,9 +2063,9 @@ const noTestReturnStatement = createEslintRule({
2063
2063
  }
2064
2064
  });
2065
2065
 
2066
- const RULE_NAME$x = "prefer-called-with";
2066
+ const RULE_NAME$y = "prefer-called-with";
2067
2067
  const preferCalledWith = createEslintRule({
2068
- name: RULE_NAME$x,
2068
+ name: RULE_NAME$y,
2069
2069
  meta: {
2070
2070
  docs: {
2071
2071
  description: "enforce using `toBeCalledWith()` or `toHaveBeenCalledWith()`",
@@ -2104,7 +2104,7 @@ const preferCalledWith = createEslintRule({
2104
2104
  }
2105
2105
  });
2106
2106
 
2107
- const RULE_NAME$w = "valid-title";
2107
+ const RULE_NAME$x = "valid-title";
2108
2108
  const trimFXPrefix = (word) => ["f", "x"].includes(word.charAt(0)) ? word.substring(1) : word;
2109
2109
  const quoteStringValue = (node) => node.type === utils.AST_NODE_TYPES.TemplateLiteral ? `\`${node.quasis[0].value.raw}\`` : node.raw;
2110
2110
  const MatcherAndMessageSchema = {
@@ -2154,7 +2154,7 @@ const doesBinaryExpressionContainStringNode = (binaryExp) => {
2154
2154
  return isStringNode(binaryExp.left);
2155
2155
  };
2156
2156
  const validTitle = createEslintRule({
2157
- name: RULE_NAME$w,
2157
+ name: RULE_NAME$x,
2158
2158
  meta: {
2159
2159
  docs: {
2160
2160
  description: "enforce valid titles",
@@ -2334,8 +2334,8 @@ const validTitle = createEslintRule({
2334
2334
  }
2335
2335
  });
2336
2336
 
2337
- const RULE_NAME$v = "valid-expect";
2338
- const defaultAsyncMatchers = ["toReject", "toResolve"];
2337
+ const RULE_NAME$w = "valid-expect";
2338
+ const defaultAsyncMatchers$1 = ["toReject", "toResolve"];
2339
2339
  const getPromiseCallExpressionNode = (node) => {
2340
2340
  if (node.type === utils.AST_NODE_TYPES.ArrayExpression && node.parent && node.parent.type === utils.AST_NODE_TYPES.CallExpression)
2341
2341
  node = node.parent;
@@ -2364,7 +2364,7 @@ const isAcceptableReturnNode = (node, allowReturn) => {
2364
2364
  ].includes(node.type);
2365
2365
  };
2366
2366
  const validExpect = createEslintRule({
2367
- name: RULE_NAME$v,
2367
+ name: RULE_NAME$w,
2368
2368
  meta: {
2369
2369
  docs: {
2370
2370
  description: "enforce valid `expect()` usage",
@@ -2407,11 +2407,11 @@ const validExpect = createEslintRule({
2407
2407
  },
2408
2408
  defaultOptions: [{
2409
2409
  alwaysAwait: false,
2410
- asyncMatchers: defaultAsyncMatchers,
2410
+ asyncMatchers: defaultAsyncMatchers$1,
2411
2411
  minArgs: 1,
2412
2412
  maxArgs: 1
2413
2413
  }],
2414
- create: (context, [{ alwaysAwait, asyncMatchers = defaultAsyncMatchers, minArgs = 1, maxArgs = 1 }]) => {
2414
+ create: (context, [{ alwaysAwait, asyncMatchers = defaultAsyncMatchers$1, minArgs = 1, maxArgs = 1 }]) => {
2415
2415
  const arrayExceptions = /* @__PURE__ */ new Set();
2416
2416
  const pushPromiseArrayException = (loc) => arrayExceptions.add(promiseArrayExceptionKey(loc));
2417
2417
  const promiseArrayExceptionExists = (loc) => arrayExceptions.has(promiseArrayExceptionKey(loc));
@@ -2538,9 +2538,9 @@ const isBooleanEqualityMatcher = (expectFnCall) => {
2538
2538
  const isInstanceOfBinaryExpression = (node, className) => node.type === utils.AST_NODE_TYPES.BinaryExpression && node.operator === "instanceof" && isSupportedAccessor(node.right, className);
2539
2539
  const hasOnlyOneArgument = (call) => call.arguments.length === 1;
2540
2540
 
2541
- const RULE_NAME$u = "prefer-to-be-object";
2541
+ const RULE_NAME$v = "prefer-to-be-object";
2542
2542
  const preferToBeObject = createEslintRule({
2543
- name: RULE_NAME$u,
2543
+ name: RULE_NAME$v,
2544
2544
  meta: {
2545
2545
  type: "suggestion",
2546
2546
  docs: {
@@ -2613,10 +2613,10 @@ const preferToBeObject = createEslintRule({
2613
2613
  }
2614
2614
  });
2615
2615
 
2616
- const RULE_NAME$t = "prefer-to-be-truthy";
2616
+ const RULE_NAME$u = "prefer-to-be-truthy";
2617
2617
  const isTrueLiteral = (node) => node.type === utils.AST_NODE_TYPES.Literal && node.value === true;
2618
2618
  const preferToBeTruthy = createEslintRule({
2619
- name: RULE_NAME$t,
2619
+ name: RULE_NAME$u,
2620
2620
  meta: {
2621
2621
  type: "suggestion",
2622
2622
  docs: {
@@ -2651,10 +2651,10 @@ const preferToBeTruthy = createEslintRule({
2651
2651
  }
2652
2652
  });
2653
2653
 
2654
- const RULE_NAME$s = "prefer-to-be-falsy";
2654
+ const RULE_NAME$t = "prefer-to-be-falsy";
2655
2655
  const isFalseLiteral = (node) => node.type === utils.AST_NODE_TYPES.Literal && node.value === false;
2656
2656
  const preferToBeFalsy = createEslintRule({
2657
- name: RULE_NAME$s,
2657
+ name: RULE_NAME$t,
2658
2658
  meta: {
2659
2659
  type: "suggestion",
2660
2660
  docs: {
@@ -2689,9 +2689,9 @@ const preferToBeFalsy = createEslintRule({
2689
2689
  }
2690
2690
  });
2691
2691
 
2692
- const RULE_NAME$r = "prefer-to-have-length";
2692
+ const RULE_NAME$s = "prefer-to-have-length";
2693
2693
  const preferToHaveLength = createEslintRule({
2694
- name: RULE_NAME$r,
2694
+ name: RULE_NAME$s,
2695
2695
  meta: {
2696
2696
  type: "suggestion",
2697
2697
  docs: {
@@ -2739,9 +2739,9 @@ const preferToHaveLength = createEslintRule({
2739
2739
  }
2740
2740
  });
2741
2741
 
2742
- const RULE_NAME$q = "prefer-equality-matcher";
2742
+ const RULE_NAME$r = "prefer-equality-matcher";
2743
2743
  const preferEqualityMatcher = createEslintRule({
2744
- name: RULE_NAME$q,
2744
+ name: RULE_NAME$r,
2745
2745
  meta: {
2746
2746
  type: "suggestion",
2747
2747
  docs: {
@@ -2813,9 +2813,9 @@ const preferEqualityMatcher = createEslintRule({
2813
2813
  }
2814
2814
  });
2815
2815
 
2816
- const RULE_NAME$p = "prefer-strict-equal";
2816
+ const RULE_NAME$q = "prefer-strict-equal";
2817
2817
  const preferStrictEqual = createEslintRule({
2818
- name: RULE_NAME$p,
2818
+ name: RULE_NAME$q,
2819
2819
  meta: {
2820
2820
  type: "suggestion",
2821
2821
  docs: {
@@ -2856,9 +2856,9 @@ const preferStrictEqual = createEslintRule({
2856
2856
  }
2857
2857
  });
2858
2858
 
2859
- const RULE_NAME$o = "prefer-expect-resolves";
2859
+ const RULE_NAME$p = "prefer-expect-resolves";
2860
2860
  const preferExpectResolves = createEslintRule({
2861
- name: RULE_NAME$o,
2861
+ name: RULE_NAME$p,
2862
2862
  meta: {
2863
2863
  type: "suggestion",
2864
2864
  docs: {
@@ -2901,9 +2901,9 @@ const preferExpectResolves = createEslintRule({
2901
2901
  })
2902
2902
  });
2903
2903
 
2904
- const RULE_NAME$n = "prefer-each";
2904
+ const RULE_NAME$o = "prefer-each";
2905
2905
  const preferEach = createEslintRule({
2906
- name: RULE_NAME$n,
2906
+ name: RULE_NAME$o,
2907
2907
  meta: {
2908
2908
  type: "suggestion",
2909
2909
  docs: {
@@ -2962,9 +2962,9 @@ const preferEach = createEslintRule({
2962
2962
  }
2963
2963
  });
2964
2964
 
2965
- const RULE_NAME$m = "prefer-hooks-on-top";
2965
+ const RULE_NAME$n = "prefer-hooks-on-top";
2966
2966
  const preferHooksOnTop = createEslintRule({
2967
- name: RULE_NAME$m,
2967
+ name: RULE_NAME$n,
2968
2968
  meta: {
2969
2969
  type: "suggestion",
2970
2970
  docs: {
@@ -2998,10 +2998,10 @@ const preferHooksOnTop = createEslintRule({
2998
2998
  }
2999
2999
  });
3000
3000
 
3001
- const RULE_NAME$l = "prefer-hooks-in-order";
3001
+ const RULE_NAME$m = "prefer-hooks-in-order";
3002
3002
  const HooksOrder = ["beforeAll", "beforeEach", "afterEach", "afterAll"];
3003
3003
  const preferHooksInOrder = createEslintRule({
3004
- name: RULE_NAME$l,
3004
+ name: RULE_NAME$m,
3005
3005
  meta: {
3006
3006
  type: "suggestion",
3007
3007
  docs: {
@@ -3056,7 +3056,7 @@ const preferHooksInOrder = createEslintRule({
3056
3056
  }
3057
3057
  });
3058
3058
 
3059
- const RULE_NAME$k = "prefer-mock-promise-shorthand";
3059
+ const RULE_NAME$l = "prefer-mock-promise-shorthand";
3060
3060
  const withOnce = (name, addOnce) => {
3061
3061
  return `${name}${addOnce ? "Once" : ""}`;
3062
3062
  };
@@ -3068,7 +3068,7 @@ const findSingleReturnArgumentNode = (fnNode) => {
3068
3068
  return null;
3069
3069
  };
3070
3070
  const preferMockPromiseShorthand = createEslintRule({
3071
- name: RULE_NAME$k,
3071
+ name: RULE_NAME$l,
3072
3072
  meta: {
3073
3073
  type: "suggestion",
3074
3074
  docs: {
@@ -3170,10 +3170,10 @@ const areTokensOnSameLine = (left, right) => left.loc.end.line === right.loc.sta
3170
3170
  const isTypeCastExpression = (node) => node.type === utils.AST_NODE_TYPES.TSAsExpression || node.type === utils.AST_NODE_TYPES.TSTypeAssertion;
3171
3171
  const followTypeAssertionChain = (expression) => isTypeCastExpression(expression) ? followTypeAssertionChain(expression.expression) : expression;
3172
3172
 
3173
- const RULE_NAME$j = "prefer-vi-mocked";
3173
+ const RULE_NAME$k = "prefer-vi-mocked";
3174
3174
  const mockTypes = ["Mock", "MockedFunction", "MockedClass", "MockedObject"];
3175
3175
  const preferViMocked = createEslintRule({
3176
- name: RULE_NAME$j,
3176
+ name: RULE_NAME$k,
3177
3177
  meta: {
3178
3178
  type: "suggestion",
3179
3179
  docs: {
@@ -3222,7 +3222,7 @@ const preferViMocked = createEslintRule({
3222
3222
  }
3223
3223
  });
3224
3224
 
3225
- const RULE_NAME$i = "prefer-snapshot-hint";
3225
+ const RULE_NAME$j = "prefer-snapshot-hint";
3226
3226
  const snapshotMatchers = ["toMatchSnapshot", "toThrowErrorMatchingSnapshot"];
3227
3227
  const snapshotMatcherNames = snapshotMatchers;
3228
3228
  const isSnapshotMatcherWithoutHint = (expectFnCall) => {
@@ -3236,7 +3236,7 @@ const isSnapshotMatcherWithoutHint = (expectFnCall) => {
3236
3236
  return !isStringNode(arg);
3237
3237
  };
3238
3238
  const preferSnapshotHint = createEslintRule({
3239
- name: RULE_NAME$i,
3239
+ name: RULE_NAME$j,
3240
3240
  meta: {
3241
3241
  type: "suggestion",
3242
3242
  docs: {
@@ -3314,7 +3314,7 @@ const preferSnapshotHint = createEslintRule({
3314
3314
  }
3315
3315
  });
3316
3316
 
3317
- const RULE_NAME$h = "valid-describe-callback";
3317
+ const RULE_NAME$i = "valid-describe-callback";
3318
3318
  const paramsLocation = (params) => {
3319
3319
  const [first] = params;
3320
3320
  const last = params[params.length - 1];
@@ -3324,7 +3324,7 @@ const paramsLocation = (params) => {
3324
3324
  };
3325
3325
  };
3326
3326
  const validDescribeCallback = createEslintRule({
3327
- name: RULE_NAME$h,
3327
+ name: RULE_NAME$i,
3328
3328
  meta: {
3329
3329
  type: "problem",
3330
3330
  docs: {
@@ -3396,9 +3396,9 @@ const validDescribeCallback = createEslintRule({
3396
3396
  }
3397
3397
  });
3398
3398
 
3399
- const RULE_NAME$g = "require-top-level-describe";
3399
+ const RULE_NAME$h = "require-top-level-describe";
3400
3400
  const requireTopLevelDescribe = createEslintRule({
3401
- name: RULE_NAME$g,
3401
+ name: RULE_NAME$h,
3402
3402
  meta: {
3403
3403
  docs: {
3404
3404
  description: "enforce that all tests are in a top-level describe",
@@ -3467,9 +3467,9 @@ const requireTopLevelDescribe = createEslintRule({
3467
3467
  }
3468
3468
  });
3469
3469
 
3470
- const RULE_NAME$f = "require-to-throw-message";
3470
+ const RULE_NAME$g = "require-to-throw-message";
3471
3471
  const requireToThrowMessage = createEslintRule({
3472
- name: RULE_NAME$f,
3472
+ name: RULE_NAME$g,
3473
3473
  meta: {
3474
3474
  type: "suggestion",
3475
3475
  docs: {
@@ -3502,7 +3502,7 @@ const requireToThrowMessage = createEslintRule({
3502
3502
  }
3503
3503
  });
3504
3504
 
3505
- const RULE_NAME$e = "require-hook";
3505
+ const RULE_NAME$f = "require-hook";
3506
3506
  const isVitestFnCall = (node, context) => {
3507
3507
  if (parseVitestFnCall(node, context))
3508
3508
  return true;
@@ -3529,7 +3529,7 @@ const shouldBeInHook = (node, context, allowedFunctionCalls = []) => {
3529
3529
  }
3530
3530
  };
3531
3531
  const requireHook = createEslintRule({
3532
- name: RULE_NAME$e,
3532
+ name: RULE_NAME$f,
3533
3533
  meta: {
3534
3534
  docs: {
3535
3535
  description: "require setup and teardown to be within a hook",
@@ -3585,9 +3585,9 @@ const requireHook = createEslintRule({
3585
3585
  }
3586
3586
  });
3587
3587
 
3588
- const RULE_NAME$d = "require-local-test-context-for-concurrent-snapshots";
3588
+ const RULE_NAME$e = "require-local-test-context-for-concurrent-snapshots";
3589
3589
  const requireLocalTestContextForConcurrentSnapshots = createEslintRule({
3590
- name: RULE_NAME$d,
3590
+ name: RULE_NAME$e,
3591
3591
  meta: {
3592
3592
  docs: {
3593
3593
  description: "require local Test Context for concurrent snapshot tests",
@@ -3636,7 +3636,7 @@ const requireLocalTestContextForConcurrentSnapshots = createEslintRule({
3636
3636
  }
3637
3637
  });
3638
3638
 
3639
- const RULE_NAME$c = "prefer-todo";
3639
+ const RULE_NAME$d = "prefer-todo";
3640
3640
  const isTargetedTestCase = (vitestFnCall) => {
3641
3641
  if (vitestFnCall.members.some((s) => getAccessorValue(s) !== "skip"))
3642
3642
  return false;
@@ -3655,7 +3655,7 @@ function createTodoFixer(vitestFnCall, fixer) {
3655
3655
  return fixer.replaceText(vitestFnCall.head.node, `${vitestFnCall.head.local}.todo`);
3656
3656
  }
3657
3657
  const preferTodo = createEslintRule({
3658
- name: RULE_NAME$c,
3658
+ name: RULE_NAME$d,
3659
3659
  meta: {
3660
3660
  type: "layout",
3661
3661
  docs: {
@@ -3699,7 +3699,7 @@ const preferTodo = createEslintRule({
3699
3699
  }
3700
3700
  });
3701
3701
 
3702
- const RULE_NAME$b = "prefer-spy-on";
3702
+ const RULE_NAME$c = "prefer-spy-on";
3703
3703
  const findNodeObject = (node) => {
3704
3704
  if ("object" in node)
3705
3705
  return node.object;
@@ -3727,7 +3727,7 @@ const getAutoFixMockImplementation = (vitestFnCall, context) => {
3727
3727
  return argSource ? `.mockImplementation(${argSource})` : ".mockImplementation()";
3728
3728
  };
3729
3729
  const preferSpyOn = createEslintRule({
3730
- name: RULE_NAME$b,
3730
+ name: RULE_NAME$c,
3731
3731
  meta: {
3732
3732
  type: "suggestion",
3733
3733
  docs: {
@@ -3774,7 +3774,7 @@ const preferSpyOn = createEslintRule({
3774
3774
  }
3775
3775
  });
3776
3776
 
3777
- const RULE_NAME$a = "prefer-comparison-matcher";
3777
+ const RULE_NAME$b = "prefer-comparison-matcher";
3778
3778
  const isString = (node) => {
3779
3779
  return isStringNode(node) || node?.type === utils.AST_NODE_TYPES.TemplateLiteral;
3780
3780
  };
@@ -3809,7 +3809,7 @@ const determineMatcher = (operator, negated) => {
3809
3809
  return null;
3810
3810
  };
3811
3811
  const preferComparisonMatcher = createEslintRule({
3812
- name: RULE_NAME$a,
3812
+ name: RULE_NAME$b,
3813
3813
  meta: {
3814
3814
  type: "suggestion",
3815
3815
  docs: {
@@ -3873,10 +3873,10 @@ const preferComparisonMatcher = createEslintRule({
3873
3873
  }
3874
3874
  });
3875
3875
 
3876
- const RULE_NAME$9 = "prefer-to-contain";
3876
+ const RULE_NAME$a = "prefer-to-contain";
3877
3877
  const isFixableIncludesCallExpression = (node) => node.type === utils.AST_NODE_TYPES.CallExpression && node.callee.type === utils.AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.callee.property, "includes") && hasOnlyOneArgument(node) && node.arguments[0].type !== utils.AST_NODE_TYPES.SpreadElement;
3878
3878
  const preferToContain = createEslintRule({
3879
- name: RULE_NAME$9,
3879
+ name: RULE_NAME$a,
3880
3880
  meta: {
3881
3881
  docs: {
3882
3882
  description: "enforce using toContain()",
@@ -3935,7 +3935,7 @@ const preferToContain = createEslintRule({
3935
3935
  }
3936
3936
  });
3937
3937
 
3938
- const RULE_NAME$8 = "prefer-expect-assertions";
3938
+ const RULE_NAME$9 = "prefer-expect-assertions";
3939
3939
  const isFirstStatement = (node) => {
3940
3940
  let parent = node;
3941
3941
  while (parent) {
@@ -4308,7 +4308,7 @@ const createPaddingRule = (name, description, configs, deprecated = false) => {
4308
4308
  });
4309
4309
  };
4310
4310
 
4311
- const RULE_NAME$7 = "padding-around-after-all-blocks";
4311
+ const RULE_NAME$8 = "padding-around-after-all-blocks";
4312
4312
  const config$6 = [
4313
4313
  {
4314
4314
  paddingType: PaddingType.Always,
@@ -4321,9 +4321,9 @@ const config$6 = [
4321
4321
  nextStatementType: StatementType.Any
4322
4322
  }
4323
4323
  ];
4324
- const paddingAroundAfterAllBlocks = createPaddingRule(RULE_NAME$7, "Enforce padding around `afterAll` blocks", config$6);
4324
+ const paddingAroundAfterAllBlocks = createPaddingRule(RULE_NAME$8, "Enforce padding around `afterAll` blocks", config$6);
4325
4325
 
4326
- const RULE_NAME$6 = "padding-around-after-each-blocks";
4326
+ const RULE_NAME$7 = "padding-around-after-each-blocks";
4327
4327
  const config$5 = [
4328
4328
  {
4329
4329
  paddingType: PaddingType.Always,
@@ -4336,9 +4336,9 @@ const config$5 = [
4336
4336
  nextStatementType: StatementType.Any
4337
4337
  }
4338
4338
  ];
4339
- const paddingAroundAfterEachBlocks = createPaddingRule(RULE_NAME$6, "Enforce padding around `afterEach` blocks", config$5);
4339
+ const paddingAroundAfterEachBlocks = createPaddingRule(RULE_NAME$7, "Enforce padding around `afterEach` blocks", config$5);
4340
4340
 
4341
- const RULE_NAME$5 = "padding-around-before-all-blocks";
4341
+ const RULE_NAME$6 = "padding-around-before-all-blocks";
4342
4342
  const config$4 = [
4343
4343
  {
4344
4344
  paddingType: PaddingType.Always,
@@ -4351,9 +4351,9 @@ const config$4 = [
4351
4351
  nextStatementType: StatementType.Any
4352
4352
  }
4353
4353
  ];
4354
- const paddingAroundBeforeAllBlocks = createPaddingRule(RULE_NAME$5, "Enforce padding around `beforeAll` blocks", config$4);
4354
+ const paddingAroundBeforeAllBlocks = createPaddingRule(RULE_NAME$6, "Enforce padding around `beforeAll` blocks", config$4);
4355
4355
 
4356
- const RULE_NAME$4 = "padding-around-before-each-blocks";
4356
+ const RULE_NAME$5 = "padding-around-before-each-blocks";
4357
4357
  const config$3 = [
4358
4358
  {
4359
4359
  paddingType: PaddingType.Always,
@@ -4367,12 +4367,12 @@ const config$3 = [
4367
4367
  }
4368
4368
  ];
4369
4369
  const paddingAroundBeforeEachBlocks = createPaddingRule(
4370
- RULE_NAME$4,
4370
+ RULE_NAME$5,
4371
4371
  "Enforce padding around `beforeEach` blocks",
4372
4372
  config$3
4373
4373
  );
4374
4374
 
4375
- const RULE_NAME$3 = "padding-around-describe-blocks";
4375
+ const RULE_NAME$4 = "padding-around-describe-blocks";
4376
4376
  const config$2 = [
4377
4377
  {
4378
4378
  paddingType: PaddingType.Always,
@@ -4394,12 +4394,12 @@ const config$2 = [
4394
4394
  }
4395
4395
  ];
4396
4396
  const paddingAroundDescribeBlocks = createPaddingRule(
4397
- RULE_NAME$3,
4397
+ RULE_NAME$4,
4398
4398
  "Enforce padding around `describe` blocks",
4399
4399
  config$2
4400
4400
  );
4401
4401
 
4402
- const RULE_NAME$2 = "padding-around-expect-groups";
4402
+ const RULE_NAME$3 = "padding-around-expect-groups";
4403
4403
  const config$1 = [
4404
4404
  {
4405
4405
  paddingType: PaddingType.Always,
@@ -4418,12 +4418,12 @@ const config$1 = [
4418
4418
  }
4419
4419
  ];
4420
4420
  const paddingAroundExpectGroups = createPaddingRule(
4421
- RULE_NAME$2,
4421
+ RULE_NAME$3,
4422
4422
  "Enforce padding around `expect` groups",
4423
4423
  config$1
4424
4424
  );
4425
4425
 
4426
- const RULE_NAME$1 = "padding-around-test-blocks";
4426
+ const RULE_NAME$2 = "padding-around-test-blocks";
4427
4427
  const config = [
4428
4428
  {
4429
4429
  paddingType: PaddingType.Always,
@@ -4449,14 +4449,14 @@ const config = [
4449
4449
  }
4450
4450
  ];
4451
4451
  const paddingAroundTestBlocks = createPaddingRule(
4452
- RULE_NAME$1,
4452
+ RULE_NAME$2,
4453
4453
  "Enforce padding around afterAll blocks",
4454
4454
  config
4455
4455
  );
4456
4456
 
4457
- const RULE_NAME = "padding-around-all";
4457
+ const RULE_NAME$1 = "padding-around-all";
4458
4458
  const paddingAroundAll = createPaddingRule(
4459
- RULE_NAME,
4459
+ RULE_NAME$1,
4460
4460
  "Enforce padding around vitest functions",
4461
4461
  [
4462
4462
  ...config$6,
@@ -4469,6 +4469,256 @@ const paddingAroundAll = createPaddingRule(
4469
4469
  ]
4470
4470
  );
4471
4471
 
4472
+ const RULE_NAME = "valid-expect-in-promise";
4473
+ const defaultAsyncMatchers = ["toRejectWith", "toResolveWith"];
4474
+ const isPromiseChainCall = (node) => {
4475
+ if (node.type === utils.AST_NODE_TYPES.CallExpression && node.callee.type === utils.AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.callee.property)) {
4476
+ if (node.arguments.length === 0) {
4477
+ return false;
4478
+ }
4479
+ switch (getAccessorValue(node.callee.property)) {
4480
+ case "then":
4481
+ return node.arguments.length < 3;
4482
+ case "catch":
4483
+ case "finally":
4484
+ return node.arguments.length < 2;
4485
+ }
4486
+ }
4487
+ return false;
4488
+ };
4489
+ const isTestCaseCallWithCallbackArg = (node, context) => {
4490
+ const vitestCallFn = parseVitestFnCall(node, context);
4491
+ if (vitestCallFn?.type !== "test") {
4492
+ return false;
4493
+ }
4494
+ const isVitestEach = vitestCallFn.members.some(
4495
+ (s) => getAccessorValue(s) === "each"
4496
+ );
4497
+ if (isVitestEach && node.callee.type !== utils.AST_NODE_TYPES.TaggedTemplateExpression) {
4498
+ return true;
4499
+ }
4500
+ const [, callback] = node.arguments;
4501
+ const callbackArgIndex = Number(isVitestEach);
4502
+ return callback && isFunction(callback) && callback.params.length === 1 + callbackArgIndex;
4503
+ };
4504
+ const isPromiseMethodThatUsesValue = (node, identifier) => {
4505
+ const { name } = identifier;
4506
+ if (node.argument === null) {
4507
+ return false;
4508
+ }
4509
+ if (node.argument.type === utils.AST_NODE_TYPES.CallExpression && node.argument.arguments.length > 0) {
4510
+ const nodeName = getNodeName(node.argument);
4511
+ if (["Promise.all", "Promise.allSettled"].includes(nodeName)) {
4512
+ const [firstArg] = node.argument.arguments;
4513
+ if (firstArg.type === utils.AST_NODE_TYPES.ArrayExpression && firstArg.elements.some((nod) => nod && isIdentifier(nod, name))) {
4514
+ return true;
4515
+ }
4516
+ }
4517
+ if (["Promise.resolve", "Promise.reject"].includes(nodeName) && node.argument.arguments.length === 1) {
4518
+ return isIdentifier(node.argument.arguments[0], name);
4519
+ }
4520
+ }
4521
+ return isIdentifier(node.argument, name);
4522
+ };
4523
+ const isValueAwaitedInElements = (name, elements) => {
4524
+ for (const element of elements) {
4525
+ if (element?.type === utils.AST_NODE_TYPES.AwaitExpression && isIdentifier(element.argument, name)) {
4526
+ return true;
4527
+ }
4528
+ if (element?.type === utils.AST_NODE_TYPES.ArrayExpression && isValueAwaitedInElements(name, element.elements)) {
4529
+ return true;
4530
+ }
4531
+ }
4532
+ return false;
4533
+ };
4534
+ const isValueAwaitedInArguments = (name, call) => {
4535
+ let node = call;
4536
+ while (node) {
4537
+ if (node.type === utils.AST_NODE_TYPES.CallExpression) {
4538
+ if (isValueAwaitedInElements(name, node.arguments)) {
4539
+ return true;
4540
+ }
4541
+ node = node.callee;
4542
+ }
4543
+ if (node.type !== utils.AST_NODE_TYPES.MemberExpression) {
4544
+ break;
4545
+ }
4546
+ node = node.object;
4547
+ }
4548
+ return false;
4549
+ };
4550
+ const getLeftMostCallExpression = (call) => {
4551
+ let leftMostCallExpression = call;
4552
+ let node = call;
4553
+ while (node) {
4554
+ if (node.type === utils.AST_NODE_TYPES.CallExpression) {
4555
+ leftMostCallExpression = node;
4556
+ node = node.callee;
4557
+ }
4558
+ if (node.type !== utils.AST_NODE_TYPES.MemberExpression) {
4559
+ break;
4560
+ }
4561
+ node = node.object;
4562
+ }
4563
+ return leftMostCallExpression;
4564
+ };
4565
+ const isValueAwaitedOrReturned = (identifier, body, context) => {
4566
+ const { name } = identifier;
4567
+ for (const node of body) {
4568
+ if (node.range[0] <= identifier.range[0]) {
4569
+ continue;
4570
+ }
4571
+ if (node.type === utils.AST_NODE_TYPES.ReturnStatement) {
4572
+ return isPromiseMethodThatUsesValue(node, identifier);
4573
+ }
4574
+ if (node.type === utils.AST_NODE_TYPES.ExpressionStatement) {
4575
+ if (node.expression.type === utils.AST_NODE_TYPES.CallExpression) {
4576
+ if (isValueAwaitedInArguments(name, node.expression)) {
4577
+ return true;
4578
+ }
4579
+ const leftMostCall = getLeftMostCallExpression(node.expression);
4580
+ const vitestFnCall = parseVitestFnCall(node.expression, context);
4581
+ if (vitestFnCall?.type === "expect" && leftMostCall.arguments.length > 0 && isIdentifier(leftMostCall.arguments[0], name)) {
4582
+ if (vitestFnCall.members.some((m) => {
4583
+ const v = getAccessorValue(m);
4584
+ return v === ModifierName.resolves || v === ModifierName.rejects;
4585
+ })) {
4586
+ return true;
4587
+ }
4588
+ }
4589
+ }
4590
+ if (node.expression.type === utils.AST_NODE_TYPES.AwaitExpression && isPromiseMethodThatUsesValue(node.expression, identifier)) {
4591
+ return true;
4592
+ }
4593
+ if (node.expression.type === utils.AST_NODE_TYPES.AssignmentExpression) {
4594
+ if (isIdentifier(node.expression.left, name) && getNodeName(node.expression.right)?.startsWith(`${name}.`) && isPromiseChainCall(node.expression.right)) {
4595
+ continue;
4596
+ }
4597
+ break;
4598
+ }
4599
+ }
4600
+ if (node.type === utils.AST_NODE_TYPES.BlockStatement && isValueAwaitedOrReturned(identifier, node.body, context)) {
4601
+ return true;
4602
+ }
4603
+ }
4604
+ return false;
4605
+ };
4606
+ const findFirstBlockBodyUp = (node) => {
4607
+ let parent = node;
4608
+ while (parent) {
4609
+ if (parent.type === utils.AST_NODE_TYPES.BlockStatement) {
4610
+ return parent.body;
4611
+ }
4612
+ parent = parent.parent;
4613
+ }
4614
+ throw new Error(
4615
+ `Could not find BlockStatement - please file a github issue at https://github.com/vitest-dev/eslint-plugin-vitest`
4616
+ );
4617
+ };
4618
+ const isDirectlyWithinTestCaseCall = (node, context) => {
4619
+ let parent = node;
4620
+ while (parent) {
4621
+ if (isFunction(parent)) {
4622
+ parent = parent.parent;
4623
+ return parent?.type === utils.AST_NODE_TYPES.CallExpression && isTypeOfVitestFnCall(parent, context, ["test"]);
4624
+ }
4625
+ parent = parent.parent;
4626
+ }
4627
+ return false;
4628
+ };
4629
+ const isVariableAwaitedOrReturned = (variable, context) => {
4630
+ const body = findFirstBlockBodyUp(variable);
4631
+ if (!isIdentifier(variable.id)) {
4632
+ return true;
4633
+ }
4634
+ return isValueAwaitedOrReturned(variable.id, body, context);
4635
+ };
4636
+ const validExpectInPromise = createEslintRule({
4637
+ name: __filename,
4638
+ meta: {
4639
+ docs: {
4640
+ description: "Require promises that have expectations in their chain to be valid"
4641
+ },
4642
+ messages: {
4643
+ expectInFloatingPromise: "This promise should either be returned or awaited to ensure the expects in its chain are called"
4644
+ },
4645
+ type: "suggestion",
4646
+ schema: []
4647
+ },
4648
+ defaultOptions: [{
4649
+ alwaysAwait: false,
4650
+ asyncMatchers: defaultAsyncMatchers,
4651
+ minArgs: 1,
4652
+ maxArgs: 1
4653
+ }],
4654
+ create(context) {
4655
+ let inTestCaseWithDoneCallback = false;
4656
+ const chains = [];
4657
+ return {
4658
+ CallExpression(node) {
4659
+ if (isTestCaseCallWithCallbackArg(node, context)) {
4660
+ inTestCaseWithDoneCallback = true;
4661
+ return;
4662
+ }
4663
+ if (isPromiseChainCall(node)) {
4664
+ chains.unshift(false);
4665
+ return;
4666
+ }
4667
+ if (chains.length > 0 && isTypeOfVitestFnCall(node, context, ["expect"])) {
4668
+ chains[0] = true;
4669
+ }
4670
+ },
4671
+ "CallExpression:exit"(node) {
4672
+ if (inTestCaseWithDoneCallback) {
4673
+ if (isTypeOfVitestFnCall(node, context, ["test"])) {
4674
+ inTestCaseWithDoneCallback = false;
4675
+ }
4676
+ return;
4677
+ }
4678
+ if (!isPromiseChainCall(node)) {
4679
+ return;
4680
+ }
4681
+ const hasExpectCall = chains.shift();
4682
+ if (!hasExpectCall) {
4683
+ return;
4684
+ }
4685
+ const { parent } = findTopMostCallExpression(node);
4686
+ if (!parent || !isDirectlyWithinTestCaseCall(parent, context)) {
4687
+ return;
4688
+ }
4689
+ switch (parent.type) {
4690
+ case utils.AST_NODE_TYPES.VariableDeclarator: {
4691
+ if (isVariableAwaitedOrReturned(parent, context)) {
4692
+ return;
4693
+ }
4694
+ break;
4695
+ }
4696
+ case utils.AST_NODE_TYPES.AssignmentExpression: {
4697
+ if (parent.left.type === utils.AST_NODE_TYPES.Identifier && isValueAwaitedOrReturned(
4698
+ parent.left,
4699
+ findFirstBlockBodyUp(parent),
4700
+ context
4701
+ )) {
4702
+ return;
4703
+ }
4704
+ break;
4705
+ }
4706
+ case utils.AST_NODE_TYPES.ExpressionStatement:
4707
+ break;
4708
+ case utils.AST_NODE_TYPES.ReturnStatement:
4709
+ case utils.AST_NODE_TYPES.AwaitExpression:
4710
+ default:
4711
+ return;
4712
+ }
4713
+ context.report({
4714
+ messageId: "expectInFloatingPromise",
4715
+ node: parent
4716
+ });
4717
+ }
4718
+ };
4719
+ }
4720
+ });
4721
+
4472
4722
  const createConfig = (rules) => Object.keys(rules).reduce((acc, ruleName) => {
4473
4723
  return {
4474
4724
  ...acc,
@@ -4485,17 +4735,18 @@ const createConfigLegacy = (rules) => ({
4485
4735
  }, {})
4486
4736
  });
4487
4737
  const allRules = {
4738
+ [RULE_NAME$Z]: "warn",
4488
4739
  [RULE_NAME$Y]: "warn",
4489
- [RULE_NAME$X]: "warn",
4740
+ [RULE_NAME$W]: "warn",
4490
4741
  [RULE_NAME$V]: "warn",
4491
- [RULE_NAME$U]: "warn",
4492
- [RULE_NAME$S]: "warn",
4742
+ [RULE_NAME$T]: "warn",
4743
+ [RULE_NAME$R]: "warn",
4493
4744
  [RULE_NAME$Q]: "warn",
4494
4745
  [RULE_NAME$P]: "warn",
4495
4746
  [RULE_NAME$O]: "warn",
4496
4747
  [RULE_NAME$N]: "warn",
4497
- [RULE_NAME$M]: "warn",
4498
- [RULE_NAME$K]: "warn",
4748
+ [RULE_NAME$L]: "warn",
4749
+ [RULE_NAME$J]: "warn",
4499
4750
  [RULE_NAME$I]: "warn",
4500
4751
  [RULE_NAME$H]: "warn",
4501
4752
  [RULE_NAME$G]: "warn",
@@ -4507,10 +4758,10 @@ const allRules = {
4507
4758
  [RULE_NAME$A]: "warn",
4508
4759
  [RULE_NAME$z]: "warn",
4509
4760
  [RULE_NAME$y]: "warn",
4510
- [RULE_NAME$x]: "warn",
4511
- [RULE_NAME$s]: "warn",
4512
- [RULE_NAME$u]: "warn",
4513
4761
  [RULE_NAME$t]: "warn",
4762
+ [RULE_NAME$v]: "warn",
4763
+ [RULE_NAME$u]: "warn",
4764
+ [RULE_NAME$s]: "warn",
4514
4765
  [RULE_NAME$r]: "warn",
4515
4766
  [RULE_NAME$q]: "warn",
4516
4767
  [RULE_NAME$p]: "warn",
@@ -4520,34 +4771,34 @@ const allRules = {
4520
4771
  [RULE_NAME$l]: "warn",
4521
4772
  [RULE_NAME$k]: "warn",
4522
4773
  [RULE_NAME$j]: "warn",
4523
- [RULE_NAME$i]: "warn",
4774
+ [RULE_NAME$h]: "warn",
4524
4775
  [RULE_NAME$g]: "warn",
4525
4776
  [RULE_NAME$f]: "warn",
4526
- [RULE_NAME$e]: "warn",
4777
+ [RULE_NAME$d]: "warn",
4527
4778
  [RULE_NAME$c]: "warn",
4528
4779
  [RULE_NAME$b]: "warn",
4529
4780
  [RULE_NAME$a]: "warn",
4530
4781
  [RULE_NAME$9]: "warn",
4782
+ [RULE_NAME$S]: "warn",
4531
4783
  [RULE_NAME$8]: "warn",
4532
- [RULE_NAME$R]: "warn",
4533
4784
  [RULE_NAME$7]: "warn",
4785
+ [RULE_NAME$1]: "warn",
4534
4786
  [RULE_NAME$6]: "warn",
4535
- [RULE_NAME]: "warn",
4536
4787
  [RULE_NAME$5]: "warn",
4537
4788
  [RULE_NAME$4]: "warn",
4538
4789
  [RULE_NAME$3]: "warn",
4539
4790
  [RULE_NAME$2]: "warn",
4540
- [RULE_NAME$1]: "warn"
4791
+ [RULE_NAME]: "warn"
4541
4792
  };
4542
4793
  const recommended = {
4543
- [RULE_NAME$T]: "error",
4544
- [RULE_NAME$W]: "error",
4545
- [RULE_NAME$L]: "error",
4794
+ [RULE_NAME$U]: "error",
4795
+ [RULE_NAME$X]: "error",
4796
+ [RULE_NAME$M]: "error",
4797
+ [RULE_NAME$x]: "error",
4546
4798
  [RULE_NAME$w]: "error",
4547
- [RULE_NAME$v]: "error",
4548
- [RULE_NAME$h]: "error",
4549
- [RULE_NAME$d]: "error",
4550
- [RULE_NAME$J]: "error"
4799
+ [RULE_NAME$i]: "error",
4800
+ [RULE_NAME$e]: "error",
4801
+ [RULE_NAME$K]: "error"
4551
4802
  };
4552
4803
  const plugin = {
4553
4804
  meta: {
@@ -4555,67 +4806,68 @@ const plugin = {
4555
4806
  version
4556
4807
  },
4557
4808
  rules: {
4558
- [RULE_NAME$Y]: lowerCaseTitle,
4559
- [RULE_NAME$X]: maxNestedDescribe,
4560
- [RULE_NAME$W]: noIdenticalTitle,
4561
- [RULE_NAME$V]: noFocusedTests,
4562
- [RULE_NAME$U]: noConditionalTest,
4563
- [RULE_NAME$T]: expectExpect,
4564
- [RULE_NAME$S]: consistentTestIt,
4565
- [RULE_NAME$R]: preferToBe,
4566
- [RULE_NAME$Q]: noHooks,
4567
- [RULE_NAME$P]: noRestrictedViMethods,
4568
- [RULE_NAME$O]: consistentTestFilename,
4569
- [RULE_NAME$N]: maxExpect,
4570
- [RULE_NAME$M]: noAliasMethod,
4571
- [RULE_NAME$L]: noCommentedOutTests,
4572
- [RULE_NAME$K]: noConditionalExpect,
4573
- [RULE_NAME$I]: noConditionalInTest,
4574
- [RULE_NAME$H]: noDisabledTests,
4575
- [RULE_NAME$G]: noDoneCallback,
4576
- [RULE_NAME$F]: noDuplicateHooks,
4577
- [RULE_NAME$E]: noLargeSnapshots,
4578
- [RULE_NAME$D]: nonInterpolationInSnapShots,
4579
- [RULE_NAME$C]: noMocksImport,
4580
- [RULE_NAME$B]: noRestrictedMatchers,
4581
- [RULE_NAME$A]: noStandaloneExpect,
4582
- [RULE_NAME$z]: noTestPrefixes,
4583
- [RULE_NAME$y]: noTestReturnStatement,
4584
- [RULE_NAME$J]: noImportNodeTest,
4585
- [RULE_NAME$x]: preferCalledWith,
4586
- [RULE_NAME$w]: validTitle,
4587
- [RULE_NAME$v]: validExpect,
4588
- [RULE_NAME$s]: preferToBeFalsy,
4589
- [RULE_NAME$u]: preferToBeObject,
4590
- [RULE_NAME$t]: preferToBeTruthy,
4591
- [RULE_NAME$r]: preferToHaveLength,
4592
- [RULE_NAME$q]: preferEqualityMatcher,
4593
- [RULE_NAME$p]: preferStrictEqual,
4594
- [RULE_NAME$o]: preferExpectResolves,
4595
- [RULE_NAME$n]: preferEach,
4596
- [RULE_NAME$m]: preferHooksOnTop,
4597
- [RULE_NAME$l]: preferHooksInOrder,
4598
- [RULE_NAME$d]: requireLocalTestContextForConcurrentSnapshots,
4599
- [RULE_NAME$k]: preferMockPromiseShorthand,
4600
- [RULE_NAME$j]: preferViMocked,
4601
- [RULE_NAME$i]: preferSnapshotHint,
4602
- [RULE_NAME$h]: validDescribeCallback,
4603
- [RULE_NAME$g]: requireTopLevelDescribe,
4604
- [RULE_NAME$f]: requireToThrowMessage,
4605
- [RULE_NAME$e]: requireHook,
4606
- [RULE_NAME$c]: preferTodo,
4607
- [RULE_NAME$b]: preferSpyOn,
4608
- [RULE_NAME$a]: preferComparisonMatcher,
4609
- [RULE_NAME$9]: preferToContain,
4610
- [RULE_NAME$8]: preferExpectAssertions,
4611
- [RULE_NAME$7]: paddingAroundAfterAllBlocks,
4612
- [RULE_NAME$6]: paddingAroundAfterEachBlocks,
4613
- [RULE_NAME]: paddingAroundAll,
4614
- [RULE_NAME$5]: paddingAroundBeforeAllBlocks,
4615
- [RULE_NAME$4]: paddingAroundBeforeEachBlocks,
4616
- [RULE_NAME$3]: paddingAroundDescribeBlocks,
4617
- [RULE_NAME$2]: paddingAroundExpectGroups,
4618
- [RULE_NAME$1]: paddingAroundTestBlocks
4809
+ [RULE_NAME$Z]: lowerCaseTitle,
4810
+ [RULE_NAME$Y]: maxNestedDescribe,
4811
+ [RULE_NAME$X]: noIdenticalTitle,
4812
+ [RULE_NAME$W]: noFocusedTests,
4813
+ [RULE_NAME$V]: noConditionalTest,
4814
+ [RULE_NAME$U]: expectExpect,
4815
+ [RULE_NAME$T]: consistentTestIt,
4816
+ [RULE_NAME$S]: preferToBe,
4817
+ [RULE_NAME$R]: noHooks,
4818
+ [RULE_NAME$Q]: noRestrictedViMethods,
4819
+ [RULE_NAME$P]: consistentTestFilename,
4820
+ [RULE_NAME$O]: maxExpect,
4821
+ [RULE_NAME$N]: noAliasMethod,
4822
+ [RULE_NAME$M]: noCommentedOutTests,
4823
+ [RULE_NAME$L]: noConditionalExpect,
4824
+ [RULE_NAME$J]: noConditionalInTest,
4825
+ [RULE_NAME$I]: noDisabledTests,
4826
+ [RULE_NAME$H]: noDoneCallback,
4827
+ [RULE_NAME$G]: noDuplicateHooks,
4828
+ [RULE_NAME$F]: noLargeSnapshots,
4829
+ [RULE_NAME$E]: nonInterpolationInSnapShots,
4830
+ [RULE_NAME$D]: noMocksImport,
4831
+ [RULE_NAME$C]: noRestrictedMatchers,
4832
+ [RULE_NAME$B]: noStandaloneExpect,
4833
+ [RULE_NAME$A]: noTestPrefixes,
4834
+ [RULE_NAME$z]: noTestReturnStatement,
4835
+ [RULE_NAME$K]: noImportNodeTest,
4836
+ [RULE_NAME$y]: preferCalledWith,
4837
+ [RULE_NAME$x]: validTitle,
4838
+ [RULE_NAME$w]: validExpect,
4839
+ [RULE_NAME$t]: preferToBeFalsy,
4840
+ [RULE_NAME$v]: preferToBeObject,
4841
+ [RULE_NAME$u]: preferToBeTruthy,
4842
+ [RULE_NAME$s]: preferToHaveLength,
4843
+ [RULE_NAME$r]: preferEqualityMatcher,
4844
+ [RULE_NAME$q]: preferStrictEqual,
4845
+ [RULE_NAME$p]: preferExpectResolves,
4846
+ [RULE_NAME$o]: preferEach,
4847
+ [RULE_NAME$n]: preferHooksOnTop,
4848
+ [RULE_NAME$m]: preferHooksInOrder,
4849
+ [RULE_NAME$e]: requireLocalTestContextForConcurrentSnapshots,
4850
+ [RULE_NAME$l]: preferMockPromiseShorthand,
4851
+ [RULE_NAME$k]: preferViMocked,
4852
+ [RULE_NAME$j]: preferSnapshotHint,
4853
+ [RULE_NAME$i]: validDescribeCallback,
4854
+ [RULE_NAME$h]: requireTopLevelDescribe,
4855
+ [RULE_NAME$g]: requireToThrowMessage,
4856
+ [RULE_NAME$f]: requireHook,
4857
+ [RULE_NAME$d]: preferTodo,
4858
+ [RULE_NAME$c]: preferSpyOn,
4859
+ [RULE_NAME$b]: preferComparisonMatcher,
4860
+ [RULE_NAME$a]: preferToContain,
4861
+ [RULE_NAME$9]: preferExpectAssertions,
4862
+ [RULE_NAME$8]: paddingAroundAfterAllBlocks,
4863
+ [RULE_NAME$7]: paddingAroundAfterEachBlocks,
4864
+ [RULE_NAME$1]: paddingAroundAll,
4865
+ [RULE_NAME$6]: paddingAroundBeforeAllBlocks,
4866
+ [RULE_NAME$5]: paddingAroundBeforeEachBlocks,
4867
+ [RULE_NAME$4]: paddingAroundDescribeBlocks,
4868
+ [RULE_NAME$3]: paddingAroundExpectGroups,
4869
+ [RULE_NAME$2]: paddingAroundTestBlocks,
4870
+ [RULE_NAME]: validExpectInPromise
4619
4871
  },
4620
4872
  configs: {
4621
4873
  "legacy-recommended": createConfigLegacy(recommended),