Socket
Socket
Sign inDemoInstall

eslint-plugin-jest-dom

Package Overview
Dependencies
4
Maintainers
1
Versions
60
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.3.0 to 3.4.0

10

dist/queries.js

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

});
exports.queriesByVariant = exports.queries = void 0;
exports.queries = void 0;

@@ -12,8 +12,2 @@ var _dom = require("@testing-library/dom");

const queries = Object.keys(_dom.queries);
exports.queries = queries;
const queriesByVariant = {
query: queries.filter(q => q.startsWith("query")),
get: queries.filter(q => q.startsWith("get")),
find: queries.filter(q => q.startsWith("find"))
};
exports.queriesByVariant = queriesByVariant;
exports.queries = queries;

141

dist/rules/prefer-in-document.js

@@ -33,57 +33,116 @@ "use strict";

function check(context, {
queryNode,
matcherNode,
matcherArguments,
negatedMatcher
}) {
const query = queryNode.name || queryNode.property.name; // toHaveLength() is only invalid with 0 or 1
const create = context => {
const alternativeMatchers = /(toHaveLength|toBeDefined|toBeNull)/;
if (matcherNode.name === "toHaveLength" && matcherArguments[0].value > 1) {
return;
}
function check({
queryNode,
matcherNode,
matcherArguments,
negatedMatcher,
expect
}) {
if (!queryNode || !queryNode.name && !queryNode.property) return; // toHaveLength() is only invalid with 0 or 1
if (_queries.queries.includes(query)) {
context.report({
node: matcherNode,
messageId: "use-document",
loc: matcherNode.loc,
if (matcherNode.name === "toHaveLength" && matcherArguments[0].value > 1) {
return;
}
fix(fixer) {
const operations = []; // Flip the .not if neccessary
const query = queryNode.name || queryNode.property.name;
if (isAntonymMatcher(matcherNode, matcherArguments)) {
if (negatedMatcher) {
operations.push(fixer.removeRange([matcherNode.range[0] - 5, matcherNode.range[0] - 1]));
} else {
operations.push(fixer.insertTextBefore(matcherNode, "not."));
}
} // Replace the actual matcher
if (_queries.queries.includes(query)) {
context.report({
node: matcherNode,
messageId: "use-document",
loc: matcherNode.loc,
fix(fixer) {
const operations = []; // Remove any arguments in the matcher
operations.push(fixer.replaceText(matcherNode, "toBeInTheDocument")); // Remove any arguments in the matcher
for (const argument of Array.from(matcherArguments)) {
operations.push(fixer.remove(argument));
} // Flip the .not if necessary
for (const argument of matcherArguments) {
operations.push(fixer.remove(argument));
if (isAntonymMatcher(matcherNode, matcherArguments)) {
if (negatedMatcher) {
operations.push(fixer.replaceTextRange([expect.range[1], matcherNode.range[1]], ".toBeInTheDocument"));
return operations;
} else {
operations.push(fixer.insertTextBefore(matcherNode, "not."));
}
} // Replace the actual matcher
operations.push(fixer.replaceText(matcherNode, "toBeInTheDocument"));
return operations;
}
return operations;
});
}
}
function getQueryNodeFromAssignment(identifierName) {
const variable = context.getScope().set.get(identifierName);
const init = variable.defs[0].node.init;
let queryNode;
if (init) {
// let foo = screen.<query>();
queryNode = init.type === "AwaitExpression" ? init.argument.callee.property : init.callee.property || init.callee;
} else {
// let foo;
// foo = screen.<query>();
const assignmentRef = variable.references.reverse().find(ref => !!ref.writeExpr);
if (!assignmentRef) {
return;
}
});
queryNode = assignmentRef.writeExpr.type === "AwaitExpression" ? assignmentRef.writeExpr.argument.callee : assignmentRef.writeExpr.type === "CallExpression" ? assignmentRef.writeExpr.callee : assignmentRef.writeExpr;
}
return queryNode;
}
}
const create = context => {
const alternativeMatchers = /(toHaveLength|toBeDefined|toBeNull)/;
return {
// Grabbing expect(<query>).not.<matcher>
[`CallExpression[callee.object.object.callee.name='expect'][callee.object.property.name='not'][callee.property.name=${alternativeMatchers}]`](node) {
const queryNode = node.callee.object.object.arguments[0].callee;
// expect(<query>).not.<matcher>
[`CallExpression[callee.object.object.callee.name='expect'][callee.object.property.name='not'][callee.property.name=${alternativeMatchers}], CallExpression[callee.object.callee.name='expect'][callee.object.property.name='not'][callee.object.arguments.0.argument.callee.name=${alternativeMatchers}]`](node) {
const arg = node.callee.object.object.arguments[0];
const queryNode = arg.type === "AwaitExpression" ? arg.argument.callee : arg.callee;
const matcherNode = node.callee.property;
const matcherArguments = node.arguments;
check(context, {
const expect = node.callee.object.object;
check({
negatedMatcher: true,
queryNode,
matcherNode,
matcherArguments,
expect
});
},
// // const foo = <query> expect(foo).not.<matcher>
[`MemberExpression[object.object.callee.name=expect][object.property.name=not][property.name=${alternativeMatchers}][object.object.arguments.0.type=Identifier]`](node) {
const queryNode = getQueryNodeFromAssignment(node.object.object.arguments[0].name);
const matcherNode = node.property;
const matcherArguments = node.parent.arguments;
const expect = node.object.object;
check({
negatedMatcher: true,
queryNode,
matcherNode,
matcherArguments,
expect
});
},
// const foo = <query> expect(foo).<matcher>
[`MemberExpression[object.callee.name=expect][property.name=${alternativeMatchers}][object.arguments.0.type=Identifier]`](node) {
const queryNode = getQueryNodeFromAssignment(node.object.arguments[0].name);
const matcherNode = node.property;
const matcherArguments = node.parent.arguments;
check({
negatedMatcher: false,
queryNode,
matcherNode,
matcherArguments

@@ -93,8 +152,10 @@ });

// Grabbing expect(<query>).<matcher>
[`CallExpression[callee.object.callee.name='expect'][callee.property.name=${alternativeMatchers}]`](node) {
const queryNode = node.callee.object.arguments[0].callee;
// expect(await <query>).<matcher>
// expect(<query>).<matcher>
[`CallExpression[callee.object.callee.name='expect'][callee.property.name=${alternativeMatchers}], CallExpression[callee.object.callee.name='expect'][callee.object.arguments.0.argument.callee.name=${alternativeMatchers}]`](node) {
const arg = node.callee.object.arguments[0];
const queryNode = arg.type === "AwaitExpression" ? arg.argument.callee : arg.callee;
const matcherNode = node.callee.property;
const matcherArguments = node.arguments;
check(context, {
check({
negatedMatcher: false,

@@ -101,0 +162,0 @@ queryNode,

{
"name": "eslint-plugin-jest-dom",
"version": "3.3.0",
"version": "3.4.0",
"description": "ESLint plugin to follow best practices and anticipate common mistakes when writing tests with jest-dom",

@@ -37,2 +37,3 @@ "main": "dist/index.js",

"test": "kcd-scripts test",
"test:smoke": "eslint-remote-tester --config ./smoke-test/eslint-remote-tester.config.js",
"test:update": "npm test -- --updateSnapshot --coverage",

@@ -47,5 +48,8 @@ "validate": "kcd-scripts validate"

"devDependencies": {
"@typescript-eslint/parser": "^4.8.2",
"eslint": "7.14",
"eslint-remote-tester": "^0.3.3",
"jest-extended": "^0.11.5",
"kcd-scripts": "6.5.1"
"kcd-scripts": "6.5.1",
"typescript": "^4.1.2"
},

@@ -60,3 +64,4 @@ "peerDependencies": {

"max-lines-per-function": "off",
"testing-library/no-dom-import": "off"
"testing-library/no-dom-import": "off",
"consistent-return": "off"
}

@@ -67,3 +72,5 @@ },

"coverage",
"dist"
"dist",
".cache-eslint-remote-tester",
"eslint-remote-tester-results"
],

@@ -70,0 +77,0 @@ "engines": {

@@ -103,13 +103,15 @@ <div align="center">

<!-- __BEGIN AUTOGENERATED TABLE__ -->
Name | πŸ‘ | πŸ”§ | Description
----- | ----- | ----- | -----
[prefer-checked](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-checked.md) | πŸ‘ | πŸ”§ | prefer toBeChecked over checking attributes
[prefer-empty](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-empty.md) | πŸ‘ | πŸ”§ | Prefer toBeEmpty over checking innerHTML
[prefer-enabled-disabled](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-enabled-disabled.md) | πŸ‘ | πŸ”§ | prefer toBeDisabled or toBeEnabled over checking attributes
[prefer-focus](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-focus.md) | πŸ‘ | πŸ”§ | prefer toHaveFocus over checking document.activeElement
[prefer-in-document](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-in-document.md) | | πŸ”§ | Prefer .toBeInTheDocument() in favor of checking the length of the result using .toHaveLength(1)
[prefer-required](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-required.md) | πŸ‘ | πŸ”§ | prefer toBeRequired over checking properties
[prefer-to-have-attribute](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-to-have-attribute.md) | πŸ‘ | πŸ”§ | prefer toHaveAttribute over checking getAttribute/hasAttribute
[prefer-to-have-style](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-to-have-style.md) | πŸ‘ | πŸ”§ | prefer toHaveStyle over checking element style
[prefer-to-have-text-content](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-to-have-text-content.md) | πŸ‘ | πŸ”§ | Prefer toHaveTextContent over checking element.textContent
| Name | πŸ‘ | πŸ”§ | Description |
| ---------------------------------------------------------------------------------------------------------------------------------------------- | --- | --- | ------------------------------------------------------------------------------------------------ |
| [prefer-checked](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-checked.md) | πŸ‘ | πŸ”§ | prefer toBeChecked over checking attributes |
| [prefer-empty](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-empty.md) | πŸ‘ | πŸ”§ | Prefer toBeEmpty over checking innerHTML |
| [prefer-enabled-disabled](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-enabled-disabled.md) | πŸ‘ | πŸ”§ | prefer toBeDisabled or toBeEnabled over checking attributes |
| [prefer-focus](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-focus.md) | πŸ‘ | πŸ”§ | prefer toHaveFocus over checking document.activeElement |
| [prefer-in-document](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-in-document.md) | | πŸ”§ | Prefer .toBeInTheDocument() in favor of checking the length of the result using .toHaveLength(1) |
| [prefer-required](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-required.md) | πŸ‘ | πŸ”§ | prefer toBeRequired over checking properties |
| [prefer-to-have-attribute](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-to-have-attribute.md) | πŸ‘ | πŸ”§ | prefer toHaveAttribute over checking getAttribute/hasAttribute |
| [prefer-to-have-style](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-to-have-style.md) | πŸ‘ | πŸ”§ | prefer toHaveStyle over checking element style |
| [prefer-to-have-text-content](https://github.com/testing-library/eslint-plugin-jest-dom/blob/master/docs/rules/prefer-to-have-text-content.md) | πŸ‘ | πŸ”§ | Prefer toHaveTextContent over checking element.textContent |
<!-- __END AUTOGENERATED TABLE__ -->

@@ -156,3 +158,3 @@

<td align="center"><a href="https://mario.dev"><img src="https://avatars1.githubusercontent.com/u/2677072?v=4" width="100px;" alt=""/><br /><sub><b>Mario BeltrΓ‘n AlarcΓ³n</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-jest-dom/commits?author=Belco90" title="Documentation">πŸ“–</a></td>
<td align="center"><a href="https://codepen.io/ariperkkio/"><img src="https://avatars2.githubusercontent.com/u/14806298?v=4" width="100px;" alt=""/><br /><sub><b>Ari PerkkiΓΆ</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-jest-dom/issues?q=author%3AAriPerkkio" title="Bug reports">πŸ›</a></td>
<td align="center"><a href="https://codepen.io/ariperkkio/"><img src="https://avatars2.githubusercontent.com/u/14806298?v=4" width="100px;" alt=""/><br /><sub><b>Ari PerkkiΓΆ</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-jest-dom/issues?q=author%3AAriPerkkio" title="Bug reports">πŸ›</a> <a href="https://github.com/testing-library/eslint-plugin-jest-dom/commits?author=AriPerkkio" title="Code">πŸ’»</a> <a href="https://github.com/testing-library/eslint-plugin-jest-dom/commits?author=AriPerkkio" title="Tests">⚠️</a></td>
<td align="center"><a href="http://www.antn.se"><img src="https://avatars0.githubusercontent.com/u/785676?v=4" width="100px;" alt=""/><br /><sub><b>Anton Niklasson</b></sub></a><br /><a href="https://github.com/testing-library/eslint-plugin-jest-dom/commits?author=AntonNiklasson" title="Code">πŸ’»</a> <a href="https://github.com/testing-library/eslint-plugin-jest-dom/commits?author=AntonNiklasson" title="Tests">⚠️</a> <a href="https://github.com/testing-library/eslint-plugin-jest-dom/commits?author=AntonNiklasson" title="Documentation">πŸ“–</a></td>

@@ -164,3 +166,2 @@ </tr>

<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->

@@ -167,0 +168,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚑️ by Socket Inc