Socket
Socket
Sign inDemoInstall

eslint-plugin-jest

Package Overview
Dependencies
Maintainers
10
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 23.13.2 to 23.14.0

14

CHANGELOG.md

@@ -0,1 +1,15 @@

# [23.14.0](https://github.com/jest-community/eslint-plugin-jest/compare/v23.13.2...v23.14.0) (2020-06-20)
### Bug Fixes
* **no-test-callback:** check argument is an identifier ([f70612d](https://github.com/jest-community/eslint-plugin-jest/commit/f70612d8b414575725a5831ed9dfad1eaf1e6548))
* **no-test-callback:** provide suggestion instead of autofix ([782d8fa](https://github.com/jest-community/eslint-plugin-jest/commit/782d8fa00149143f453e7cb066f90c017e2d3f61))
* **prefer-strict-equal:** provide suggestion instead of autofix ([2eaed2b](https://github.com/jest-community/eslint-plugin-jest/commit/2eaed2bf30c72b03ee205910887f8aab304047a5))
### Features
* **prefer-expect-assertions:** provide suggestions ([bad88a0](https://github.com/jest-community/eslint-plugin-jest/commit/bad88a006135258e8da18902a84bdb52a9bb9fa7))
## [23.13.2](https://github.com/jest-community/eslint-plugin-jest/compare/v23.13.1...v23.13.2) (2020-05-26)

@@ -2,0 +16,0 @@

2

lib/rules/no-focused-tests.js

@@ -15,3 +15,3 @@ "use strict";

const isConcurrentExpression = expression => expression.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && (0, _utils.isSupportedAccessor)(expression.property, _utils.TestCaseProperty.concurrent) && !!expression.parent && expression.parent.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression;
const isConcurrentExpression = expression => (0, _utils.isSupportedAccessor)(expression.property, _utils.TestCaseProperty.concurrent) && !!expression.parent && expression.parent.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression;

@@ -18,0 +18,0 @@ const matchesTestFunction = object => 'name' in object && (object.name in _utils.TestCaseName || object.name in _utils.DescribeAlias);

@@ -35,3 +35,3 @@ "use strict";

if (whitelistedSnapshots && node.type === _experimentalUtils.AST_NODE_TYPES.ExpressionStatement && 'left' in node.expression && (0, _utils.isExpectMember)(node.expression.left)) {
if (node.type === _experimentalUtils.AST_NODE_TYPES.ExpressionStatement && 'left' in node.expression && (0, _utils.isExpectMember)(node.expression.left)) {
const fileName = context.getFilename();

@@ -38,0 +38,0 @@ const whitelistedSnapshotsInFile = whitelistedSnapshots[fileName];

@@ -37,3 +37,3 @@ "use strict";

ImportDeclaration(node) {
if (node.source && isMockImportLiteral(node.source)) {
if (isMockImportLiteral(node.source)) {
context.report({

@@ -40,0 +40,0 @@ node,

@@ -18,9 +18,10 @@ "use strict";

description: 'Avoid using a callback in asynchronous tests',
recommended: false
recommended: false,
suggestion: true
},
messages: {
illegalTestCallback: 'Illegal usage of test callback',
suggestWrappingInPromise: 'Wrap in `new Promise({{ callback }} => ...`',
useAwaitInsteadOfCallback: 'Use await instead of callback in async functions'
},
fixable: 'code',
schema: [],

@@ -46,2 +47,10 @@ type: 'suggestion'

if (argument.type !== _experimentalUtils.AST_NODE_TYPES.Identifier) {
context.report({
node: argument,
messageId: 'illegalTestCallback'
});
return;
}
if (callback.async) {

@@ -58,51 +67,57 @@ context.report({

messageId: 'illegalTestCallback',
suggest: [{
messageId: 'suggestWrappingInPromise',
data: {
callback: argument.name
},
fix(fixer) {
const {
body
} = callback;
/* istanbul ignore if https://github.com/typescript-eslint/typescript-eslint/issues/734 */
fix(fixer) {
const {
body
} = callback;
/* istanbul ignore if https://github.com/typescript-eslint/typescript-eslint/issues/734 */
if (!body) {
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`);
}
if (!body) {
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 sourceCode = context.getSourceCode();
const firstBodyToken = sourceCode.getFirstToken(body);
const lastBodyToken = sourceCode.getLastToken(body);
const tokenBeforeArgument = sourceCode.getTokenBefore(argument);
const tokenAfterArgument = sourceCode.getTokenAfter(argument);
/* istanbul ignore if */
const sourceCode = context.getSourceCode();
const firstBodyToken = sourceCode.getFirstToken(body);
const lastBodyToken = sourceCode.getLastToken(body);
const tokenBeforeArgument = sourceCode.getTokenBefore(argument);
const tokenAfterArgument = sourceCode.getTokenAfter(argument);
/* istanbul ignore if */
if (!('name' in argument) || !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`);
}
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, '()');
const argumentInParens = tokenBeforeArgument.value === '(' && tokenAfterArgument.value === ')';
let argumentFix = fixer.replaceText(argument, '()');
if (argumentInParens) {
argumentFix = fixer.remove(argument);
}
if (argumentInParens) {
argumentFix = fixer.remove(argument);
}
let newCallback = argument.name;
let newCallback = argument.name;
if (argumentInParens) {
newCallback = `(${newCallback})`;
}
if (argumentInParens) {
newCallback = `(${newCallback})`;
}
let beforeReplacement = `new Promise(${newCallback} => `;
let afterReplacement = ')';
let replaceBefore = true;
let beforeReplacement = `new Promise(${newCallback} => `;
let afterReplacement = ')';
let replaceBefore = true;
if (body.type === _experimentalUtils.AST_NODE_TYPES.BlockStatement) {
const keyword = 'return';
beforeReplacement = `${keyword} ${beforeReplacement}{`;
afterReplacement += '}';
replaceBefore = false;
if (body.type === _experimentalUtils.AST_NODE_TYPES.BlockStatement) {
const keyword = 'return';
beforeReplacement = `${keyword} ${beforeReplacement}{`;
afterReplacement += '}';
replaceBefore = false;
}
return [argumentFix, replaceBefore ? fixer.insertTextBefore(firstBodyToken, beforeReplacement) : fixer.insertTextAfter(firstBodyToken, beforeReplacement), fixer.insertTextAfter(lastBodyToken, afterReplacement)];
}
return [argumentFix, replaceBefore ? fixer.insertTextBefore(firstBodyToken, beforeReplacement) : fixer.insertTextAfter(firstBodyToken, beforeReplacement), fixer.insertTextAfter(lastBodyToken, afterReplacement)];
}
}]
});

@@ -109,0 +124,0 @@ }

@@ -12,21 +12,13 @@ "use strict";

const isExpectAssertionsOrHasAssertionsCall = expression => {
if (expression.type !== _experimentalUtils.AST_NODE_TYPES.CallExpression || expression.callee.type !== _experimentalUtils.AST_NODE_TYPES.MemberExpression || !(0, _utils.isSupportedAccessor)(expression.callee.object, 'expect') || !(0, _utils.isSupportedAccessor)(expression.callee.property)) {
return false;
}
const isExpectAssertionsOrHasAssertionsCall = expression => expression.type === _experimentalUtils.AST_NODE_TYPES.CallExpression && expression.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && (0, _utils.isSupportedAccessor)(expression.callee.object, 'expect') && (0, _utils.isSupportedAccessor)(expression.callee.property) && ['assertions', 'hasAssertions'].includes((0, _utils.getAccessorValue)(expression.callee.property));
const expectAssertionName = (0, _utils.getAccessorValue)(expression.callee.property);
const isFirstLineExprStmt = functionBody => functionBody[0] && functionBody[0].type === _experimentalUtils.AST_NODE_TYPES.ExpressionStatement;
if (expectAssertionName !== 'assertions') {
return expectAssertionName === 'hasAssertions';
}
const suggestRemovingExtraArguments = (args, extraArgsStartAt) => ({
messageId: 'suggestRemovingExtraArguments',
fix: fixer => fixer.removeRange([args[extraArgsStartAt].range[0] - Math.sign(extraArgsStartAt), args[args.length - 1].range[1]])
});
const [arg] = expression.arguments;
return (0, _utils.hasOnlyOneArgument)(expression) && arg.type === _experimentalUtils.AST_NODE_TYPES.Literal && typeof arg.value === 'number' && Number.isInteger(arg.value);
};
const suggestions = [['suggestAddingHasAssertions', 'expect.hasAssertions();'], ['suggestAddingAssertions', 'expect.assertions();']];
const getFunctionFirstLine = functionBody => functionBody[0] && functionBody[0].expression;
const isFirstLineExprStmt = functionBody => functionBody[0] && functionBody[0].type === _experimentalUtils.AST_NODE_TYPES.ExpressionStatement;
var _default = (0, _utils.createRule)({

@@ -38,6 +30,13 @@ name: __filename,

description: 'Suggest using `expect.assertions()` OR `expect.hasAssertions()`',
recommended: false
recommended: false,
suggestion: true
},
messages: {
haveExpectAssertions: 'Every test should have either `expect.assertions(<number of assertions>)` or `expect.hasAssertions()` as its first expression'
hasAssertionsTakesNoArguments: '`expect.hasAssertions` expects no arguments',
assertionsRequiresOneArgument: '`expect.assertions` excepts a single argument of type number',
assertionsRequiresNumberArgument: 'This argument should be a number',
haveExpectAssertions: 'Every test should have either `expect.assertions(<number of assertions>)` or `expect.hasAssertions()` as its first expression',
suggestAddingHasAssertions: 'Add `expect.hasAssertions()`',
suggestAddingAssertions: 'Add `expect.assertions(<number of assertions>)`',
suggestRemovingExtraArguments: 'Remove extra arguments'
},

@@ -57,3 +56,7 @@ type: 'suggestion',

messageId: 'haveExpectAssertions',
node
node,
suggest: suggestions.map(([messageId, text]) => ({
messageId,
fix: fixer => fixer.insertTextBeforeRange([node.arguments[1].body.range[0] + 1, node.arguments[1].body.range[1]], text)
}))
});

@@ -63,3 +66,3 @@ return;

const testFuncFirstLine = getFunctionFirstLine(testFuncBody);
const testFuncFirstLine = testFuncBody[0].expression;

@@ -69,5 +72,48 @@ if (!isExpectAssertionsOrHasAssertionsCall(testFuncFirstLine)) {

messageId: 'haveExpectAssertions',
node
node,
suggest: suggestions.map(([messageId, text]) => ({
messageId,
fix: fixer => fixer.insertTextBefore(testFuncBody[0], text)
}))
});
return;
}
if ((0, _utils.isSupportedAccessor)(testFuncFirstLine.callee.property, 'hasAssertions')) {
if (testFuncFirstLine.arguments.length) {
context.report({
messageId: 'hasAssertionsTakesNoArguments',
node: testFuncFirstLine.callee.property,
suggest: [suggestRemovingExtraArguments(testFuncFirstLine.arguments, 0)]
});
}
return;
}
if (!(0, _utils.hasOnlyOneArgument)(testFuncFirstLine)) {
const report = {
messageId: 'assertionsRequiresOneArgument',
loc: testFuncFirstLine.callee.property.loc
};
if (testFuncFirstLine.arguments.length) {
report.loc = testFuncFirstLine.arguments[1].loc;
report.suggest = [suggestRemovingExtraArguments(testFuncFirstLine.arguments, 1)];
}
context.report(report);
return;
}
const [arg] = testFuncFirstLine.arguments;
if (arg.type === _experimentalUtils.AST_NODE_TYPES.Literal && typeof arg.value === 'number' && Number.isInteger(arg.value)) {
return;
}
context.report({
messageId: 'assertionsRequiresNumberArgument',
node: arg
});
}

@@ -74,0 +120,0 @@

@@ -16,8 +16,9 @@ "use strict";

description: 'Suggest using toStrictEqual()',
recommended: false
recommended: false,
suggestion: true
},
messages: {
useToStrictEqual: 'Use toStrictEqual() instead'
useToStrictEqual: 'Use `toStrictEqual()` instead',
suggestReplaceWithStrictEqual: 'Replace with `toStrictEqual()`'
},
fixable: 'code',
type: 'suggestion',

@@ -41,5 +42,8 @@ schema: []

context.report({
fix: fixer => [fixer.replaceText(matcher.node.property, _utils.EqualityMatcher.toStrictEqual)],
messageId: 'useToStrictEqual',
node: matcher.node.property
node: matcher.node.property,
suggest: [{
messageId: 'suggestReplaceWithStrictEqual',
fix: fixer => [fixer.replaceText(matcher.node.property, _utils.EqualityMatcher.toStrictEqual)]
}]
});

@@ -46,0 +50,0 @@ }

@@ -125,3 +125,3 @@ "use strict";

if (modifier && modifier.name === _utils.ModifierName.not) {
if (modifier) {
return getNegationFixes(includesCall, modifier, matcher, sourceCode, fixer, fileName).concat(fixArr);

@@ -128,0 +128,0 @@ }

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

* @param {Node} node
* @param {V?} value
* @param {V} [value]
*
* @return {node is StringLiteral<V>}
*
* @template {V}.
* @template V
*/

@@ -65,3 +65,3 @@ const isStringLiteral = (node, value) => node.type === _experimentalUtils.AST_NODE_TYPES.Literal && typeof node.value === 'string' && (value === undefined || node.value === value);

* @param {Node} node
* @param {V?} value
* @param {V} [value]
*

@@ -79,3 +79,3 @@ * @return {node is TemplateLiteral<V>}

* @param {Node} node
* @param {V?} specifics
* @param {V} [specifics]
*

@@ -118,3 +118,3 @@ * @return {node is StringNode}

*/
const hasOnlyOneArgument = call => call.arguments && call.arguments.length === 1;
const hasOnlyOneArgument = call => call.arguments.length === 1;
/**

@@ -134,3 +134,3 @@ * An `Identifier` with a known `name` value - i.e `expect`.

* @param {Node} node
* @param {V?} name
* @param {V} [name]
*

@@ -158,3 +158,3 @@ * @return {node is KnownIdentifier<Name>}

* @param {Node} node
* @param {V?} value
* @param {V} [value]
*

@@ -161,0 +161,0 @@ * @return {node is AccessorNode<V>}

@@ -25,3 +25,3 @@ "use strict";

const getPromiseCallExpressionNode = node => {
if (node && node.type === _experimentalUtils.AST_NODE_TYPES.ArrayExpression && node.parent && node.parent.type === _experimentalUtils.AST_NODE_TYPES.CallExpression) {
if (node.type === _experimentalUtils.AST_NODE_TYPES.ArrayExpression && node.parent && node.parent.type === _experimentalUtils.AST_NODE_TYPES.CallExpression) {
node = node.parent;

@@ -28,0 +28,0 @@ }

{
"name": "eslint-plugin-jest",
"version": "23.13.2",
"version": "23.14.0",
"description": "Eslint rules for Jest",

@@ -102,2 +102,3 @@ "keywords": [

"@semantic-release/git": "^7.0.17",
"@types/dedent": "^0.7.0",
"@types/eslint": "^6.1.3",

@@ -110,5 +111,7 @@ "@types/jest": "^25.1.0",

"babel-plugin-replace-ts-export-assignment": "^0.0.2",
"dedent": "^0.7.0",
"eslint": "^5.1.0 || ^6.0.0",
"eslint-config-prettier": "^6.5.0",
"eslint-plugin-eslint-comments": "^3.1.2",
"eslint-plugin-eslint-config": "^1.0.2",
"eslint-plugin-eslint-plugin": "^2.0.0",

@@ -115,0 +118,0 @@ "eslint-plugin-import": "^2.20.2",

@@ -151,3 +151,3 @@ <div align="center">

| [no-standalone-expect](docs/rules/no-standalone-expect.md) | Prevents expects that are outside of an it or test block. | ![recommended][] | |
| [no-test-callback](docs/rules/no-test-callback.md) | Avoid using a callback in asynchronous tests | ![recommended][] | ![fixable][] |
| [no-test-callback](docs/rules/no-test-callback.md) | Avoid using a callback in asynchronous tests | ![recommended][] | ![suggest][] |
| [no-test-prefixes](docs/rules/no-test-prefixes.md) | Use `.only` and `.skip` over `f` and `x` | ![recommended][] | ![fixable][] |

@@ -157,6 +157,6 @@ | [no-test-return-statement](docs/rules/no-test-return-statement.md) | Disallow explicitly returning from tests | | |

| [prefer-called-with](docs/rules/prefer-called-with.md) | Suggest using `toBeCalledWith()` OR `toHaveBeenCalledWith()` | | |
| [prefer-expect-assertions](docs/rules/prefer-expect-assertions.md) | Suggest using `expect.assertions()` OR `expect.hasAssertions()` | | |
| [prefer-expect-assertions](docs/rules/prefer-expect-assertions.md) | Suggest using `expect.assertions()` OR `expect.hasAssertions()` | | ![suggest][] |
| [prefer-hooks-on-top](docs/rules/prefer-hooks-on-top.md) | Suggest to have all hooks at top level | | |
| [prefer-spy-on](docs/rules/prefer-spy-on.md) | Suggest using `jest.spyOn()` | | ![fixable][] |
| [prefer-strict-equal](docs/rules/prefer-strict-equal.md) | Suggest using toStrictEqual() | | ![fixable][] |
| [prefer-strict-equal](docs/rules/prefer-strict-equal.md) | Suggest using toStrictEqual() | | ![suggest][] |
| [prefer-to-be-null](docs/rules/prefer-to-be-null.md) | Suggest using `toBeNull()` | ![style][] | ![fixable][] |

@@ -191,3 +191,4 @@ | [prefer-to-be-undefined](docs/rules/prefer-to-be-undefined.md) | Suggest using `toBeUndefined()` | ![style][] | ![fixable][] |

[recommended]: https://img.shields.io/badge/-recommended-lightgrey.svg
[suggest]: https://img.shields.io/badge/-suggest-yellow.svg
[fixable]: https://img.shields.io/badge/-fixable-green.svg
[style]: https://img.shields.io/badge/-style-blue.svg
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