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 21.24.1 to 21.24.2

2

package.json
{
"name": "eslint-plugin-jest",
"version": "21.24.1",
"version": "21.24.2",
"description": "Eslint rules for Jest",

@@ -5,0 +5,0 @@ "repository": "jest-community/eslint-plugin-jest",

@@ -26,2 +26,10 @@ 'use strict';

},
{
code: [
'test("verifies the function call", () => {',
' td.verify(someFunctionCall())',
'})',
].join('\n'),
options: [{ assertFunctionNames: ['td.verify'] }],
},
],

@@ -28,0 +36,0 @@

@@ -9,2 +9,3 @@ 'use strict';

const getDocsUrl = require('./util').getDocsUrl;
const getNodeName = require('./util').getNodeName;

@@ -30,41 +31,24 @@ module.exports = {

create(context) {
// variables should be defined here
const unchecked = [];
const assertFunctionNames =
const assertFunctionNames = new Set(
context.options[0] && context.options[0].assertFunctionNames
? context.options[0].assertFunctionNames
: ['expect'];
: ['expect']
);
//----------------------------------------------------------------------
// Helpers
//----------------------------------------------------------------------
const isExpectCall = node =>
// if we're not calling a function, ignore
node.type === 'CallExpression' &&
// if we're not calling allowed assertion
assertFunctionNames.some(name => name === node.callee.name);
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
return {
// give me methods
CallExpression(node) {
// keep track of `it` calls
if (['it', 'test'].indexOf(node.callee.name) > -1) {
const name = getNodeName(node.callee);
if (name === 'it' || name === 'test') {
unchecked.push(node);
return;
} else if (assertFunctionNames.has(name)) {
// Return early in case of nested `it` statements.
for (const ancestor of context.getAncestors()) {
const index = unchecked.indexOf(ancestor);
if (index !== -1) {
unchecked.splice(index, 1);
break;
}
}
}
if (!isExpectCall(node)) {
return;
}
// here, we do have a call to expect
// use `some` to return early (in case of nested `it`s
context.getAncestors().some(ancestor => {
const index = unchecked.indexOf(ancestor);
if (index !== -1) {
unchecked.splice(index, 1);
return true;
}
return false;
});
},

@@ -71,0 +55,0 @@ 'Program:exit'() {

'use strict';
const getDocsUrl = require('./util').getDocsUrl;
const getNodeName = require('./util').getNodeName;
function getName(node) {
function joinNames(a, b) {
return a && b ? `${a}.${b}` : null;
}
switch (node && node.type) {
case 'Identifier':
return node.name;
case 'Literal':
return node.value;
case 'MemberExpression':
return joinNames(getName(node.object), getName(node.property));
}
return null;
}
function collectReferences(scope) {

@@ -60,10 +44,18 @@ const locals = new Set();

return {
'CallExpression[callee.name="describe"]'() {
suiteDepth++;
},
'CallExpression[callee.name=/^it|test$/]'() {
testDepth++;
},
'CallExpression[callee.name=/^it|test$/][arguments.length<2]'(node) {
context.report({
message: 'Test is missing function argument',
node,
});
},
CallExpression(node) {
const functionName = getName(node.callee);
const functionName = getNodeName(node.callee);
switch (functionName) {
case 'describe':
suiteDepth++;
break;
case 'describe.skip':

@@ -73,13 +65,2 @@ context.report({ message: 'Skipped test suite', node });

case 'it':
case 'test':
testDepth++;
if (node.arguments.length < 2) {
context.report({
message: 'Test is missing function argument',
node,
});
}
break;
case 'it.skip':

@@ -89,62 +70,48 @@ case 'test.skip':

break;
case 'pending': {
const references = collectReferences(context.getScope());
if (
// `pending` was found as a local variable or function declaration.
references.locals.has('pending') ||
// `pending` was not found as an unresolved reference,
// meaning it is likely not an implicit global reference.
!references.unresolved.has('pending')
) {
break;
}
if (testDepth > 0) {
context.report({
message: 'Call to pending() within test',
node,
});
} else if (suiteDepth > 0) {
context.report({
message: 'Call to pending() within test suite',
node,
});
} else {
context.report({
message: 'Call to pending()',
node,
});
}
break;
}
case 'xdescribe':
context.report({ message: 'Disabled test suite', node });
break;
case 'xit':
case 'xtest':
context.report({ message: 'Disabled test', node });
break;
}
},
'CallExpression[callee.name="pending"]'(node) {
const references = collectReferences(context.getScope());
'CallExpression:exit'(node) {
const functionName = getName(node.callee);
if (
// `pending` was found as a local variable or function declaration.
references.locals.has('pending') ||
// `pending` was not found as an unresolved reference,
// meaning it is likely not an implicit global reference.
!references.unresolved.has('pending')
) {
return;
}
switch (functionName) {
case 'describe':
suiteDepth--;
break;
case 'it':
case 'test':
testDepth--;
break;
if (testDepth > 0) {
context.report({
message: 'Call to pending() within test',
node,
});
} else if (suiteDepth > 0) {
context.report({
message: 'Call to pending() within test suite',
node,
});
} else {
context.report({
message: 'Call to pending()',
node,
});
}
},
'CallExpression[callee.name="xdescribe"]'(node) {
context.report({ message: 'Disabled test suite', node });
},
'CallExpression[callee.name=/^xit|xtest$/]'(node) {
context.report({ message: 'Disabled test', node });
},
'CallExpression[callee.name="describe"]:exit'() {
suiteDepth--;
},
'CallExpression[callee.name=/^it|test$/]:exit'() {
testDepth--;
},
};
},
};

@@ -34,10 +34,2 @@ 'use strict';

const isTestOrItFunction = node => {
return (
node.type === 'CallExpression' &&
node.callee &&
(node.callee.name === 'it' || node.callee.name === 'test')
);
};
const getFunctionFirstLine = functionBody => {

@@ -51,10 +43,2 @@ return functionBody[0] && functionBody[0].expression;

const getTestFunctionBody = node => {
try {
return node.arguments[1].body.body;
} catch (e) {
return undefined;
}
};
const reportMsg = (context, node) => {

@@ -75,14 +59,11 @@ context.report({

return {
CallExpression(node) {
if (isTestOrItFunction(node)) {
const testFuncBody = getTestFunctionBody(node);
if (testFuncBody) {
if (!isFirstLineExprStmt(testFuncBody)) {
reportMsg(context, node);
} else {
const testFuncFirstLine = getFunctionFirstLine(testFuncBody);
if (!isExpectAssertionsOrHasAssertionsCall(testFuncFirstLine)) {
reportMsg(context, node);
}
}
'CallExpression[callee.name=/^it|test$/][arguments.1.body.body]'(node) {
const testFuncBody = node.arguments[1].body.body;
if (!isFirstLineExprStmt(testFuncBody)) {
reportMsg(context, node);
} else {
const testFuncFirstLine = getFunctionFirstLine(testFuncBody);
if (!isExpectAssertionsOrHasAssertionsCall(testFuncFirstLine)) {
reportMsg(context, node);
}

@@ -89,0 +70,0 @@ }

@@ -101,6 +101,16 @@ 'use strict';

const getNodeName = node => {
if (node.type === 'MemberExpression') {
return `${node.object.name}.${node.property.name}`;
function joinNames(a, b) {
return a && b ? `${a}.${b}` : null;
}
return node.name;
switch (node && node.type) {
case 'Identifier':
return node.name;
case 'Literal':
return node.value;
case 'MemberExpression':
return joinNames(getNodeName(node.object), getNodeName(node.property));
}
return null;
};

@@ -107,0 +117,0 @@

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