Socket
Socket
Sign inDemoInstall

eslint-plugin-jest

Package Overview
Dependencies
Maintainers
11
Versions
325
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-jest - npm Package Compare versions

Comparing version 27.1.2 to 27.1.3

24

lib/index.js
"use strict";
var _fs = require("fs");
var _path = require("path");
var _globals = _interopRequireDefault(require("./globals.json"));
var snapshotProcessor = _interopRequireWildcard(require("./processors/snapshot-processor"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// copied from https://github.com/babel/babel/blob/d8da63c929f2d28c401571e2a43166678c555bc4/packages/babel-helpers/src/helpers.js#L602-L606
/* istanbul ignore next */

@@ -23,18 +15,19 @@ const interopRequireDefault = obj => obj && obj.__esModule ? obj : {

};
const importDefault = moduleName => // eslint-disable-next-line @typescript-eslint/no-require-imports
const importDefault = moduleName =>
// eslint-disable-next-line @typescript-eslint/no-require-imports
interopRequireDefault(require(moduleName)).default;
const rulesDir = (0, _path.join)(__dirname, 'rules');
const excludedFiles = ['__tests__', 'detectJestVersion', 'utils'];
const rules = (0, _fs.readdirSync)(rulesDir).map(rule => (0, _path.parse)(rule).name).filter(rule => !excludedFiles.includes(rule)).reduce((acc, curr) => ({ ...acc,
const rules = (0, _fs.readdirSync)(rulesDir).map(rule => (0, _path.parse)(rule).name).filter(rule => !excludedFiles.includes(rule)).reduce((acc, curr) => ({
...acc,
[curr]: importDefault((0, _path.join)(rulesDir, curr))
}), {});
const recommendedRules = Object.entries(rules).filter(([, rule]) => rule.meta.docs.recommended).reduce((acc, [name, rule]) => ({ ...acc,
const recommendedRules = Object.entries(rules).filter(([, rule]) => rule.meta.docs.recommended).reduce((acc, [name, rule]) => ({
...acc,
[`jest/${name}`]: rule.meta.docs.recommended
}), {});
const allRules = Object.entries(rules).filter(([, rule]) => !rule.meta.deprecated).reduce((acc, [name]) => ({ ...acc,
const allRules = Object.entries(rules).filter(([, rule]) => !rule.meta.deprecated).reduce((acc, [name]) => ({
...acc,
[`jest/${name}`]: 'error'
}), {});
const createConfig = rules => ({

@@ -47,3 +40,2 @@ plugins: ['jest'],

});
module.exports = {

@@ -50,0 +42,0 @@ configs: {

@@ -7,12 +7,10 @@ "use strict";

exports.preprocess = exports.postprocess = void 0;
// https://eslint.org/docs/developer-guide/working-with-plugins#processors-in-plugins
// https://github.com/typescript-eslint/typescript-eslint/issues/808
const preprocess = source => [source];
exports.preprocess = preprocess;
const postprocess = messages => // snapshot files should only be linted with snapshot specific rules
const postprocess = messages =>
// snapshot files should only be linted with snapshot specific rules
messages[0].filter(message => message.ruleId === 'jest/no-large-snapshots');
exports.postprocess = postprocess;

@@ -7,9 +7,5 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const buildFixer = (callee, nodeName, preferredTestKeyword) => fixer => [fixer.replaceText(callee.type === _utils.AST_NODE_TYPES.MemberExpression ? callee.object : callee, getPreferredNodeName(nodeName, preferredTestKeyword))];
var _default = (0, _utils2.createRule)({

@@ -46,3 +42,2 @@ name: __filename,

}],
create(context) {

@@ -56,7 +51,5 @@ const configObj = context.options[0] || {};

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if (!jestFnCall) {
return;
}
if (jestFnCall.type === 'describe') {

@@ -66,5 +59,3 @@ describeNestingLevel++;

}
const funcNode = node.callee.type === _utils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _utils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;
if (jestFnCall.type === 'test' && describeNestingLevel === 0 && !jestFnCall.name.endsWith(testKeyword)) {

@@ -82,3 +73,2 @@ const oppositeTestKeyword = getOppositeTestKeyword(testKeyword);

}
if (jestFnCall.type === 'test' && describeNestingLevel > 0 && !jestFnCall.name.endsWith(testKeywordWithinDescribe)) {

@@ -97,3 +87,2 @@ const oppositeTestKeyword = getOppositeTestKeyword(testKeywordWithinDescribe);

},
'CallExpression:exit'(node) {

@@ -104,10 +93,6 @@ if ((0, _utils2.isTypeOfJestFnCall)(node, context, ['describe'])) {

}
};
}
});
exports.default = _default;
function getPreferredNodeName(nodeName, preferredTestKeyword) {

@@ -117,6 +102,4 @@ if (nodeName === _utils2.TestCaseName.fit) {

}
return nodeName.startsWith('f') || nodeName.startsWith('x') ? nodeName.charAt(0) + preferredTestKeyword : preferredTestKeyword;
}
function getOppositeTestKeyword(test) {

@@ -126,4 +109,3 @@ if (test === _utils2.TestCaseName.test) {

}
return _utils2.TestCaseName.test;
}

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
/*

@@ -31,3 +28,2 @@ * This implementation is adapted from eslint-plugin-jasmine.

}
var _default = (0, _utils2.createRule)({

@@ -68,3 +64,2 @@ name: __filename,

}],
create(context, [{

@@ -75,7 +70,5 @@ assertFunctionNames = ['expect'],

const unchecked = [];
function checkCallExpressionUsed(nodes) {
for (const node of nodes) {
const index = node.type === _utils.AST_NODE_TYPES.CallExpression ? unchecked.indexOf(node) : -1;
if (node.type === _utils.AST_NODE_TYPES.FunctionDeclaration) {

@@ -86,3 +79,2 @@ const declaredVariables = context.getDeclaredVariables(node);

}
if (index !== -1) {

@@ -94,7 +86,5 @@ unchecked.splice(index, 1);

}
return {
CallExpression(node) {
const name = (0, _utils2.getNodeName)(node.callee) ?? '';
if ((0, _utils2.isTypeOfJestFnCall)(node, context, ['test']) || additionalTestBlockFunctions.includes(name)) {

@@ -104,3 +94,2 @@ if (node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.property, 'todo')) {

}
unchecked.push(node);

@@ -112,3 +101,2 @@ } else if (matchesAssertFunctionName(name, assertFunctionNames)) {

},
'Program:exit'() {

@@ -120,8 +108,5 @@ unchecked.forEach(node => context.report({

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -39,3 +36,2 @@ name: __filename,

}],
create(context, [{

@@ -45,8 +41,5 @@ max

let count = 0;
const maybeResetCount = node => {
var _node$parent;
const isTestFn = ((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) !== _utils.AST_NODE_TYPES.CallExpression || (0, _utils2.isTypeOfJestFnCall)(node.parent, context, ['test']);
if (isTestFn) {

@@ -56,3 +49,2 @@ count = 0;

};
return {

@@ -63,14 +55,9 @@ FunctionExpression: maybeResetCount,

'ArrowFunctionExpression:exit': maybeResetCount,
CallExpression(node) {
var _jestFnCall$head$node;
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect' || ((_jestFnCall$head$node = jestFnCall.head.node.parent) === null || _jestFnCall$head$node === void 0 ? void 0 : _jestFnCall$head$node.type) === _utils.AST_NODE_TYPES.MemberExpression) {
return;
}
count += 1;
if (count > max) {

@@ -87,8 +74,5 @@ context.report({

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -39,3 +36,2 @@ name: __filename,

}],
create(context, [{

@@ -45,3 +41,2 @@ max

const describeCallbackStack = [];
function pushDescribeCallback(node) {

@@ -51,9 +46,6 @@ const {

} = node;
if ((parent === null || parent === void 0 ? void 0 : parent.type) !== _utils.AST_NODE_TYPES.CallExpression || !(0, _utils2.isTypeOfJestFnCall)(parent, context, ['describe'])) {
return;
}
describeCallbackStack.push(0);
if (describeCallbackStack.length > max) {

@@ -70,3 +62,2 @@ context.report({

}
function popDescribeCallback(node) {

@@ -76,3 +67,2 @@ const {

} = node;
if ((parent === null || parent === void 0 ? void 0 : parent.type) === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isTypeOfJestFnCall)(parent, context, ['describe'])) {

@@ -82,3 +72,2 @@ describeCallbackStack.pop();

}
return {

@@ -91,5 +80,3 @@ FunctionExpression: pushDescribeCallback,

}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -27,3 +25,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -47,7 +44,5 @@ // map of jest matcher aliases & their canonical names

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
const {

@@ -57,3 +52,2 @@ matcher

const alias = (0, _utils.getAccessorValue)(matcher);
if (alias in methodNames) {

@@ -72,8 +66,5 @@ const canonical = methodNames[alias];

}
};
}
});
exports.default = _default;

@@ -7,9 +7,6 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
function hasTests(node) {
return /^\s*[xf]?(test|it|describe)(\.\w+|\[['"]\w+['"]\])?\s*\(/mu.test(node.value);
}
var _default = (0, _utils.createRule)({

@@ -30,6 +27,4 @@ name: __filename,

defaultOptions: [],
create(context) {
const sourceCode = context.getSourceCode();
function checkNode(node) {

@@ -39,3 +34,2 @@ if (!hasTests(node)) {

}
context.report({

@@ -46,3 +40,2 @@ messageId: 'commentedTests',

}
return {

@@ -53,8 +46,5 @@ Program() {

}
};
}
});
exports.default = _default;

@@ -7,9 +7,5 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const isCatchCall = node => node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.property, 'catch');
var _default = (0, _utils2.createRule)({

@@ -30,3 +26,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -36,7 +31,4 @@ let conditionalDepth = 0;

let inPromiseCatch = false;
const increaseConditionalDepth = () => inTestCase && conditionalDepth++;
const decreaseConditionalDepth = () => inTestCase && conditionalDepth--;
return {

@@ -46,3 +38,2 @@ FunctionDeclaration(node) {

const testCallExpressions = (0, _utils2.getTestCallExpressionsFromDeclaredVariables)(declaredVariables, context);
if (testCallExpressions.length > 0) {

@@ -52,3 +43,2 @@ inTestCase = true;

},
CallExpression(node) {

@@ -58,11 +48,8 @@ const {

} = (0, _utils2.parseJestFnCall)(node, context) ?? {};
if (jestFnCallType === 'test') {
inTestCase = true;
}
if (isCatchCall(node)) {
inPromiseCatch = true;
}
if (inTestCase && jestFnCallType === 'expect' && conditionalDepth > 0) {

@@ -74,3 +61,2 @@ context.report({

}
if (inPromiseCatch && jestFnCallType === 'expect') {

@@ -83,3 +69,2 @@ context.report({

},
'CallExpression:exit'(node) {

@@ -89,3 +74,2 @@ if ((0, _utils2.isTypeOfJestFnCall)(node, context, ['test'])) {

}
if (isCatchCall(node)) {

@@ -95,3 +79,2 @@ inPromiseCatch = false;

},
CatchClause: increaseConditionalDepth,

@@ -109,5 +92,3 @@ 'CatchClause:exit': decreaseConditionalDepth,

}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -26,6 +24,4 @@ name: __filename,

defaultOptions: [],
create(context) {
let inTestCase = false;
const maybeReportConditional = node => {

@@ -39,3 +35,2 @@ if (inTestCase) {

};
return {

@@ -47,3 +42,2 @@ CallExpression(node) {

},
'CallExpression:exit'(node) {

@@ -54,3 +48,2 @@ if ((0, _utils.isTypeOfJestFnCall)(node, context, ['test'])) {

},
IfStatement: maybeReportConditional,

@@ -62,5 +55,3 @@ SwitchStatement: maybeReportConditional,

}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const parseJestVersion = rawVersion => {

@@ -17,7 +14,5 @@ if (typeof rawVersion === 'number') {

}
const [majorVersion] = rawVersion.split('.');
return parseInt(majorVersion, 10);
};
var _default = (0, _utils2.createRule)({

@@ -39,8 +34,7 @@ name: __filename,

defaultOptions: [],
create(context) {
var _context$settings, _context$settings$jes;
const jestVersion = parseJestVersion(((_context$settings = context.settings) === null || _context$settings === void 0 ? void 0 : (_context$settings$jes = _context$settings.jest) === null || _context$settings$jes === void 0 ? void 0 : _context$settings$jes.version) || (0, _utils2.detectJestVersion)());
const deprecations = { ...(jestVersion >= 15 && {
const deprecations = {
...(jestVersion >= 15 && {
'jest.resetModuleRegistry': 'jest.resetModules'

@@ -67,9 +61,6 @@ }),

}
const deprecation = (0, _utils2.getNodeName)(node);
if (!deprecation || !(deprecation in deprecations)) {
return;
}
const replacement = deprecations[deprecation];

@@ -86,21 +77,14 @@ const {

node,
fix(fixer) {
let [name, func] = replacement.split('.');
if (callee.property.type === _utils.AST_NODE_TYPES.Literal) {
func = `'${func}'`;
}
return [fixer.replaceText(callee.object, name), fixer.replaceText(callee.property, func)];
}
});
}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -31,3 +29,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -39,14 +36,10 @@ let suiteDepth = 0;

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if (!jestFnCall) {
return;
}
if (jestFnCall.type === 'describe') {
suiteDepth++;
}
if (jestFnCall.type === 'test') {
testDepth++;
if (node.arguments.length < 2 && jestFnCall.members.every(s => (0, _utils.getAccessorValue)(s) !== 'todo')) {

@@ -59,4 +52,4 @@ context.report({

}
if ( // the only jest functions that are with "x" are "xdescribe", "xtest", and "xit"
if (
// the only jest functions that are with "x" are "xdescribe", "xtest", and "xit"
jestFnCall.name.startsWith('x') || jestFnCall.members.some(s => (0, _utils.getAccessorValue)(s) === 'skip')) {

@@ -69,14 +62,10 @@ context.report({

},
'CallExpression:exit'(node) {
const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if (!jestFnCall) {
return;
}
if (jestFnCall.type === 'describe') {
suiteDepth--;
}
if (jestFnCall.type === 'test') {

@@ -86,3 +75,2 @@ testDepth--;

},
'CallExpression[callee.name="pending"]'(node) {

@@ -92,3 +80,2 @@ if ((0, _utils.scopeHasLocalReference)(context.getScope(), 'pending')) {

}
if (testDepth > 0) {

@@ -111,8 +98,5 @@ context.report({

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const findCallbackArg = (node, isJestEach, context) => {

@@ -17,16 +14,11 @@ if (isJestEach) {

}
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'hook' && node.arguments.length >= 1) {
return node.arguments[0];
}
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test' && node.arguments.length >= 2) {
return node.arguments[1];
}
return null;
};
var _default = (0, _utils2.createRule)({

@@ -50,3 +42,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -56,6 +47,4 @@ return {

var _getNodeName;
// done is the second argument for it.each, not the first
const isJestEach = ((_getNodeName = (0, _utils2.getNodeName)(node.callee)) === null || _getNodeName === void 0 ? void 0 : _getNodeName.endsWith('.each')) ?? false;
if (isJestEach && node.callee.type !== _utils.AST_NODE_TYPES.TaggedTemplateExpression) {

@@ -67,12 +56,8 @@ // isJestEach but not a TaggedTemplateExpression, so this must be

}
const callback = findCallbackArg(node, isJestEach, context);
const callbackArgIndex = Number(isJestEach);
if (!callback || !(0, _utils2.isFunction)(callback) || callback.params.length !== 1 + callbackArgIndex) {
return;
}
const argument = callback.params[callbackArgIndex];
if (argument.type !== _utils.AST_NODE_TYPES.Identifier) {

@@ -85,3 +70,2 @@ context.report({

}
if (callback.async) {

@@ -94,3 +78,2 @@ context.report({

}
context.report({

@@ -104,3 +87,2 @@ node: argument,

},
fix(fixer) {

@@ -115,25 +97,19 @@ const {

const tokenAfterArgument = sourceCode.getTokenAfter(argument);
/* istanbul ignore if */
if (!firstBodyToken || !lastBodyToken || !tokenBeforeArgument || !tokenAfterArgument) {
throw new Error(`Unexpected null when attempting to fix ${context.getFilename()} - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
}
const argumentInParens = tokenBeforeArgument.value === '(' && tokenAfterArgument.value === ')';
let argumentFix = fixer.replaceText(argument, '()');
if (argumentInParens) {
argumentFix = fixer.remove(argument);
}
let newCallback = argument.name;
if (argumentInParens) {
newCallback = `(${newCallback})`;
}
let beforeReplacement = `new Promise(${newCallback} => `;
let afterReplacement = ')';
let replaceBefore = true;
if (body.type === _utils.AST_NODE_TYPES.BlockStatement) {

@@ -145,15 +121,10 @@ const keyword = 'return';

}
return [argumentFix, replaceBefore ? fixer.insertTextBefore(firstBodyToken, beforeReplacement) : fixer.insertTextAfter(firstBodyToken, beforeReplacement), fixer.insertTextAfter(lastBodyToken, afterReplacement)];
}
}]
});
}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -26,3 +24,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -33,17 +30,12 @@ const hookContexts = [{}];

var _jestFnCall$name;
const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'describe') {
hookContexts.push({});
}
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'hook') {
return;
}
const currentLayer = hookContexts[hookContexts.length - 1];
currentLayer[_jestFnCall$name = jestFnCall.name] || (currentLayer[_jestFnCall$name] = 0);
currentLayer[jestFnCall.name] += 1;
if (currentLayer[jestFnCall.name] > 1) {

@@ -59,3 +51,2 @@ context.report({

},
'CallExpression:exit'(node) {

@@ -66,8 +57,5 @@ if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe'])) {

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -28,3 +25,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -44,3 +40,2 @@ const exportNodes = [];

},
CallExpression(node) {

@@ -51,7 +46,5 @@ if ((0, _utils2.isTypeOfJestFnCall)(node, context, ['test'])) {

},
'ExportNamedDeclaration, ExportDefaultDeclaration'(node) {
exportNodes.push(node);
},
'AssignmentExpression > MemberExpression'(node) {

@@ -62,3 +55,2 @@ let {

} = node;
if (object.type === _utils.AST_NODE_TYPES.MemberExpression) {

@@ -70,3 +62,2 @@ ({

}
if ('name' in object && object.name === 'module' && property.type === _utils.AST_NODE_TYPES.Identifier && /^exports?$/u.test(property.name)) {

@@ -76,8 +67,5 @@ exportNodes.push(node);

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -30,3 +27,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -36,7 +32,5 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test' && (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'describe') {
return;
}
if (jestFnCall.name.startsWith('f')) {

@@ -48,3 +42,2 @@ context.report({

messageId: 'suggestRemoveFocus',
fix(fixer) {

@@ -55,6 +48,4 @@ // don't apply the fixer if we're an aliased import

}
return fixer.removeRange([node.range[0], node.range[0] + 1]);
}
}]

@@ -64,9 +55,6 @@ });

}
const onlyNode = jestFnCall.members.find(s => (0, _utils2.getAccessorValue)(s) === 'only');
if (!onlyNode) {
return;
}
context.report({

@@ -81,8 +69,5 @@ messageId: 'focusedTest',

}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -37,3 +35,2 @@ name: __filename,

}],
create(context, [{

@@ -45,3 +42,2 @@ allow = []

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'hook' && !allow.includes(jestFnCall.name)) {

@@ -57,8 +53,5 @@ context.report({

}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
const newDescribeContext = () => ({

@@ -15,3 +13,2 @@ describeTitles: [],

});
var _default = (0, _utils.createRule)({

@@ -33,3 +30,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -41,23 +37,16 @@ const contexts = [newDescribeContext()];

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if (!jestFnCall) {
return;
}
if (jestFnCall.type === 'describe') {
contexts.push(newDescribeContext());
}
if (jestFnCall.members.find(s => (0, _utils.isSupportedAccessor)(s, 'each'))) {
return;
}
const [argument] = node.arguments;
if (!argument || !(0, _utils.isStringNode)(argument)) {
return;
}
const title = (0, _utils.getStringValue)(argument);
if (jestFnCall.type === 'test') {

@@ -70,10 +59,7 @@ if (currentLayer.testTitles.includes(title)) {

}
currentLayer.testTitles.push(title);
}
if (jestFnCall.type !== 'describe') {
return;
}
if (currentLayer.describeTitles.includes(title)) {

@@ -85,6 +71,4 @@ context.report({

}
currentLayer.describeTitles.push(title);
},
'CallExpression:exit'(node) {

@@ -95,8 +79,5 @@ if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe'])) {

}
};
}
});
exports.default = _default;

@@ -7,11 +7,6 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const testCaseNames = new Set([...Object.keys(_utils2.TestCaseName), 'it.only', 'it.only', 'it.skip', 'it.skip', 'test.only', 'test.only', 'test.skip', 'test.skip', 'fit.concurrent']);
const isTestFunctionExpression = node => node.parent !== undefined && node.parent.type === _utils.AST_NODE_TYPES.CallExpression && testCaseNames.has((0, _utils2.getNodeName)(node.parent.callee));
const conditionName = {

@@ -22,3 +17,2 @@ [_utils.AST_NODE_TYPES.ConditionalExpression]: 'conditional',

};
var _default = (0, _utils2.createRule)({

@@ -41,13 +35,9 @@ name: __filename,

defaultOptions: [],
create(context) {
const stack = [];
function validate(node) {
const lastElementInStack = stack[stack.length - 1];
if (stack.length === 0 || !lastElementInStack) {
return;
}
context.report({

@@ -61,10 +51,7 @@ data: {

}
return {
CallExpression(node) {
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test') {
stack.push(true);
if (jestFnCall.members.some(s => (0, _utils2.getAccessorValue)(s) === 'each')) {

@@ -75,7 +62,5 @@ stack.push(true);

},
FunctionExpression(node) {
stack.push(isTestFunctionExpression(node));
},
FunctionDeclaration(node) {

@@ -86,32 +71,23 @@ const declaredVariables = context.getDeclaredVariables(node);

},
ArrowFunctionExpression(node) {
stack.push(isTestFunctionExpression(node));
},
IfStatement: validate,
SwitchStatement: validate,
ConditionalExpression: validate,
'CallExpression:exit'() {
stack.pop();
},
'FunctionExpression:exit'() {
stack.pop();
},
'FunctionDeclaration:exit'() {
stack.pop();
},
'ArrowFunctionExpression:exit'() {
stack.pop();
}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -28,3 +25,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -34,7 +30,5 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
if (['toMatchInlineSnapshot', 'toThrowErrorMatchingInlineSnapshot'].includes((0, _utils2.getAccessorValue)(jestFnCall.matcher))) {

@@ -52,8 +46,5 @@ // Check all since the optional 'propertyMatchers' argument might be present

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -33,3 +30,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -42,7 +38,5 @@ return {

const calleeName = (0, _utils2.getNodeName)(callee);
if (!calleeName) {
return;
}
if (calleeName === 'spyOn' || calleeName === 'spyOnProperty' || calleeName === 'fail' || calleeName === 'pending') {

@@ -53,3 +47,2 @@ if ((0, _utils2.scopeHasLocalReference)(context.getScope(), calleeName)) {

}
switch (calleeName) {

@@ -67,3 +60,2 @@ case 'spyOn':

break;
case 'fail':

@@ -75,3 +67,2 @@ context.report({

break;
case 'pending':

@@ -84,9 +75,6 @@ context.report({

}
return;
}
if (callee.type === _utils.AST_NODE_TYPES.MemberExpression && calleeName.startsWith('jasmine.')) {
const functionName = calleeName.replace('jasmine.', '');
if (functionName === 'any' || functionName === 'anything' || functionName === 'arrayContaining' || functionName === 'objectContaining' || functionName === 'stringMatching') {

@@ -104,3 +92,2 @@ context.report({

}
if (functionName === 'addMatchers') {

@@ -117,3 +104,2 @@ context.report({

}
if (functionName === 'createSpy') {

@@ -130,3 +116,2 @@ context.report({

}
context.report({

@@ -138,3 +123,2 @@ node,

},
MemberExpression(node) {

@@ -146,3 +130,2 @@ if ((0, _utils2.isSupportedAccessor)(node.object, 'jasmine')) {

} = node;
if (parent && parent.type === _utils.AST_NODE_TYPES.AssignmentExpression) {

@@ -153,3 +136,2 @@ if ((0, _utils2.isSupportedAccessor)(property, 'DEFAULT_TIMEOUT_INTERVAL')) {

} = parent;
if (right.type === _utils.AST_NODE_TYPES.Literal) {

@@ -164,3 +146,2 @@ context.report({

}
context.report({

@@ -173,8 +154,5 @@ node,

}
};
}
});
exports.default = _default;

@@ -7,9 +7,5 @@ "use strict";

exports.default = void 0;
var _path = require("path");
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const reportOnViolation = (context, node, {

@@ -23,13 +19,9 @@ maxSize: lineLimit = 50,

const allPathsAreAbsolute = Object.keys(allowedSnapshots).every(_path.isAbsolute);
if (!allPathsAreAbsolute) {
throw new Error('All paths for allowedSnapshots must be absolute. You can use JS config and `path.resolve`');
}
let isAllowed = false;
if (node.type === _utils.AST_NODE_TYPES.ExpressionStatement && 'left' in node.expression && node.expression.left.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.expression.left.property)) {
const fileName = context.getFilename();
const allowedSnapshotsInFile = allowedSnapshots[fileName];
if (allowedSnapshotsInFile) {

@@ -41,3 +33,2 @@ const snapshotName = (0, _utils2.getAccessorValue)(node.expression.left.property);

}
return snapshotName === name;

@@ -47,3 +38,2 @@ });

}
if (!isAllowed && lineCount > lineLimit) {

@@ -60,3 +50,2 @@ context.report({

};
var _default = (0, _utils2.createRule)({

@@ -95,3 +84,2 @@ name: __filename,

defaultOptions: [{}],
create(context, [options]) {

@@ -103,16 +91,13 @@ if (context.getFilename().endsWith('.snap')) {

}
};
}
return {
CallExpression(node) {
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
if (['toMatchInlineSnapshot', 'toThrowErrorMatchingInlineSnapshot'].includes((0, _utils2.getAccessorValue)(jestFnCall.matcher)) && jestFnCall.args.length) {
reportOnViolation(context, jestFnCall.args[0], { ...options,
reportOnViolation(context, jestFnCall.args[0], {
...options,
maxSize: options.inlineMaxSize ?? options.maxSize

@@ -122,8 +107,5 @@ });

}
};
}
});
exports.default = _default;

@@ -7,13 +7,7 @@ "use strict";

exports.default = void 0;
var _path = require("path");
var _utils = require("./utils");
const mocksDirName = '__mocks__';
const isMockPath = path => path.split(_path.posix.sep).includes(mocksDirName);
const isMockImportLiteral = expression => (0, _utils.isStringNode)(expression) && isMockPath((0, _utils.getStringValue)(expression));
var _default = (0, _utils.createRule)({

@@ -34,3 +28,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -46,6 +39,4 @@ return {

},
'CallExpression[callee.name="require"]'(node) {
const [arg] = node.arguments;
if (arg && isMockImportLiteral(arg)) {

@@ -58,8 +49,5 @@ context.report({

}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
const messages = {

@@ -15,3 +13,2 @@ restrictedJestMethod: 'Use of `{{ restriction }}` is disallowed',

};
var _default = (0, _utils.createRule)({

@@ -35,3 +32,2 @@ name: __filename,

defaultOptions: [{}],
create(context, [restrictedMethods]) {

@@ -41,9 +37,6 @@ return {

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'jest') {
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'jest' || jestFnCall.members.length === 0) {
return;
}
const method = (0, _utils.getAccessorValue)(jestFnCall.members[0]);
if (method in restrictedMethods) {

@@ -64,8 +57,5 @@ const message = restrictedMethods[method];

}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
const isChainRestricted = (chain, restriction) => {

@@ -15,6 +13,4 @@ if (_utils.ModifierName.hasOwnProperty(restriction) || restriction.endsWith('.not')) {

}
return chain === restriction;
};
var _default = (0, _utils.createRule)({

@@ -41,3 +37,2 @@ name: __filename,

defaultOptions: [{}],
create(context, [restrictedChains]) {

@@ -47,9 +42,6 @@ return {

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
const chain = jestFnCall.members.map(nod => (0, _utils.getAccessorValue)(nod)).join('.');
for (const [restriction, message] of Object.entries(restrictedChains)) {

@@ -72,8 +64,5 @@ if (isChainRestricted(chain, restriction)) {

}
};
}
});
exports.default = _default;

@@ -7,28 +7,25 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const getBlockType = (statement, context) => {
const func = statement.parent;
/* istanbul ignore if */
if (!func) {
throw new Error(`Unexpected BlockStatement. No parent defined. - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
} // functionDeclaration: function func() {}
}
// functionDeclaration: function func() {}
if (func.type === _utils.AST_NODE_TYPES.FunctionDeclaration) {
return 'function';
}
if ((0, _utils2.isFunction)(func) && func.parent) {
const expr = func.parent; // arrow function or function expr
const expr = func.parent;
// arrow function or function expr
if (expr.type === _utils.AST_NODE_TYPES.VariableDeclarator) {
return 'function';
} // if it's not a variable, it will be callExpr, we only care about describe
}
// if it's not a variable, it will be callExpr, we only care about describe
if (expr.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isTypeOfJestFnCall)(expr, context, ['describe'])) {

@@ -38,6 +35,4 @@ return 'describe';

}
return null;
};
var _default = (0, _utils2.createRule)({

@@ -70,3 +65,2 @@ name: __filename,

}],
create(context, [{

@@ -76,18 +70,12 @@ additionalTestBlockFunctions = []

const callStack = [];
const isCustomTestBlockFunction = node => additionalTestBlockFunctions.includes((0, _utils2.getNodeName)(node) || '');
return {
CallExpression(node) {
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect') {
var _jestFnCall$head$node;
if (((_jestFnCall$head$node = jestFnCall.head.node.parent) === null || _jestFnCall$head$node === void 0 ? void 0 : _jestFnCall$head$node.type) === _utils.AST_NODE_TYPES.MemberExpression && jestFnCall.members.length === 1 && !['assertions', 'hasAssertions'].includes((0, _utils2.getAccessorValue)(jestFnCall.members[0]))) {
return;
}
const parent = callStack[callStack.length - 1];
if (!parent || parent === _utils2.DescribeAlias.describe) {

@@ -99,10 +87,7 @@ context.report({

}
return;
}
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test' || isCustomTestBlockFunction(node)) {
callStack.push('test');
}
if (node.callee.type === _utils.AST_NODE_TYPES.TaggedTemplateExpression) {

@@ -112,6 +97,4 @@ callStack.push('template');

},
'CallExpression:exit'(node) {
const top = callStack[callStack.length - 1];
if (top === 'test' && ((0, _utils2.isTypeOfJestFnCall)(node, context, ['test']) || isCustomTestBlockFunction(node)) && node.callee.type !== _utils.AST_NODE_TYPES.MemberExpression || top === 'template' && node.callee.type === _utils.AST_NODE_TYPES.TaggedTemplateExpression) {

@@ -121,6 +104,4 @@ callStack.pop();

},
BlockStatement(statement) {
const blockType = getBlockType(statement, context);
if (blockType) {

@@ -130,3 +111,2 @@ callStack.push(blockType);

},
'BlockStatement:exit'(statement) {

@@ -137,6 +117,4 @@ if (callStack[callStack.length - 1] === getBlockType(statement, context)) {

},
ArrowFunctionExpression(node) {
var _node$parent;
if (((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) !== _utils.AST_NODE_TYPES.CallExpression) {

@@ -146,3 +124,2 @@ callStack.push('arrow');

},
'ArrowFunctionExpression:exit'() {

@@ -153,8 +130,5 @@ if (callStack[callStack.length - 1] === 'arrow') {

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -29,3 +26,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -35,11 +31,8 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'describe' && (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test') {
return;
}
if (jestFnCall.name[0] !== 'f' && jestFnCall.name[0] !== 'x') {
return;
}
const preferredNodeName = [jestFnCall.name.slice(1), jestFnCall.name[0] === 'f' ? 'only' : 'skip', ...jestFnCall.members.map(s => (0, _utils2.getAccessorValue)(s))].join('.');

@@ -53,15 +46,10 @@ const funcNode = node.callee.type === _utils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _utils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;

},
fix(fixer) {
return [fixer.replaceText(funcNode, preferredNodeName)];
}
});
}
};
}
});
exports.default = _default;

@@ -7,17 +7,11 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const getBody = args => {
const [, secondArg] = args;
if (secondArg && (0, _utils2.isFunction)(secondArg) && secondArg.body.type === _utils.AST_NODE_TYPES.BlockStatement) {
return secondArg.body.body;
}
return [];
};
var _default = (0, _utils2.createRule)({

@@ -38,3 +32,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -46,3 +39,2 @@ return {

}
const body = getBody(node.arguments);

@@ -56,3 +48,2 @@ const returnStmt = body.find(t => t.type === _utils.AST_NODE_TYPES.ReturnStatement);

},
FunctionDeclaration(node) {

@@ -69,8 +60,5 @@ const declaredVariables = context.getDeclaredVariables(node);

}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -26,3 +24,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -32,11 +29,8 @@ return {

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
if (jestFnCall.modifiers.some(nod => (0, _utils.getAccessorValue)(nod) === 'not')) {
return;
}
const {

@@ -46,3 +40,2 @@ matcher

const matcherName = (0, _utils.getAccessorValue)(matcher);
if (['toBeCalled', 'toHaveBeenCalled'].includes(matcherName)) {

@@ -58,8 +51,5 @@ context.report({

}
};
}
});
exports.default = _default;

@@ -7,15 +7,10 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const isString = node => {
return (0, _utils2.isStringNode)(node) || node.type === _utils.AST_NODE_TYPES.TemplateLiteral;
};
const isComparingToString = expression => {
return isString(expression.left) || isString(expression.right);
};
const invertOperator = operator => {

@@ -25,36 +20,25 @@ switch (operator) {

return '<=';
case '<':
return '>=';
case '>=':
return '<';
case '<=':
return '>';
}
return null;
};
const determineMatcher = (operator, negated) => {
const op = negated ? invertOperator(operator) : operator;
switch (op) {
case '>':
return 'toBeGreaterThan';
case '<':
return 'toBeLessThan';
case '>=':
return 'toBeGreaterThanOrEqual';
case '<=':
return 'toBeLessThanOrEqual';
}
return null;
};
var _default = (0, _utils2.createRule)({

@@ -76,3 +60,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -82,15 +65,11 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect' || jestFnCall.args.length === 0) {
return;
}
const {
parent: expect
} = jestFnCall.head.node;
if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
return;
}
const {

@@ -104,26 +83,25 @@ arguments: [comparison],

const matcherArg = (0, _utils2.getFirstMatcherArg)(jestFnCall);
if ((comparison === null || comparison === void 0 ? void 0 : comparison.type) !== _utils.AST_NODE_TYPES.BinaryExpression || isComparingToString(comparison) || !_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || !(0, _utils2.isBooleanLiteral)(matcherArg)) {
return;
}
const [modifier] = jestFnCall.modifiers;
const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
const preferredMatcher = determineMatcher(comparison.operator, matcherArg.value === hasNot);
if (!preferredMatcher) {
return;
}
context.report({
fix(fixer) {
const sourceCode = context.getSourceCode(); // preserve the existing modifier if it's not a negation
const sourceCode = context.getSourceCode();
// preserve the existing modifier if it's not a negation
const modifierText = modifier && (0, _utils2.getAccessorValue)(modifier) !== 'not' ? `.${(0, _utils2.getAccessorValue)(modifier)}` : '';
return [// replace the comparison argument with the left-hand side of the comparison
fixer.replaceText(comparison, sourceCode.getText(comparison.left)), // replace the current matcher & modifier with the preferred matcher
fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], `${modifierText}.${preferredMatcher}`), // replace the matcher argument with the right-hand side of the comparison
return [
// replace the comparison argument with the left-hand side of the comparison
fixer.replaceText(comparison, sourceCode.getText(comparison.left)),
// replace the current matcher & modifier with the preferred matcher
fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], `${modifierText}.${preferredMatcher}`),
// replace the matcher argument with the right-hand side of the comparison
fixer.replaceText(matcherArg, sourceCode.getText(comparison.right))];
},
messageId: 'useToBeComparison',

@@ -136,8 +114,5 @@ data: {

}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -26,7 +24,5 @@ name: __filename,

defaultOptions: [],
create(context) {
const jestFnCalls = [];
let inTestCaseCall = false;
const recommendFn = () => {

@@ -36,6 +32,4 @@ if (jestFnCalls.length === 1 && jestFnCalls[0] === 'test') {

}
return 'describe';
};
const enterForLoop = () => {

@@ -45,6 +39,4 @@ if (jestFnCalls.length === 0 || inTestCaseCall) {

}
jestFnCalls.length = 0;
};
const exitForLoop = node => {

@@ -54,3 +46,2 @@ if (jestFnCalls.length === 0 || inTestCaseCall) {

}
context.report({

@@ -65,3 +56,2 @@ node,

};
return {

@@ -74,3 +64,2 @@ ForStatement: enterForLoop,

'ForOfStatement:exit': exitForLoop,
CallExpression(node) {

@@ -80,7 +69,5 @@ const {

} = (0, _utils.parseJestFnCall)(node, context) ?? {};
if (jestFnCallType === 'hook' || jestFnCallType === 'describe' || jestFnCallType === 'test') {
jestFnCalls.push(jestFnCallType);
}
if (jestFnCallType === 'test') {

@@ -90,3 +77,2 @@ inTestCaseCall = true;

},
'CallExpression:exit'(node) {

@@ -96,3 +82,2 @@ const {

} = (0, _utils.parseJestFnCall)(node, context) ?? {};
if (jestFnCallType === 'test') {

@@ -102,8 +87,5 @@ inTestCaseCall = false;

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -30,3 +27,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -36,15 +32,11 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect' || jestFnCall.args.length === 0) {
return;
}
const {
parent: expect
} = jestFnCall.head.node;
if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
return;
}
const {

@@ -58,29 +50,28 @@ arguments: [comparison],

const matcherArg = (0, _utils2.getFirstMatcherArg)(jestFnCall);
if ((comparison === null || comparison === void 0 ? void 0 : comparison.type) !== _utils.AST_NODE_TYPES.BinaryExpression || comparison.operator !== '===' && comparison.operator !== '!==' || !_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || !(0, _utils2.isBooleanLiteral)(matcherArg)) {
return;
}
const matcherValue = matcherArg.value;
const [modifier] = jestFnCall.modifiers;
const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not'); // we need to negate the expectation if the current expected
const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
// we need to negate the expectation if the current expected
// value is itself negated by the "not" modifier
const addNotModifier = (comparison.operator === '!==' ? !matcherValue : matcherValue) === hasNot;
const buildFixer = equalityMatcher => fixer => {
const sourceCode = context.getSourceCode(); // preserve the existing modifier if it's not a negation
const sourceCode = context.getSourceCode();
// preserve the existing modifier if it's not a negation
let modifierText = modifier && (0, _utils2.getAccessorValue)(modifier) !== 'not' ? `.${(0, _utils2.getAccessorValue)(modifier)}` : '';
if (addNotModifier) {
modifierText += `.${_utils2.ModifierName.not}`;
}
return [// replace the comparison argument with the left-hand side of the comparison
fixer.replaceText(comparison, sourceCode.getText(comparison.left)), // replace the current matcher & modifier with the preferred matcher
fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], `${modifierText}.${equalityMatcher}`), // replace the matcher argument with the right-hand side of the comparison
return [
// replace the comparison argument with the left-hand side of the comparison
fixer.replaceText(comparison, sourceCode.getText(comparison.left)),
// replace the current matcher & modifier with the preferred matcher
fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], `${modifierText}.${equalityMatcher}`),
// replace the matcher argument with the right-hand side of the comparison
fixer.replaceText(matcherArg, sourceCode.getText(comparison.right))];
};
context.report({

@@ -98,8 +89,5 @@ messageId: 'useEqualityMatcher',

}
};
}
});
exports.default = _default;

@@ -7,31 +7,23 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const isFirstStatement = node => {
let parent = node;
while (parent) {
var _parent$parent, _parent$parent2;
if (((_parent$parent = parent.parent) === null || _parent$parent === void 0 ? void 0 : _parent$parent.type) === _utils.AST_NODE_TYPES.BlockStatement) {
return parent.parent.body[0] === parent;
} // if we've hit an arrow function, then it must have a single expression
}
// if we've hit an arrow function, then it must have a single expression
// as its body, as otherwise we would have hit the block statement already
if (((_parent$parent2 = parent.parent) === null || _parent$parent2 === void 0 ? void 0 : _parent$parent2.type) === _utils.AST_NODE_TYPES.ArrowFunctionExpression) {
return true;
}
parent = parent.parent;
}
/* istanbul ignore next */
throw new Error(`Could not find BlockStatement - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
};
const suggestRemovingExtraArguments = (args, extraArgsStartAt) => ({

@@ -41,3 +33,2 @@ messageId: 'suggestRemovingExtraArguments',

});
var _default = (0, _utils2.createRule)({

@@ -83,3 +74,2 @@ name: __filename,

}],
create(context, [options]) {

@@ -92,3 +82,2 @@ let expressionDepth = 0;

let inForLoop = false;
const shouldCheckFunction = testFunction => {

@@ -98,3 +87,2 @@ if (!options.onlyFunctionsWithAsyncKeyword && !options.onlyFunctionsWithExpectInLoop && !options.onlyFunctionsWithExpectInCallback) {

}
if (options.onlyFunctionsWithAsyncKeyword) {

@@ -105,3 +93,2 @@ if (testFunction.async) {

}
if (options.onlyFunctionsWithExpectInLoop) {

@@ -112,3 +99,2 @@ if (hasExpectInLoop) {

}
if (options.onlyFunctionsWithExpectInCallback) {

@@ -119,6 +105,4 @@ if (hasExpectInCallback) {

}
return false;
};
const checkExpectHasAssertions = expectFnCall => {

@@ -133,6 +117,4 @@ if ((0, _utils2.getAccessorValue)(expectFnCall.members[0]) === 'hasAssertions') {

}
return;
}
if (expectFnCall.args.length !== 1) {

@@ -143,3 +125,2 @@ let {

const suggest = [];
if (expectFnCall.args.length) {

@@ -149,3 +130,2 @@ loc = expectFnCall.args[1].loc;

}
context.report({

@@ -158,9 +138,6 @@ messageId: 'assertionsRequiresOneArgument',

}
const [arg] = expectFnCall.args;
if (arg.type === _utils.AST_NODE_TYPES.Literal && typeof arg.value === 'number' && Number.isInteger(arg.value)) {
return;
}
context.report({

@@ -171,11 +148,6 @@ messageId: 'assertionsRequiresNumberArgument',

};
const enterExpression = () => inTestCaseCall && expressionDepth++;
const exitExpression = () => inTestCaseCall && expressionDepth--;
const enterForLoop = () => inForLoop = true;
const exitForLoop = () => inForLoop = false;
return {

@@ -192,6 +164,4 @@ FunctionExpression: enterExpression,

'ForOfStatement:exit': exitForLoop,
CallExpression(node) {
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test') {

@@ -201,6 +171,4 @@ inTestCaseCall = true;

}
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect' && inTestCaseCall) {
var _jestFnCall$head$node;
if (expressionDepth === 1 && isFirstStatement(node) && ((_jestFnCall$head$node = jestFnCall.head.node.parent) === null || _jestFnCall$head$node === void 0 ? void 0 : _jestFnCall$head$node.type) === _utils.AST_NODE_TYPES.MemberExpression && jestFnCall.members.length === 1 && ['assertions', 'hasAssertions'].includes((0, _utils2.getAccessorValue)(jestFnCall.members[0]))) {

@@ -210,7 +178,5 @@ checkExpectHasAssertions(jestFnCall);

}
if (inForLoop) {
hasExpectInLoop = true;
}
if (expressionDepth > 1) {

@@ -221,3 +187,2 @@ hasExpectInCallback = true;

},
'CallExpression:exit'(node) {

@@ -227,18 +192,12 @@ if (!(0, _utils2.isTypeOfJestFnCall)(node, context, ['test'])) {

}
inTestCaseCall = false;
if (node.arguments.length < 2) {
return;
}
const [, testFn] = node.arguments;
if (!(0, _utils2.isFunction)(testFn) || !shouldCheckFunction(testFn)) {
return;
}
hasExpectInLoop = false;
hasExpectInCallback = false;
if (hasExpectAssertionsAsFirstStatement) {

@@ -248,9 +207,6 @@ hasExpectAssertionsAsFirstStatement = false;

}
const suggestions = [];
if (testFn.body.type === _utils.AST_NODE_TYPES.BlockStatement) {
suggestions.push(['suggestAddingHasAssertions', 'expect.hasAssertions();'], ['suggestAddingAssertions', 'expect.assertions();']);
}
context.report({

@@ -265,8 +221,5 @@ messageId: 'haveExpectAssertions',

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -32,17 +29,12 @@ name: __filename,

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
const {
parent
} = jestFnCall.head.node;
if ((parent === null || parent === void 0 ? void 0 : parent.type) !== _utils.AST_NODE_TYPES.CallExpression) {
return;
}
const [awaitNode] = parent.arguments;
if ((awaitNode === null || awaitNode === void 0 ? void 0 : awaitNode.type) === _utils.AST_NODE_TYPES.AwaitExpression) {

@@ -52,14 +44,10 @@ context.report({

messageId: 'expectResolves',
fix(fixer) {
return [fixer.insertTextBefore(parent, 'await '), fixer.removeRange([awaitNode.range[0], awaitNode.argument.range[0]]), fixer.insertTextAfter(parent, '.resolves')];
}
});
}
}
})
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
const HooksOrder = ['beforeAll', 'beforeEach', 'afterEach', 'afterAll'];
var _default = (0, _utils.createRule)({

@@ -28,3 +25,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -39,5 +35,3 @@ let previousHookIndex = -1;

}
const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'hook') {

@@ -48,7 +42,5 @@ // Reset the previousHookIndex when encountering something different from a hook

}
inHook = true;
const currentHook = jestFnCall.name;
const currentHookIndex = HooksOrder.indexOf(currentHook);
if (currentHookIndex < previousHookIndex) {

@@ -65,6 +57,4 @@ context.report({

}
previousHookIndex = currentHookIndex;
},
'CallExpression:exit'(node) {

@@ -75,16 +65,12 @@ if ((0, _utils.isTypeOfJestFnCall)(node, context, ['hook'])) {

}
if (inHook) {
return;
} // Reset the previousHookIndex when encountering something different from a hook
}
// Reset the previousHookIndex when encountering something different from a hook
previousHookIndex = -1;
}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -26,3 +24,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -35,3 +32,2 @@ const hooksContext = [false];

}
if (hooksContext[hooksContext.length - 1] && (0, _utils.isTypeOfJestFnCall)(node, context, ['hook'])) {

@@ -43,15 +39,10 @@ context.report({

}
hooksContext.push(false);
},
'CallExpression:exit'() {
hooksContext.pop();
}
};
}
});
exports.default = _default;

@@ -7,25 +7,17 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
const hasStringAsFirstArgument = node => node.arguments[0] && (0, _utils.isStringNode)(node.arguments[0]);
const populateIgnores = ignore => {
const ignores = [];
if (ignore.includes(_utils.DescribeAlias.describe)) {
ignores.push(...Object.keys(_utils.DescribeAlias));
}
if (ignore.includes(_utils.TestCaseName.test)) {
ignores.push(...Object.keys(_utils.TestCaseName).filter(k => k.endsWith(_utils.TestCaseName.test)));
}
if (ignore.includes(_utils.TestCaseName.it)) {
ignores.push(...Object.keys(_utils.TestCaseName).filter(k => k.endsWith(_utils.TestCaseName.it)));
}
return ignores;
};
var _default = (0, _utils.createRule)({

@@ -74,3 +66,2 @@ name: __filename,

}],
create(context, [{

@@ -86,10 +77,7 @@ ignore = [],

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if (!jestFnCall || !hasStringAsFirstArgument(node)) {
return;
}
if (jestFnCall.type === 'describe') {
numberOfDescribeBlocks++;
if (ignoreTopLevelDescribe && numberOfDescribeBlocks === 1) {

@@ -101,16 +89,11 @@ return;

}
const [firstArg] = node.arguments;
const description = (0, _utils.getStringValue)(firstArg);
if (allowedPrefixes.some(name => description.startsWith(name))) {
return;
}
const firstCharacter = description.charAt(0);
if (!firstCharacter || firstCharacter === firstCharacter.toLowerCase() || ignores.includes(jestFnCall.name)) {
return;
}
context.report({

@@ -122,3 +105,2 @@ messageId: 'unexpectedLowercase',

},
fix(fixer) {

@@ -130,6 +112,4 @@ const description = (0, _utils.getStringValue)(firstArg);

}
});
},
'CallExpression:exit'(node) {

@@ -140,8 +120,5 @@ if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe'])) {

}
};
}
});
exports.default = _default;

@@ -7,25 +7,17 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const withOnce = (name, addOnce) => {
return `${name}${addOnce ? 'Once' : ''}`;
};
const findSingleReturnArgumentNode = fnNode => {
var _fnNode$body$body$;
if (fnNode.body.type !== _utils.AST_NODE_TYPES.BlockStatement) {
return fnNode.body;
}
if (((_fnNode$body$body$ = fnNode.body.body[0]) === null || _fnNode$body$body$ === void 0 ? void 0 : _fnNode$body$body$.type) === _utils.AST_NODE_TYPES.ReturnStatement) {
return fnNode.body.body[0].argument;
}
return null;
};
var _default = (0, _utils2.createRule)({

@@ -47,3 +39,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -54,9 +45,6 @@ const report = (property, isOnce, outerArgNode, innerArgNode = outerArgNode) => {

}
const argName = (0, _utils2.getNodeName)(innerArgNode);
if (argName !== 'Promise.resolve' && argName !== 'Promise.reject') {
return;
}
const replacement = withOnce(argName.endsWith('reject') ? 'mockRejectedValue' : 'mockResolvedValue', isOnce);

@@ -69,12 +57,12 @@ context.report({

},
fix(fixer) {
const sourceCode = context.getSourceCode();
fix(fixer) {
const sourceCode = context.getSourceCode(); // there shouldn't be more than one argument, but if there is don't try
// there shouldn't be more than one argument, but if there is don't try
// fixing since we have no idea what to do with the extra arguments
if (innerArgNode.arguments.length > 1) {
return null;
}
return [fixer.replaceText(property, replacement), fixer.replaceText(outerArgNode, // the value argument for both Promise methods is optional,
return [fixer.replaceText(property, replacement), fixer.replaceText(outerArgNode,
// the value argument for both Promise methods is optional,
// whereas for Jest they're required so use an explicit undefined

@@ -84,6 +72,4 @@ // if no argument is being passed to the call we're replacing

}
});
};
return {

@@ -94,6 +80,4 @@ CallExpression(node) {

}
const mockFnName = (0, _utils2.getAccessorValue)(node.callee.property);
const isOnce = mockFnName.endsWith('Once');
if (mockFnName === withOnce('mockReturnValue', isOnce)) {

@@ -103,16 +87,11 @@ report(node.callee.property, isOnce, node.arguments[0]);

const [arg] = node.arguments;
if (!(0, _utils2.isFunction)(arg) || arg.params.length !== 0) {
return;
}
report(node.callee.property, isOnce, arg, findSingleReturnArgumentNode(arg));
}
}
};
}
});
exports.default = _default;

@@ -7,35 +7,30 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
const snapshotMatchers = ['toMatchSnapshot', 'toThrowErrorMatchingSnapshot'];
const snapshotMatcherNames = snapshotMatchers;
const isSnapshotMatcherWithoutHint = expectFnCall => {
if (expectFnCall.args.length === 0) {
return true;
} // this matcher only supports one argument which is the hint
}
// this matcher only supports one argument which is the hint
if (!(0, _utils.isSupportedAccessor)(expectFnCall.matcher, 'toMatchSnapshot')) {
return expectFnCall.args.length !== 1;
} // if we're being passed two arguments,
}
// if we're being passed two arguments,
// the second one should be the hint
if (expectFnCall.args.length === 2) {
return false;
}
const [arg] = expectFnCall.args;
const [arg] = expectFnCall.args; // the first argument to `toMatchSnapshot` can be _either_ a snapshot hint or
// the first argument to `toMatchSnapshot` can be _either_ a snapshot hint or
// an object with asymmetric matchers, so we can't just assume that the first
// argument is a hint when it's by itself.
return !(0, _utils.isStringNode)(arg);
};
const messages = {
missingHint: 'You should provide a hint for this snapshot'
};
var _default = (0, _utils.createRule)({

@@ -57,3 +52,2 @@ name: __filename,

defaultOptions: ['multi'],
create(context, [mode]) {

@@ -63,3 +57,2 @@ const snapshotMatchers = [];

let expressionDepth = 0;
const reportSnapshotMatchersWithoutHints = () => {

@@ -75,10 +68,7 @@ for (const snapshotMatcher of snapshotMatchers) {

};
const enterExpression = () => {
expressionDepth++;
};
const exitExpression = () => {
expressionDepth--;
if (mode === 'always') {

@@ -88,3 +78,2 @@ reportSnapshotMatchersWithoutHints();

}
if (mode === 'multi' && expressionDepth === 0) {

@@ -94,7 +83,5 @@ if (snapshotMatchers.length > 1) {

}
snapshotMatchers.length = 0;
}
};
return {

@@ -105,3 +92,2 @@ 'Program:exit'() {

},
FunctionExpression: enterExpression,

@@ -111,3 +97,2 @@ 'FunctionExpression:exit': exitExpression,

'ArrowFunctionExpression:exit': exitExpression,
'CallExpression:exit'(node) {

@@ -119,6 +104,4 @@ if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe', 'test'])) {

},
CallExpression(node) {
const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {

@@ -129,20 +112,13 @@ if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'describe' || (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'test') {

}
return;
}
const matcherName = (0, _utils.getAccessorValue)(jestFnCall.matcher);
if (!snapshotMatcherNames.includes(matcherName)) {
return;
}
snapshotMatchers.push(jestFnCall);
}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const findNodeObject = node => {

@@ -17,10 +14,7 @@ if ('object' in node) {

}
if (node.callee.type === _utils.AST_NODE_TYPES.MemberExpression) {
return node.callee.object;
}
return null;
};
const getJestFnCall = node => {

@@ -30,16 +24,11 @@ if (node.type !== _utils.AST_NODE_TYPES.CallExpression && node.type !== _utils.AST_NODE_TYPES.MemberExpression) {

}
const obj = findNodeObject(node);
if (!obj) {
return null;
}
if (obj.type === _utils.AST_NODE_TYPES.Identifier) {
return node.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.getNodeName)(node.callee) === 'jest.fn' ? node : null;
}
return getJestFnCall(obj);
};
var _default = (0, _utils2.createRule)({

@@ -61,3 +50,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -76,3 +64,2 @@ return {

messageId: 'useJestSpyOn',
fix(fixer) {

@@ -85,11 +72,7 @@ const leftPropQuote = left.property.type === _utils.AST_NODE_TYPES.Identifier ? "'" : '';

}
});
}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -28,3 +26,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -34,11 +31,8 @@ return {

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
const {
matcher
} = jestFnCall;
if ((0, _utils.isSupportedAccessor)(matcher, 'toEqual')) {

@@ -55,8 +49,5 @@ context.report({

}
};
}
});
exports.default = _default;

@@ -7,8 +7,6 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const isNullLiteral = node => node.type === _utils.AST_NODE_TYPES.Literal && node.value === null;
const isNullLiteral = node => node.type === _utils.AST_NODE_TYPES.Literal && node.value === null;
/**

@@ -18,15 +16,9 @@ * Checks if the given `ParsedEqualityMatcherCall` is a call to one of the equality matchers,

*/
const isNullEqualityMatcher = expectFnCall => isNullLiteral((0, _utils2.getFirstMatcherArg)(expectFnCall));
const isFirstArgumentIdentifier = (expectFnCall, name) => (0, _utils2.isIdentifier)((0, _utils2.getFirstMatcherArg)(expectFnCall), name);
const shouldUseToBe = expectFnCall => {
let firstArg = (0, _utils2.getFirstMatcherArg)(expectFnCall);
if (firstArg.type === _utils.AST_NODE_TYPES.UnaryExpression && firstArg.operator === '-') {
firstArg = firstArg.argument;
}
if (firstArg.type === _utils.AST_NODE_TYPES.Literal) {

@@ -37,30 +29,21 @@ // regex literals are classed as literals, but they're actually objects

}
return firstArg.type === _utils.AST_NODE_TYPES.TemplateLiteral;
};
const reportPreferToBe = (context, whatToBe, expectFnCall, modifierNode) => {
context.report({
messageId: `useToBe${whatToBe}`,
fix(fixer) {
var _expectFnCall$args;
const fixes = [(0, _utils2.replaceAccessorFixer)(fixer, expectFnCall.matcher, `toBe${whatToBe}`)];
if ((_expectFnCall$args = expectFnCall.args) !== null && _expectFnCall$args !== void 0 && _expectFnCall$args.length && whatToBe !== '') {
fixes.push(fixer.remove(expectFnCall.args[0]));
}
if (modifierNode) {
fixes.push(fixer.removeRange([modifierNode.range[0] - 1, modifierNode.range[1]]));
}
return fixes;
},
node: expectFnCall.matcher
});
};
var _default = (0, _utils2.createRule)({

@@ -86,3 +69,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -92,10 +74,7 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
const matcherName = (0, _utils2.getAccessorValue)(jestFnCall.matcher);
const notModifier = jestFnCall.modifiers.find(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
if (notModifier && ['toBeUndefined', 'toBeDefined'].includes(matcherName)) {

@@ -105,7 +84,5 @@ reportPreferToBe(context, matcherName === 'toBeDefined' ? 'Undefined' : 'Defined', jestFnCall, notModifier);

}
if (!_utils2.EqualityMatcher.hasOwnProperty(matcherName) || jestFnCall.args.length === 0) {
return;
}
if (isNullEqualityMatcher(jestFnCall)) {

@@ -115,3 +92,2 @@ reportPreferToBe(context, 'Null', jestFnCall);

}
if (isFirstArgumentIdentifier(jestFnCall, 'undefined')) {

@@ -122,3 +98,2 @@ const name = notModifier ? 'Defined' : 'Undefined';

}
if (isFirstArgumentIdentifier(jestFnCall, 'NaN')) {

@@ -128,3 +103,2 @@ reportPreferToBe(context, 'NaN', jestFnCall);

}
if (shouldUseToBe(jestFnCall) && matcherName !== _utils2.EqualityMatcher.toBe) {

@@ -134,8 +108,5 @@ reportPreferToBe(context, '', jestFnCall);

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
/**

@@ -21,5 +18,5 @@ * Checks if the given `node` is a `CallExpression` representing the calling

*/
const isFixableIncludesCallExpression = node => node.type === _utils.AST_NODE_TYPES.CallExpression && node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.property, 'includes') && (0, _utils2.hasOnlyOneArgument)(node) && node.arguments[0].type !== _utils.AST_NODE_TYPES.SpreadElement; // expect(array.includes(<value>)[not.]{toBe,toEqual}(<boolean>)
const isFixableIncludesCallExpression = node => node.type === _utils.AST_NODE_TYPES.CallExpression && node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.property, 'includes') && (0, _utils2.hasOnlyOneArgument)(node) && node.arguments[0].type !== _utils.AST_NODE_TYPES.SpreadElement;
// expect(array.includes(<value>)[not.]{toBe,toEqual}(<boolean>)
var _default = (0, _utils2.createRule)({

@@ -41,3 +38,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -47,15 +43,11 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect' || jestFnCall.args.length === 0) {
return;
}
const {
parent: expect
} = jestFnCall.head.node;
if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
return;
}
const {

@@ -69,20 +61,21 @@ arguments: [includesCall],

const matcherArg = (0, _utils2.getFirstMatcherArg)(jestFnCall);
if (!includesCall || matcherArg.type === _utils.AST_NODE_TYPES.SpreadElement || !_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || !(0, _utils2.isBooleanLiteral)(matcherArg) || !isFixableIncludesCallExpression(includesCall)) {
return;
}
const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
context.report({
fix(fixer) {
const sourceCode = context.getSourceCode(); // we need to negate the expectation if the current expected
const sourceCode = context.getSourceCode();
// we need to negate the expectation if the current expected
// value is itself negated by the "not" modifier
const addNotModifier = matcherArg.value === hasNot;
return [// remove the "includes" call entirely
fixer.removeRange([includesCall.callee.property.range[0] - 1, includesCall.range[1]]), // replace the current matcher with "toContain", adding "not" if needed
fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], addNotModifier ? `.${_utils2.ModifierName.not}.toContain` : '.toContain'), // replace the matcher argument with the value from the "includes"
return [
// remove the "includes" call entirely
fixer.removeRange([includesCall.callee.property.range[0] - 1, includesCall.range[1]]),
// replace the current matcher with "toContain", adding "not" if needed
fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], addNotModifier ? `.${_utils2.ModifierName.not}.toContain` : '.toContain'),
// replace the matcher argument with the value from the "includes"
fixer.replaceText(jestFnCall.args[0], sourceCode.getText(includesCall.arguments[0]))];
},
messageId: 'useToContain',

@@ -92,8 +85,5 @@ node: matcher

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
var _default = (0, _utils2.createRule)({

@@ -29,3 +26,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -35,15 +31,11 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
const {
parent: expect
} = jestFnCall.head.node;
if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
return;
}
const [argument] = expect.arguments;

@@ -53,14 +45,13 @@ const {

} = jestFnCall;
if (!_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || (argument === null || argument === void 0 ? void 0 : argument.type) !== _utils.AST_NODE_TYPES.MemberExpression || !(0, _utils2.isSupportedAccessor)(argument.property, 'length')) {
return;
}
context.report({
fix(fixer) {
return [// remove the "length" property accessor
fixer.removeRange([argument.property.range[0] - 1, argument.range[1]]), // replace the current matcher with "toHaveLength"
return [
// remove the "length" property accessor
fixer.removeRange([argument.property.range[0] - 1, argument.range[1]]),
// replace the current matcher with "toHaveLength"
fixer.replaceTextRange([matcher.parent.object.range[1], matcher.parent.range[1]], '.toHaveLength')];
},
messageId: 'useToHaveLength',

@@ -70,8 +61,5 @@ node: matcher

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
function isEmptyFunction(node) {

@@ -17,6 +14,4 @@ if (!(0, _utils2.isFunction)(node)) {

}
return node.body.type === _utils.AST_NODE_TYPES.BlockStatement && !node.body.body.length;
}
function createTodoFixer(jestFnCall, fixer) {

@@ -26,19 +21,15 @@ if (jestFnCall.members.length) {

}
return fixer.replaceText(jestFnCall.head.node, `${jestFnCall.head.local}.todo`);
}
const isTargetedTestCase = jestFnCall => {
if (jestFnCall.members.some(s => (0, _utils2.getAccessorValue)(s) !== 'skip')) {
return false;
} // todo: we should support this too (needs custom fixer)
}
// todo: we should support this too (needs custom fixer)
if (jestFnCall.name.startsWith('x')) {
return false;
}
return !jestFnCall.name.startsWith('f');
};
var _default = (0, _utils2.createRule)({

@@ -61,3 +52,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -68,7 +58,5 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if (!title || (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test' || !isTargetedTestCase(jestFnCall) || !(0, _utils2.isStringNode)(title)) {
return;
}
if (callback && isEmptyFunction(callback)) {

@@ -81,3 +69,2 @@ context.report({

}
if ((0, _utils2.hasOnlyOneArgument)(node)) {

@@ -91,8 +78,5 @@ context.report({

}
};
}
});
exports.default = _default;

@@ -7,21 +7,14 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const isJestFnCall = (node, context) => {
var _getNodeName;
if ((0, _utils2.parseJestFnCall)(node, context)) {
return true;
}
return !!((_getNodeName = (0, _utils2.getNodeName)(node)) !== null && _getNodeName !== void 0 && _getNodeName.startsWith('jest.'));
};
const isNullOrUndefined = node => {
return node.type === _utils.AST_NODE_TYPES.Literal && node.value === null || (0, _utils2.isIdentifier)(node, 'undefined');
};
const shouldBeInHook = (node, context, allowedFunctionCalls = []) => {

@@ -31,6 +24,4 @@ switch (node.type) {

return shouldBeInHook(node.expression, context, allowedFunctionCalls);
case _utils.AST_NODE_TYPES.CallExpression:
return !(isJestFnCall(node, context) || allowedFunctionCalls.includes((0, _utils2.getNodeName)(node)));
case _utils.AST_NODE_TYPES.VariableDeclaration:

@@ -41,3 +32,2 @@ {

}
return node.declarations.some(({

@@ -47,3 +37,2 @@ init

}
default:

@@ -53,3 +42,2 @@ return false;

};
var _default = (0, _utils2.createRule)({

@@ -83,3 +71,2 @@ name: __filename,

}],
create(context) {

@@ -89,3 +76,2 @@ const {

} = context.options[0] ?? {};
const checkBlockBody = body => {

@@ -101,3 +87,2 @@ for (const statement of body) {

};
return {

@@ -107,3 +92,2 @@ Program(program) {

},
CallExpression(node) {

@@ -113,17 +97,11 @@ if (!(0, _utils2.isTypeOfJestFnCall)(node, context, ['describe']) || node.arguments.length < 2) {

}
const [, testFn] = node.arguments;
if (!(0, _utils2.isFunction)(testFn) || testFn.body.type !== _utils.AST_NODE_TYPES.BlockStatement) {
return;
}
checkBlockBody(testFn.body.body);
}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
var _default = (0, _utils.createRule)({

@@ -26,3 +24,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -32,7 +29,5 @@ return {

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {
return;
}
const {

@@ -42,3 +37,2 @@ matcher

const matcherName = (0, _utils.getAccessorValue)(matcher);
if (jestFnCall.args.length === 0 && ['toThrow', 'toThrowError'].includes(matcherName) && !jestFnCall.modifiers.some(nod => (0, _utils.getAccessorValue)(nod) === 'not')) {

@@ -55,8 +49,5 @@ // Look for `toThrow` calls with no arguments.

}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.default = void 0;
var _utils = require("./utils");
const messages = {

@@ -16,3 +14,2 @@ tooManyDescribes: 'There should not be more than {{ max }} describe{{ s }} at the top level',

};
var _default = (0, _utils.createRule)({

@@ -40,3 +37,2 @@ name: __filename,

defaultOptions: [{}],
create(context) {

@@ -51,13 +47,9 @@ const {

const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
if (!jestFnCall) {
return;
}
if (jestFnCall.type === 'describe') {
numberOfDescribeBlocks++;
if (numberOfDescribeBlocks === 1) {
numberOfTopLevelDescribeBlocks++;
if (numberOfTopLevelDescribeBlocks > maxNumberOfTopLevelDescribes) {

@@ -74,6 +66,4 @@ context.report({

}
return;
}
if (numberOfDescribeBlocks === 0) {

@@ -87,3 +77,2 @@ if (jestFnCall.type === 'test') {

}
if (jestFnCall.type === 'hook') {

@@ -98,3 +87,2 @@ context.report({

},
'CallExpression:exit'(node) {

@@ -105,8 +93,5 @@ if ((0, _utils.isTypeOfJestFnCall)(node, context, ['describe'])) {

}
};
}
});
exports.default = _default;

@@ -7,9 +7,5 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const toThrowMatchers = ['toThrow', 'toThrowError', 'toThrowErrorMatchingSnapshot', 'toThrowErrorMatchingInlineSnapshot'];
const baseRule = (() => {

@@ -19,17 +15,12 @@ try {

const TSESLintPlugin = require('@typescript-eslint/eslint-plugin');
return TSESLintPlugin.rules['unbound-method'];
} catch (e) {
const error = e;
if (error.code === 'MODULE_NOT_FOUND') {
return null;
}
throw error;
}
})();
const DEFAULT_MESSAGE = 'This rule requires `@typescript-eslint/eslint-plugin`';
var _default = (0, _utils2.createRule)({

@@ -57,18 +48,13 @@ defaultOptions: [{

},
create(context) {
const baseSelectors = baseRule === null || baseRule === void 0 ? void 0 : baseRule.create(context);
if (!baseSelectors) {
return {};
}
return { ...baseSelectors,
return {
...baseSelectors,
MemberExpression(node) {
var _node$parent, _baseSelectors$Member;
if (((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) === _utils.AST_NODE_TYPES.CallExpression) {
const jestFnCall = (0, _utils2.parseJestFnCall)((0, _utils2.findTopMostCallExpression)(node.parent), context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect') {

@@ -78,3 +64,2 @@ const {

} = jestFnCall;
if (!toThrowMatchers.includes((0, _utils2.getAccessorValue)(matcher))) {

@@ -85,11 +70,7 @@ return;

}
(_baseSelectors$Member = baseSelectors.MemberExpression) === null || _baseSelectors$Member === void 0 ? void 0 : _baseSelectors$Member.call(baseSelectors, node);
}
};
}
});
exports.default = _default;

@@ -7,5 +7,3 @@ "use strict";

exports.isSupportedAccessor = exports.isStringNode = exports.isIdentifier = exports.getStringValue = exports.getAccessorValue = void 0;
var _utils = require("@typescript-eslint/utils");
/**

@@ -25,3 +23,2 @@ * Checks if the given `node` is a `StringLiteral`.

const isStringLiteral = (node, value) => node.type === _utils.AST_NODE_TYPES.Literal && typeof node.value === 'string' && (value === undefined || node.value === value);
/**

@@ -42,5 +39,5 @@ * Checks if the given `node` is a `TemplateLiteral`.

*/
const isTemplateLiteral = (node, value) => node.type === _utils.AST_NODE_TYPES.TemplateLiteral && node.quasis.length === 1 && ( // bail out if not simple
const isTemplateLiteral = (node, value) => node.type === _utils.AST_NODE_TYPES.TemplateLiteral && node.quasis.length === 1 && (
// bail out if not simple
value === undefined || node.quasis[0].value.raw === value);
/**

@@ -57,2 +54,3 @@ * Checks if the given `node` is a {@link StringNode}.

const isStringNode = (node, specifics) => isStringLiteral(node, specifics) || isTemplateLiteral(node, specifics);
/**

@@ -70,14 +68,9 @@ * Gets the value of the given `StringNode`.

*/
exports.isStringNode = isStringNode;
const getStringValue = node => isTemplateLiteral(node) ? node.quasis[0].value.raw : node.value;
const getStringValue = node => isTemplateLiteral(node) ? node.quasis[0].value.raw : node.value;
/**
* An `Identifier` with a known `name` value - i.e `expect`.
*/
exports.getStringValue = getStringValue;
/**

@@ -97,2 +90,3 @@ * Checks if the given `node` is an `Identifier`.

const isIdentifier = (node, name) => node.type === _utils.AST_NODE_TYPES.Identifier && (name === undefined || node.name === name);
/**

@@ -120,7 +114,5 @@ * Checks if the given `node` is a "supported accessor".

*/
exports.isIdentifier = isIdentifier;
const isSupportedAccessor = (node, value) => isIdentifier(node, value) || isStringNode(node, value);
const isSupportedAccessor = (node, value) => isIdentifier(node, value) || isStringNode(node, value);
/**

@@ -136,8 +128,4 @@ * Gets the value of the given `AccessorNode`,

*/
exports.isSupportedAccessor = isSupportedAccessor;
const getAccessorValue = accessor => accessor.type === _utils.AST_NODE_TYPES.Identifier ? accessor.name : getStringValue(accessor);
exports.getAccessorValue = getAccessorValue;

@@ -8,3 +8,2 @@ "use strict";

let cachedJestVersion = null;
const detectJestVersion = () => {

@@ -14,9 +13,7 @@ if (cachedJestVersion) {

}
try {
const jestPath = require.resolve('jest/package.json');
const jestPackageJson = // eslint-disable-next-line @typescript-eslint/no-require-imports
const jestPackageJson =
// eslint-disable-next-line @typescript-eslint/no-require-imports
require(jestPath);
if (jestPackageJson.version) {

@@ -27,6 +24,4 @@ const [majorVersion] = jestPackageJson.version.split('.');

} catch {}
throw new Error('Unable to detect Jest version - please ensure jest package is installed, or otherwise set version explicitly');
};
exports.detectJestVersion = detectJestVersion;

@@ -7,9 +7,5 @@ "use strict";

exports.followTypeAssertionChain = void 0;
var _utils = require("@typescript-eslint/utils");
const isTypeCastExpression = node => node.type === _utils.AST_NODE_TYPES.TSAsExpression || node.type === _utils.AST_NODE_TYPES.TSTypeAssertion;
const followTypeAssertionChain = expression => isTypeCastExpression(expression) ? followTypeAssertionChain(expression.expression) : expression;
exports.followTypeAssertionChain = followTypeAssertionChain;

@@ -6,5 +6,3 @@ "use strict";

});
var _accessors = require("./accessors");
Object.keys(_accessors).forEach(function (key) {

@@ -20,5 +18,3 @@ if (key === "default" || key === "__esModule") return;

});
var _detectJestVersion = require("./detectJestVersion");
Object.keys(_detectJestVersion).forEach(function (key) {

@@ -34,5 +30,3 @@ if (key === "default" || key === "__esModule") return;

});
var _followTypeAssertionChain = require("./followTypeAssertionChain");
Object.keys(_followTypeAssertionChain).forEach(function (key) {

@@ -48,5 +42,3 @@ if (key === "default" || key === "__esModule") return;

});
var _misc = require("./misc");
Object.keys(_misc).forEach(function (key) {

@@ -62,5 +54,3 @@ if (key === "default" || key === "__esModule") return;

});
var _parseJestFnCall = require("./parseJestFnCall");
Object.keys(_parseJestFnCall).forEach(function (key) {

@@ -67,0 +57,0 @@ if (key === "default" || key === "__esModule") return;

@@ -9,17 +9,9 @@ "use strict";

exports.replaceAccessorFixer = exports.isFunction = exports.isBooleanLiteral = exports.hasOnlyOneArgument = exports.getTestCallExpressionsFromDeclaredVariables = void 0;
var _path = require("path");
var _utils = require("@typescript-eslint/utils");
var _package = require("../../../package.json");
var _accessors = require("./accessors");
var _followTypeAssertionChain = require("./followTypeAssertionChain");
var _parseJestFnCall = require("./parseJestFnCall");
const REPO_URL = 'https://github.com/jest-community/eslint-plugin-jest';
const createRule = _utils.ESLintUtils.RuleCreator(name => {

@@ -29,9 +21,7 @@ const ruleName = (0, _path.parse)(name).name;

});
/**
* Represents a `MemberExpression` with a "known" `property`.
*/
exports.createRule = createRule;
/**

@@ -45,7 +35,5 @@ * Guards that the given `call` has only one `argument`.

const hasOnlyOneArgument = call => call.arguments.length === 1;
exports.hasOnlyOneArgument = hasOnlyOneArgument;
let DescribeAlias;
exports.DescribeAlias = DescribeAlias;
(function (DescribeAlias) {

@@ -56,6 +44,4 @@ DescribeAlias["describe"] = "describe";

})(DescribeAlias || (exports.DescribeAlias = DescribeAlias = {}));
let TestCaseName;
exports.TestCaseName = TestCaseName;
(function (TestCaseName) {

@@ -68,6 +54,4 @@ TestCaseName["fit"] = "fit";

})(TestCaseName || (exports.TestCaseName = TestCaseName = {}));
let HookName;
exports.HookName = HookName;
(function (HookName) {

@@ -79,6 +63,4 @@ HookName["beforeAll"] = "beforeAll";

})(HookName || (exports.HookName = HookName = {}));
let ModifierName;
exports.ModifierName = ModifierName;
(function (ModifierName) {

@@ -89,6 +71,4 @@ ModifierName["not"] = "not";

})(ModifierName || (exports.ModifierName = ModifierName = {}));
let EqualityMatcher;
exports.EqualityMatcher = EqualityMatcher;
(function (EqualityMatcher) {

@@ -99,5 +79,3 @@ EqualityMatcher["toBe"] = "toBe";

})(EqualityMatcher || (exports.EqualityMatcher = EqualityMatcher = {}));
const joinNames = (a, b) => a && b ? `${a}.${b}` : null;
function getNodeName(node) {

@@ -107,10 +85,7 @@ if ((0, _accessors.isSupportedAccessor)(node)) {

}
switch (node.type) {
case _utils.AST_NODE_TYPES.TaggedTemplateExpression:
return getNodeName(node.tag);
case _utils.AST_NODE_TYPES.MemberExpression:
return joinNames(getNodeName(node.object), getNodeName(node.property));
case _utils.AST_NODE_TYPES.NewExpression:

@@ -120,10 +95,6 @@ case _utils.AST_NODE_TYPES.CallExpression:

}
return null;
}
const isFunction = node => node.type === _utils.AST_NODE_TYPES.FunctionExpression || node.type === _utils.AST_NODE_TYPES.ArrowFunctionExpression;
exports.isFunction = isFunction;
const getTestCallExpressionsFromDeclaredVariables = (declaredVariables, context) => {

@@ -136,2 +107,3 @@ return declaredVariables.reduce((acc, {

};
/**

@@ -143,12 +115,7 @@ * Replaces an accessor node with the given `text`, surrounding it in quotes if required.

*/
exports.getTestCallExpressionsFromDeclaredVariables = getTestCallExpressionsFromDeclaredVariables;
const replaceAccessorFixer = (fixer, node, text) => {
return fixer.replaceText(node, node.type === _utils.AST_NODE_TYPES.Identifier ? text : `'${text}'`);
};
exports.replaceAccessorFixer = replaceAccessorFixer;
const findTopMostCallExpression = node => {

@@ -159,3 +126,2 @@ let topMostCallExpression = node;

} = node;
while (parent) {

@@ -167,29 +133,19 @@ if (parent.type === _utils.AST_NODE_TYPES.CallExpression) {

}
if (parent.type !== _utils.AST_NODE_TYPES.MemberExpression) {
break;
}
parent = parent.parent;
}
return topMostCallExpression;
};
exports.findTopMostCallExpression = findTopMostCallExpression;
const isBooleanLiteral = node => node.type === _utils.AST_NODE_TYPES.Literal && typeof node.value === 'boolean';
exports.isBooleanLiteral = isBooleanLiteral;
const getFirstMatcherArg = expectFnCall => {
const [firstArg] = expectFnCall.args;
if (firstArg.type === _utils.AST_NODE_TYPES.SpreadElement) {
return firstArg;
}
return (0, _followTypeAssertionChain.followTypeAssertionChain)(firstArg);
};
exports.getFirstMatcherArg = getFirstMatcherArg;

@@ -8,7 +8,4 @@ "use strict";

exports.scopeHasLocalReference = exports.parseJestFnCallWithReason = exports.parseJestFnCall = exports.isTypeOfJestFnCall = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("../utils");
const isTypeOfJestFnCall = (node, context, types) => {

@@ -18,7 +15,4 @@ const jestFnCall = parseJestFnCall(node, context);

};
exports.isTypeOfJestFnCall = isTypeOfJestFnCall;
const joinChains = (a, b) => a && b ? [...a, ...b] : null;
function getNodeChain(node) {

@@ -28,17 +22,12 @@ if ((0, _utils2.isSupportedAccessor)(node)) {

}
switch (node.type) {
case _utils.AST_NODE_TYPES.TaggedTemplateExpression:
return getNodeChain(node.tag);
case _utils.AST_NODE_TYPES.MemberExpression:
return joinChains(getNodeChain(node.object), getNodeChain(node.property));
case _utils.AST_NODE_TYPES.CallExpression:
return getNodeChain(node.callee);
}
return null;
}
const determineJestFnType = name => {

@@ -48,62 +37,44 @@ if (name === 'expect') {

}
if (name === 'jest') {
return 'jest';
}
if (_utils2.DescribeAlias.hasOwnProperty(name)) {
return 'describe';
}
if (_utils2.TestCaseName.hasOwnProperty(name)) {
return 'test';
}
/* istanbul ignore else */
if (_utils2.HookName.hasOwnProperty(name)) {
return 'hook';
}
/* istanbul ignore next */
return 'unknown';
};
const ValidJestFnCallChains = ['afterAll', 'afterEach', 'beforeAll', 'beforeEach', 'describe', 'describe.each', 'describe.only', 'describe.only.each', 'describe.skip', 'describe.skip.each', 'fdescribe', 'fdescribe.each', 'xdescribe', 'xdescribe.each', 'it', 'it.concurrent', 'it.concurrent.each', 'it.concurrent.only.each', 'it.concurrent.skip.each', 'it.each', 'it.failing', 'it.only', 'it.only.each', 'it.only.failing', 'it.skip', 'it.skip.each', 'it.skip.failing', 'it.todo', 'fit', 'fit.each', 'fit.failing', 'xit', 'xit.each', 'xit.failing', 'test', 'test.concurrent', 'test.concurrent.each', 'test.concurrent.only.each', 'test.concurrent.skip.each', 'test.each', 'test.failing', 'test.only', 'test.only.each', 'test.only.failing', 'test.skip', 'test.skip.each', 'test.skip.failing', 'test.todo', 'xtest', 'xtest.each', 'xtest.failing'];
const resolvePossibleAliasedGlobal = (global, context) => {
var _context$settings$jes;
const globalAliases = ((_context$settings$jes = context.settings.jest) === null || _context$settings$jes === void 0 ? void 0 : _context$settings$jes.globalAliases) ?? {};
const alias = Object.entries(globalAliases).find(([, aliases]) => aliases.includes(global));
if (alias) {
return alias[0];
}
return null;
};
const parseJestFnCallCache = new WeakMap();
const parseJestFnCall = (node, context) => {
const jestFnCall = parseJestFnCallWithReason(node, context);
if (typeof jestFnCall === 'string') {
return null;
}
return jestFnCall;
};
exports.parseJestFnCall = parseJestFnCall;
const parseJestFnCallWithReason = (node, context) => {
let parsedJestFnCall = parseJestFnCallCache.get(node);
if (parsedJestFnCall) {
return parsedJestFnCall;
}
parsedJestFnCall = parseJestFnCallWithReasonInner(node, context);

@@ -113,17 +84,13 @@ parseJestFnCallCache.set(node, parsedJestFnCall);

};
exports.parseJestFnCallWithReason = parseJestFnCallWithReason;
const parseJestFnCallWithReasonInner = (node, context) => {
var _node$parent2, _node$parent3;
const chain = getNodeChain(node);
if (!(chain !== null && chain !== void 0 && chain.length)) {
return null;
}
const [first, ...rest] = chain;
const lastLink = (0, _utils2.getAccessorValue)(chain[chain.length - 1]); // if we're an `each()`, ensure we're the outer CallExpression (i.e `.each()()`)
const lastLink = (0, _utils2.getAccessorValue)(chain[chain.length - 1]);
// if we're an `each()`, ensure we're the outer CallExpression (i.e `.each()()`)
if (lastLink === 'each') {

@@ -134,23 +101,20 @@ if (node.callee.type !== _utils.AST_NODE_TYPES.CallExpression && node.callee.type !== _utils.AST_NODE_TYPES.TaggedTemplateExpression) {

}
if (node.callee.type === _utils.AST_NODE_TYPES.TaggedTemplateExpression && lastLink !== 'each') {
return null;
}
const resolved = resolveToJestFn(context, (0, _utils2.getAccessorValue)(first));
const resolved = resolveToJestFn(context, (0, _utils2.getAccessorValue)(first)); // we're not a jest function
// we're not a jest function
if (!resolved) {
return null;
}
const name = resolved.original ?? resolved.local;
const links = [name, ...rest.map(link => (0, _utils2.getAccessorValue)(link))];
if (name !== 'jest' && name !== 'expect' && !ValidJestFnCallChains.includes(links.join('.'))) {
return null;
}
const parsedJestFnCall = {
name,
head: { ...resolved,
head: {
...resolved,
node: first

@@ -163,14 +127,12 @@ },

const type = determineJestFnType(name);
if (type === 'expect') {
const result = parseJestExpectCall(parsedJestFnCall);
if (type === 'expect') {
const result = parseJestExpectCall(parsedJestFnCall); // if the `expect` call chain is not valid, only report on the topmost node
// if the `expect` call chain is not valid, only report on the topmost node
// since all members in the chain are likely to get flagged for some reason
if (typeof result === 'string' && (0, _utils2.findTopMostCallExpression)(node) !== node) {
return null;
}
if (result === 'matcher-not-found') {
var _node$parent;
if (((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) === _utils.AST_NODE_TYPES.MemberExpression) {

@@ -180,33 +142,28 @@ return 'matcher-not-called';

}
return result;
} // check that every link in the chain except the last is a member expression
}
// check that every link in the chain except the last is a member expression
if (chain.slice(0, chain.length - 1).some(nod => {
var _nod$parent;
return ((_nod$parent = nod.parent) === null || _nod$parent === void 0 ? void 0 : _nod$parent.type) !== _utils.AST_NODE_TYPES.MemberExpression;
})) {
return null;
} // ensure that we're at the "top" of the function call chain otherwise when
}
// ensure that we're at the "top" of the function call chain otherwise when
// parsing e.g. x().y.z(), we'll incorrectly find & parse "x()" even though
// the full chain is not a valid jest function call chain
if (((_node$parent2 = node.parent) === null || _node$parent2 === void 0 ? void 0 : _node$parent2.type) === _utils.AST_NODE_TYPES.CallExpression || ((_node$parent3 = node.parent) === null || _node$parent3 === void 0 ? void 0 : _node$parent3.type) === _utils.AST_NODE_TYPES.MemberExpression) {
return null;
}
return { ...parsedJestFnCall,
return {
...parsedJestFnCall,
type
};
};
const findModifiersAndMatcher = members => {
const modifiers = [];
for (const member of members) {
var _member$parent, _member$parent$parent;
// check if the member is being called, which means it is the matcher

@@ -220,7 +177,6 @@ // (and also the end of the entire "expect" call chain)

};
} // otherwise, it should be a modifier
}
// otherwise, it should be a modifier
const name = (0, _utils2.getAccessorValue)(member);
if (modifiers.length === 0) {

@@ -236,5 +192,5 @@ // the first modifier can be any of the three modifiers

}
const firstModifier = (0, _utils2.getAccessorValue)(modifiers[0]);
const firstModifier = (0, _utils2.getAccessorValue)(modifiers[0]); // and the first modifier has to be either "resolves" or "rejects"
// and the first modifier has to be either "resolves" or "rejects"
if (firstModifier !== _utils2.ModifierName.resolves && firstModifier !== _utils2.ModifierName.rejects) {

@@ -246,18 +202,15 @@ return 'modifier-unknown';

}
modifiers.push(member);
} // this will only really happen if there are no members
}
// this will only really happen if there are no members
return 'matcher-not-found';
};
const parseJestExpectCall = typelessParsedJestFnCall => {
const modifiersAndMatcher = findModifiersAndMatcher(typelessParsedJestFnCall.members);
if (typeof modifiersAndMatcher === 'string') {
return modifiersAndMatcher;
}
return { ...typelessParsedJestFnCall,
return {
...typelessParsedJestFnCall,
type: 'expect',

@@ -267,3 +220,2 @@ ...modifiersAndMatcher

};
const describeImportDefAsImport = def => {

@@ -273,12 +225,10 @@ if (def.parent.type === _utils.AST_NODE_TYPES.TSImportEqualsDeclaration) {

}
if (def.node.type !== _utils.AST_NODE_TYPES.ImportSpecifier) {
return null;
} // we only care about value imports
}
// we only care about value imports
if (def.parent.importKind === 'type') {
return null;
}
return {

@@ -290,2 +240,3 @@ source: def.parent.source.value,

};
/**

@@ -298,4 +249,2 @@ * Attempts to find the node that represents the import source for the

*/
const findImportSourceNode = node => {

@@ -306,16 +255,11 @@ if (node.type === _utils.AST_NODE_TYPES.AwaitExpression) {

}
return null;
}
if (node.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isIdentifier)(node.callee, 'require')) {
return node.arguments[0] ?? null;
}
return null;
};
const describeVariableDefAsImport = def => {
var _def$name$parent;
// make sure that we've actually being assigned a value

@@ -325,17 +269,12 @@ if (!def.node.init) {

}
const sourceNode = findImportSourceNode(def.node.init);
if (!sourceNode || !(0, _utils2.isStringNode)(sourceNode)) {
return null;
}
if (((_def$name$parent = def.name.parent) === null || _def$name$parent === void 0 ? void 0 : _def$name$parent.type) !== _utils.AST_NODE_TYPES.Property) {
return null;
}
if (!(0, _utils2.isSupportedAccessor)(def.name.parent.key)) {
return null;
}
return {

@@ -347,2 +286,3 @@ source: (0, _utils2.getStringValue)(sourceNode),

};
/**

@@ -358,4 +298,2 @@ * Attempts to describe a definition as an import if possible.

*/
const describePossibleImportDef = def => {

@@ -365,10 +303,7 @@ if (def.type === 'Variable') {

}
if (def.type === 'ImportBinding') {
return describeImportDefAsImport(def);
}
return null;
};
const collectReferences = scope => {

@@ -379,3 +314,2 @@ const locals = new Set();

let currentScope = scope;
while (currentScope !== null) {

@@ -386,6 +320,4 @@ for (const ref of currentScope.variables) {

}
const def = ref.defs[ref.defs.length - 1];
const importDetails = describePossibleImportDef(def);
if (importDetails) {

@@ -395,13 +327,9 @@ imports.set(importDetails.local, importDetails);

}
locals.add(ref.name);
}
for (const ref of currentScope.through) {
unresolved.add(ref.identifier.name);
}
currentScope = currentScope.upper;
}
return {

@@ -413,7 +341,5 @@ locals,

};
const resolveToJestFn = (context, identifier) => {
const references = collectReferences(context.getScope());
const maybeImport = references.imports.get(identifier);
if (maybeImport) {

@@ -429,12 +355,10 @@ // the identifier is imported from @jest/globals,

}
return null;
}
return null;
} // the identifier was found as a local variable or function declaration
// the identifier was found as a local variable or function declaration
// meaning it's not a function from jest
if (references.locals.has(identifier)) {
return null;
}
return {

@@ -446,8 +370,10 @@ original: resolvePossibleAliasedGlobal(identifier, context),

};
const scopeHasLocalReference = (scope, referenceName) => {
const references = collectReferences(scope);
return (// referenceName was found as a local variable or function declaration.
references.locals.has(referenceName) || // referenceName was found as an imported identifier
references.imports.has(referenceName) || // referenceName was not found as an unresolved reference,
return (
// referenceName was found as a local variable or function declaration.
references.locals.has(referenceName) ||
// referenceName was found as an imported identifier
references.imports.has(referenceName) ||
// referenceName was not found as an unresolved reference,
// meaning it is likely not an implicit global reference.

@@ -457,3 +383,2 @@ !references.unresolved.has(referenceName)

};
exports.scopeHasLocalReference = scopeHasLocalReference;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const paramsLocation = params => {

@@ -21,3 +18,2 @@ const [first] = params;

};
var _default = (0, _utils2.createRule)({

@@ -42,3 +38,2 @@ name: __filename,

defaultOptions: [],
create(context) {

@@ -48,7 +43,5 @@ return {

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'describe') {
return;
}
if (node.arguments.length < 1) {

@@ -60,5 +53,3 @@ return context.report({

}
const [, callback] = node.arguments;
if (!callback) {

@@ -71,3 +62,2 @@ context.report({

}
if (!(0, _utils2.isFunction)(callback)) {

@@ -80,3 +70,2 @@ context.report({

}
if (callback.async) {

@@ -88,3 +77,2 @@ context.report({

}
if (jestFnCall.members.every(s => (0, _utils2.getAccessorValue)(s) !== 'each') && callback.params.length) {

@@ -96,3 +84,2 @@ context.report({

}
if (callback.body.type === _utils.AST_NODE_TYPES.CallExpression) {

@@ -104,3 +91,2 @@ context.report({

}
if (callback.body.type === _utils.AST_NODE_TYPES.BlockStatement) {

@@ -117,8 +103,5 @@ callback.body.body.forEach(node => {

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const isPromiseChainCall = node => {

@@ -19,7 +16,5 @@ if (node.type === _utils.AST_NODE_TYPES.CallExpression && node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.property)) {

}
switch ((0, _utils2.getAccessorValue)(node.callee.property)) {
case 'then':
return node.arguments.length < 3;
case 'catch':

@@ -30,15 +25,10 @@ case 'finally':

}
return false;
};
const isTestCaseCallWithCallbackArg = (node, context) => {
const jestCallFn = (0, _utils2.parseJestFnCall)(node, context);
if ((jestCallFn === null || jestCallFn === void 0 ? void 0 : jestCallFn.type) !== 'test') {
return false;
}
const isJestEach = jestCallFn.members.some(s => (0, _utils2.getAccessorValue)(s) === 'each');
if (isJestEach && node.callee.type !== _utils.AST_NODE_TYPES.TaggedTemplateExpression) {

@@ -51,3 +41,2 @@ // isJestEach but not a TaggedTemplateExpression, so this must be

}
const [, callback] = node.arguments;

@@ -57,3 +46,2 @@ const callbackArgIndex = Number(isJestEach);

};
const isPromiseMethodThatUsesValue = (node, identifier) => {

@@ -63,13 +51,9 @@ const {

} = identifier;
if (node.argument === null) {
return false;
}
if (node.argument.type === _utils.AST_NODE_TYPES.CallExpression && node.argument.arguments.length > 0) {
const nodeName = (0, _utils2.getNodeName)(node.argument);
if (['Promise.all', 'Promise.allSettled'].includes(nodeName)) {
const [firstArg] = node.argument.arguments;
if (firstArg.type === _utils.AST_NODE_TYPES.ArrayExpression && firstArg.elements.some(nod => (0, _utils2.isIdentifier)(nod, name))) {

@@ -79,3 +63,2 @@ return true;

}
if (['Promise.resolve', 'Promise.reject'].includes(nodeName) && node.argument.arguments.length === 1) {

@@ -85,5 +68,5 @@ return (0, _utils2.isIdentifier)(node.argument.arguments[0], name);

}
return (0, _utils2.isIdentifier)(node.argument, name);
};
/**

@@ -93,4 +76,2 @@ * Attempts to determine if the runtime value represented by the given `identifier`

*/
const isValueAwaitedInElements = (name, elements) => {

@@ -101,3 +82,2 @@ for (const element of elements) {

}
if (element.type === _utils.AST_NODE_TYPES.ArrayExpression && isValueAwaitedInElements(name, element.elements)) {

@@ -107,5 +87,5 @@ return true;

}
return false;
};
/**

@@ -115,7 +95,4 @@ * Attempts to determine if the runtime value represented by the given `identifier`

*/
const isValueAwaitedInArguments = (name, call) => {
let node = call;
while (node) {

@@ -126,20 +103,14 @@ if (node.type === _utils.AST_NODE_TYPES.CallExpression) {

}
node = node.callee;
}
if (node.type !== _utils.AST_NODE_TYPES.MemberExpression) {
break;
}
node = node.object;
}
return false;
};
const getLeftMostCallExpression = call => {
let leftMostCallExpression = call;
let node = call;
while (node) {

@@ -150,12 +121,10 @@ if (node.type === _utils.AST_NODE_TYPES.CallExpression) {

}
if (node.type !== _utils.AST_NODE_TYPES.MemberExpression) {
break;
}
node = node.object;
}
return leftMostCallExpression;
};
/**

@@ -165,4 +134,2 @@ * Attempts to determine if the runtime value represented by the given `identifier`

*/
const isValueAwaitedOrReturned = (identifier, body, context) => {

@@ -172,3 +139,2 @@ const {

} = identifier;
for (const node of body) {

@@ -180,7 +146,5 @@ // skip all nodes that are before this identifier, because they'd probably

}
if (node.type === _utils.AST_NODE_TYPES.ReturnStatement) {
return isPromiseMethodThatUsesValue(node, identifier);
}
if (node.type === _utils.AST_NODE_TYPES.ExpressionStatement) {

@@ -192,6 +156,4 @@ // it's possible that we're awaiting the value as an argument

}
const leftMostCall = getLeftMostCallExpression(node.expression);
const jestFnCall = (0, _utils2.parseJestFnCall)(node.expression, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) === 'expect' && leftMostCall.arguments.length > 0 && (0, _utils2.isIdentifier)(leftMostCall.arguments[0], name)) {

@@ -206,12 +168,10 @@ if (jestFnCall.members.some(m => {

}
if (node.expression.type === _utils.AST_NODE_TYPES.AwaitExpression && isPromiseMethodThatUsesValue(node.expression, identifier)) {
return true;
} // (re)assignment changes the runtime value, so if we've not found an
}
// (re)assignment changes the runtime value, so if we've not found an
// await or return already we act as if we've reached the end of the body
if (node.expression.type === _utils.AST_NODE_TYPES.AssignmentExpression) {
var _getNodeName;
// unless we're assigning to the same identifier, in which case

@@ -222,7 +182,5 @@ // we might be chaining off the existing promise value

}
break;
}
}
if (node.type === _utils.AST_NODE_TYPES.BlockStatement && isValueAwaitedOrReturned(identifier, node.body, context)) {

@@ -232,9 +190,6 @@ return true;

}
return false;
};
const findFirstBlockBodyUp = node => {
let parent = node;
while (parent) {

@@ -244,39 +199,30 @@ if (parent.type === _utils.AST_NODE_TYPES.BlockStatement) {

}
parent = parent.parent;
}
/* istanbul ignore next */
throw new Error(`Could not find BlockStatement - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
};
const isDirectlyWithinTestCaseCall = (node, context) => {
let parent = node;
while (parent) {
if ((0, _utils2.isFunction)(parent)) {
var _parent;
parent = parent.parent;
return ((_parent = parent) === null || _parent === void 0 ? void 0 : _parent.type) === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isTypeOfJestFnCall)(parent, context, ['test']);
}
parent = parent.parent;
}
return false;
};
const isVariableAwaitedOrReturned = (variable, context) => {
const body = findFirstBlockBodyUp(variable);
const isVariableAwaitedOrReturned = (variable, context) => {
const body = findFirstBlockBodyUp(variable); // it's pretty much impossible for us to track destructuring assignments,
// it's pretty much impossible for us to track destructuring assignments,
// so we return true to bailout gracefully
if (!(0, _utils2.isIdentifier)(variable.id)) {
return true;
}
return isValueAwaitedOrReturned(variable.id, body, context);
};
var _default = (0, _utils2.createRule)({

@@ -297,5 +243,5 @@ name: __filename,

defaultOptions: [],
create(context) {
let inTestCaseWithDoneCallback = false; // an array of booleans representing each promise chain we enter, with the
let inTestCaseWithDoneCallback = false;
// an array of booleans representing each promise chain we enter, with the
// boolean value representing if we think a given chain contains an expect

@@ -307,3 +253,2 @@ // in it's body.

// slightly less code to assign to by not needing to know the length
const chains = [];

@@ -317,13 +262,13 @@ return {

return;
} // if this call expression is a promise chain, add it to the stack with
}
// if this call expression is a promise chain, add it to the stack with
// value of "false", as we assume there are no expect calls initially
if (isPromiseChainCall(node)) {
chains.unshift(false);
return;
} // if we're within a promise chain, and this call expression looks like
}
// if we're within a promise chain, and this call expression looks like
// an expect call, mark the deepest chain as having an expect call
if (chains.length > 0 && (0, _utils2.isTypeOfJestFnCall)(node, context, ['expect'])) {

@@ -333,3 +278,2 @@ chains[0] = true;

},
'CallExpression:exit'(node) {

@@ -343,30 +287,28 @@ // there are too many ways that the "done" argument could be used to

}
return;
}
if (!isPromiseChainCall(node)) {
return;
} // since we're exiting this call expression (which is a promise chain)
}
// since we're exiting this call expression (which is a promise chain)
// we remove it from the stack of chains, since we're unwinding
const hasExpectCall = chains.shift();
const hasExpectCall = chains.shift(); // if the promise chain we're exiting doesn't contain an expect,
// if the promise chain we're exiting doesn't contain an expect,
// then we don't need to check it for anything
if (!hasExpectCall) {
return;
}
const {
parent
} = (0, _utils2.findTopMostCallExpression)(node); // if we don't have a parent (which is technically impossible at runtime)
} = (0, _utils2.findTopMostCallExpression)(node);
// if we don't have a parent (which is technically impossible at runtime)
// or our parent is not directly within the test case, we stop checking
// because we're most likely in the body of a function being defined
// within the test, which we can't track
if (!parent || !isDirectlyWithinTestCaseCall(parent, context)) {
return;
}
switch (parent.type) {

@@ -378,6 +320,4 @@ case _utils.AST_NODE_TYPES.VariableDeclarator:

}
break;
}
case _utils.AST_NODE_TYPES.AssignmentExpression:

@@ -388,9 +328,6 @@ {

}
break;
}
case _utils.AST_NODE_TYPES.ExpressionStatement:
break;
case _utils.AST_NODE_TYPES.ReturnStatement:

@@ -401,3 +338,2 @@ case _utils.AST_NODE_TYPES.AwaitExpression:

}
context.report({

@@ -408,8 +344,5 @@ messageId: 'expectInFloatingPromise',

}
};
}
});
exports.default = _default;

@@ -7,7 +7,4 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
/*

@@ -29,21 +26,14 @@ * This implementation is ported from from eslint-plugin-jasmine.

}
if (node.type === _utils.AST_NODE_TYPES.CallExpression && node.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(node.callee.object, 'Promise') && node.parent) {
return node;
}
return null;
};
const findPromiseCallExpressionNode = node => {
var _node$parent;
return (_node$parent = node.parent) !== null && _node$parent !== void 0 && _node$parent.parent && [_utils.AST_NODE_TYPES.CallExpression, _utils.AST_NODE_TYPES.ArrayExpression].includes(node.parent.type) ? getPromiseCallExpressionNode(node.parent) : null;
};
const getParentIfThenified = node => {
var _node$parent2;
const grandParentNode = (_node$parent2 = node.parent) === null || _node$parent2 === void 0 ? void 0 : _node$parent2.parent;
if (grandParentNode && grandParentNode.type === _utils.AST_NODE_TYPES.CallExpression && grandParentNode.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(grandParentNode.callee.property) && ['then', 'catch'].includes((0, _utils2.getAccessorValue)(grandParentNode.callee.property)) && grandParentNode.parent) {

@@ -53,6 +43,4 @@ // Just in case `then`s are chained look one above.

}
return node;
};
const isAcceptableReturnNode = (node, allowReturn) => {

@@ -62,10 +50,7 @@ if (allowReturn && node.type === _utils.AST_NODE_TYPES.ReturnStatement) {

}
if (node.type === _utils.AST_NODE_TYPES.ConditionalExpression && node.parent) {
return isAcceptableReturnNode(node.parent, allowReturn);
}
return [_utils.AST_NODE_TYPES.ArrowFunctionExpression, _utils.AST_NODE_TYPES.AwaitExpression].includes(node.type);
};
const promiseArrayExceptionKey = ({

@@ -75,5 +60,3 @@ start,

}) => `${start.line}:${start.column}-${end.line}:${end.column}`;
const defaultAsyncMatchers = ['toReject', 'toResolve'];
var _default = (0, _utils2.createRule)({

@@ -128,3 +111,2 @@ name: __filename,

}],
create(context, [{

@@ -138,4 +120,4 @@ alwaysAwait,

const arrayExceptions = new Set();
const pushPromiseArrayException = loc => arrayExceptions.add(promiseArrayExceptionKey(loc));
const pushPromiseArrayException = loc => arrayExceptions.add(promiseArrayExceptionKey(loc));
/**

@@ -148,6 +130,3 @@ * Promise method that accepts an array of promises,

*/
const promiseArrayExceptionExists = loc => arrayExceptions.has(promiseArrayExceptionKey(loc));
const findTopMostMemberExpression = node => {

@@ -158,3 +137,2 @@ let topMostMemberExpression = node;

} = node;
while (parent) {

@@ -164,19 +142,13 @@ if (parent.type !== _utils.AST_NODE_TYPES.MemberExpression) {

}
topMostMemberExpression = parent;
parent = parent.parent;
}
return topMostMemberExpression;
};
return {
CallExpression(node) {
const jestFnCall = (0, _utils2.parseJestFnCallWithReason)(node, context);
if (typeof jestFnCall === 'string') {
var _node$parent3;
const reportingNode = ((_node$parent3 = node.parent) === null || _node$parent3 === void 0 ? void 0 : _node$parent3.type) === _utils.AST_NODE_TYPES.MemberExpression ? findTopMostMemberExpression(node.parent).property : node;
if (jestFnCall === 'matcher-not-found') {

@@ -189,3 +161,2 @@ context.report({

}
if (jestFnCall === 'matcher-not-called') {

@@ -197,3 +168,2 @@ context.report({

}
if (jestFnCall === 'modifier-unknown') {

@@ -206,3 +176,2 @@ context.report({

}
return;

@@ -212,11 +181,8 @@ } else if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'expect') {

}
const {
parent: expect
} = jestFnCall.head.node;
if ((expect === null || expect === void 0 ? void 0 : expect.type) !== _utils.AST_NODE_TYPES.CallExpression) {
return;
}
if (expect.arguments.length < minArgs) {

@@ -244,3 +210,2 @@ const expectLength = (0, _utils2.getAccessorValue)(jestFnCall.head.node).length;

}
if (expect.arguments.length > maxArgs) {

@@ -270,3 +235,2 @@ const {

}
const {

@@ -277,3 +241,2 @@ matcher

const shouldBeAwaited = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) !== 'not') || asyncMatchers.includes((0, _utils2.getAccessorValue)(matcher));
if (!(parentNode !== null && parentNode !== void 0 && parentNode.parent) || !shouldBeAwaited) {

@@ -286,4 +249,2 @@ return;

*/
const isParentArrayExpression = parentNode.parent.type === _utils.AST_NODE_TYPES.ArrayExpression;

@@ -296,8 +257,8 @@ const orReturned = alwaysAwait ? '' : ' or returned';

*/
const targetNode = getParentIfThenified(parentNode);
const finalNode = findPromiseCallExpressionNode(targetNode) || targetNode;
if (finalNode.parent && // If node is not awaited or returned
!isAcceptableReturnNode(finalNode.parent, !alwaysAwait) && // if we didn't warn user already
if (finalNode.parent &&
// If node is not awaited or returned
!isAcceptableReturnNode(finalNode.parent, !alwaysAwait) &&
// if we didn't warn user already
!promiseArrayExceptionExists(finalNode.loc)) {

@@ -312,3 +273,2 @@ context.report({

});
if (isParentArrayExpression) {

@@ -319,8 +279,5 @@ pushPromiseArrayException(finalNode.loc);

}
};
}
});
exports.default = _default;

@@ -7,9 +7,5 @@ "use strict";

exports.default = void 0;
var _utils = require("@typescript-eslint/utils");
var _utils2 = require("./utils");
const trimFXprefix = word => ['f', 'x'].includes(word.charAt(0)) ? word.substr(1) : word;
const doesBinaryExpressionContainStringNode = binaryExp => {

@@ -19,12 +15,8 @@ if ((0, _utils2.isStringNode)(binaryExp.right)) {

}
if (binaryExp.left.type === _utils.AST_NODE_TYPES.BinaryExpression) {
return doesBinaryExpressionContainStringNode(binaryExp.left);
}
return (0, _utils2.isStringNode)(binaryExp.left);
};
const quoteStringValue = node => node.type === _utils.AST_NODE_TYPES.TemplateLiteral ? `\`${node.quasis[0].value.raw}\`` : node.raw;
const compileMatcherPattern = matcherMaybeWithMessage => {

@@ -34,3 +26,2 @@ const [matcher, message] = Array.isArray(matcherMaybeWithMessage) ? matcherMaybeWithMessage : [matcherMaybeWithMessage];

};
const compileMatcherPatterns = matchers => {

@@ -45,3 +36,2 @@ if (typeof matchers === 'string' || Array.isArray(matchers)) {

}
return {

@@ -53,3 +43,2 @@ describe: matchers.describe ? compileMatcherPattern(matchers.describe) : null,

};
const MatcherAndMessageSchema = {

@@ -64,3 +53,2 @@ type: 'array',

};
var _default = (0, _utils2.createRule)({

@@ -125,3 +113,2 @@ name: __filename,

}],
create(context, [{

@@ -139,13 +126,9 @@ ignoreTypeOfDescribeName,

const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
if ((jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'describe' && (jestFnCall === null || jestFnCall === void 0 ? void 0 : jestFnCall.type) !== 'test') {
return;
}
const [argument] = node.arguments;
if (!argument) {
return;
}
if (!(0, _utils2.isStringNode)(argument)) {

@@ -155,3 +138,2 @@ if (argument.type === _utils.AST_NODE_TYPES.BinaryExpression && doesBinaryExpressionContainStringNode(argument)) {

}
if (argument.type !== _utils.AST_NODE_TYPES.TemplateLiteral && !(ignoreTypeOfDescribeName && jestFnCall.type === 'describe')) {

@@ -163,8 +145,5 @@ context.report({

}
return;
}
const title = (0, _utils2.getStringValue)(argument);
if (!title) {

@@ -180,6 +159,4 @@ context.report({

}
if (disallowedWords.length > 0) {
const disallowedMatch = disallowedWordsRegexp.exec(title);
if (disallowedMatch) {

@@ -196,3 +173,2 @@ context.report({

}
if (title.trim().length !== title.length) {

@@ -205,6 +181,4 @@ context.report({

}
const unprefixedName = trimFXprefix(jestFnCall.name);
const [firstWord] = title.split(' ');
if (firstWord.toLowerCase() === unprefixedName) {

@@ -217,6 +191,4 @@ context.report({

}
const jestFunctionName = unprefixedName;
const [mustNotMatchPattern, mustNotMatchMessage] = mustNotMatchPatterns[jestFunctionName] ?? [];
if (mustNotMatchPattern) {

@@ -236,5 +208,3 @@ if (mustNotMatchPattern.test(title)) {

}
const [mustMatchPattern, mustMatchMessage] = mustMatchPatterns[jestFunctionName] ?? [];
if (mustMatchPattern) {

@@ -255,8 +225,5 @@ if (!mustMatchPattern.test(title)) {

}
};
}
});
exports.default = _default;
{
"name": "eslint-plugin-jest",
"version": "27.1.2",
"version": "27.1.3",
"description": "ESLint rules for Jest",

@@ -5,0 +5,0 @@ "keywords": [

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc