Skip to content

Commit

Permalink
feat(prefer-in-document): add support for assigments (#107)
Browse files Browse the repository at this point in the history
* feat(prefer-in-document): add support for assigments

* added coverage

* added not use case

* spacing

* updated docs

* fixed spelling mistake

* fixed bug with not handling

* support awaits

* more async support

* move check into create

* Apply suggestions from code review
  • Loading branch information
benmonro authored Nov 30, 2020
1 parent 8bca240 commit 7b6f524
Show file tree
Hide file tree
Showing 9 changed files with 316 additions and 84 deletions.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ learn how: http://kcd.im/pull-request
Relevant code or config

```javascript

```

What you did:
Expand Down
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,19 @@ module.exports = {
🔧 indicates that a rule is fixable.

<!-- __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__ -->

## Issues
Expand Down
25 changes: 20 additions & 5 deletions docs/rules/prefer-in-document.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,32 @@ expect(queryByText("foo")).toBeNull();
expect(queryByText("foo")).not.toBeNull();
expect(queryByText("foo")).toBeDefined();
expect(queryByText("foo")).not.toBeDefined();

const foo = screen.getByText("foo");
expect(foo).toHaveLength(1);

const bar = screen.queryByText("bar");
expect(bar).toHaveLength(0);
```

Examples of **correct** code for this rule:

```js
expect(screen.queryByText("foo")).toBeInTheDocument();
expect(screen.queryByText("foo")).toBeInTheDocument();
expect(queryByText("foo")).toBeInTheDocument()`;
expect(wrapper.queryAllByTestId('foo')).toBeInTheDocument()`;
expect(screen.getAllByLabel("foo-bar")).toHaveLength(2)`;
expect(notAQuery('foo-bar')).toHaveLength(1)`;
expect(await screen.findByText("foo")).toBeInTheDocument();
expect(queryByText("foo")).toBeInTheDocument();
expect(wrapper.queryAllByTestId("foo")).toBeInTheDocument();
expect(screen.getAllByLabel("foo-bar")).toHaveLength(2);
expect(notAQuery("foo-bar")).toHaveLength(1);

const foo = screen.getAllByText("foo");
expect(foo).toHaveLength(3);

const bar = screen.queryByText("bar");
expect(bar).not.toBeDefined();

const baz = await screen.findByText("baz");
expect(baz).toBeDefined()
```

## When Not To Use It
Expand Down
3 changes: 1 addition & 2 deletions other/MAINTAINING.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,4 @@ necessary by the git commit messages. With this in mind, **please brush up on

Thank you so much for helping to maintain this project!

[commit]:
https://github.com/conventional-changelog-archived-repos/conventional-changelog-angular/blob/ed32559941719a130bb0327f886d6a32a8cbc2ba/convention.md
[commit]: https://github.com/conventional-changelog-archived-repos/conventional-changelog-angular/blob/ed32559941719a130bb0327f886d6a32a8cbc2ba/convention.md
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
"rules": {
"babel/quotes": "off",
"max-lines-per-function": "off",
"testing-library/no-dom-import": "off"
"testing-library/no-dom-import": "off",
"consistent-return": "off"
}
},
"eslintIgnore": [
Expand Down
157 changes: 149 additions & 8 deletions src/__tests__/lib/rules/prefer-in-document.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
//------------------------------------------------------------------------------

import { RuleTester } from "eslint";
import { queries, queriesByVariant } from "../../../queries";
import * as rule from "../../../rules/prefer-in-document";

//------------------------------------------------------------------------------
Expand All @@ -28,17 +27,29 @@ function invalidCase(code, output) {
}

const valid = [
...queries.map((q) => [
...["getByText", "getByRole"].map((q) => [
`expect(screen.${q}('foo')).toBeInTheDocument()`,
`expect(${q}('foo')).toBeInTheDocument()`,
`expect(wrapper.${q}('foo')).toBeInTheDocument()`,
`let foo;
foo = screen.${q}('foo');
foo = somethingElse;
expect(foo).toHaveLength(1);`,
]),
`let foo;
foo = "bar";
expect(foo).toHaveLength(1);`,
`let foo;
foo = "bar";
expect(foo).toHaveLength(0);`,
`let foo;
expect(foo).toHaveLength(1);`,
`expect(screen.notAQuery('foo-bar')).toHaveLength(1)`,
`expect(screen.getByText('foo-bar')).toHaveLength(2)`,
`expect(screen.getAllByText('foo-bar')).toHaveLength(2)`,
];
const invalid = [
// Invalid cases that applies to all variants
...queries.map((q) => [
...["getByText", "getAllByRole"].map((q) => [
invalidCase(
`expect(screen.${q}('foo')).toHaveLength(1)`,
`expect(screen.${q}('foo')).toBeInTheDocument()`
Expand All @@ -51,9 +62,37 @@ const invalid = [
`expect(wrapper.${q}('foo')).toHaveLength(1)`,
`expect(wrapper.${q}('foo')).toBeInTheDocument()`
),
invalidCase(
`const foo = screen.${q}('foo');
expect(foo).toHaveLength(1);`,
`const foo = screen.${q}('foo');
expect(foo).toBeInTheDocument();`
),
invalidCase(
`const foo = ${q}('foo');
expect(foo).toHaveLength(1);`,
`const foo = ${q}('foo');
expect(foo).toBeInTheDocument();`
),
invalidCase(
`let foo;
foo = ${q}('foo');
expect(foo).toHaveLength(1);`,
`let foo;
foo = ${q}('foo');
expect(foo).toBeInTheDocument();`
),
invalidCase(
`let foo;
foo = screen.${q}('foo');
expect(foo).toHaveLength(1);`,
`let foo;
foo = screen.${q}('foo');
expect(foo).toBeInTheDocument();`
),
]),
// Invalid cases that applies to queryBy* and queryAllBy*
...queriesByVariant.query.map((q) => [
...["queryByText", "queryAllByText"].map((q) => [
invalidCase(
`expect(${q}('foo')).toHaveLength(0)`,
`expect(${q}('foo')).not.toBeInTheDocument()`
Expand All @@ -66,18 +105,120 @@ const invalid = [
`expect(${q}('foo')).not.toBeNull()`,
`expect(${q}('foo')).toBeInTheDocument()`
),
invalidCase(
`expect(${q}('foo')) .not .toBeNull()`,
`expect(${q}('foo')).toBeInTheDocument()`
),
invalidCase(
`expect(${q}('foo')).toBeDefined()`,
`expect(${q}('foo')).toBeInTheDocument()`
),
invalidCase(
`expect(${q}('foo')).not.toBeDefined()`,
`expect(${q}('foo')).not.toBeInTheDocument()`
`expect(${q}('foo')) .not .toBeDefined()`,
`expect(${q}('foo')) .not .toBeInTheDocument()`
),
invalidCase(
`let foo;
foo = screen.${q}('foo');
expect(foo).toHaveLength(0);`,
`let foo;
foo = screen.${q}('foo');
expect(foo).not.toBeInTheDocument();`
),
invalidCase(
`let foo;
foo = screen.${q}('foo');
expect(foo) .not.toBeNull();`,
`let foo;
foo = screen.${q}('foo');
expect(foo).toBeInTheDocument();`
),
invalidCase(
`let foo = screen.${q}('foo');
expect(foo).not.toBeNull();`,
`let foo = screen.${q}('foo');
expect(foo).toBeInTheDocument();`
),
]),
invalidCase(
`it("foo", async () => {
expect(await findByRole("button")).toBeDefined();
})`,
`it("foo", async () => {
expect(await findByRole("button")).toBeInTheDocument();
})`
),
invalidCase(
`it("foo", async () => {
expect(await findByRole("button")).not.toBeNull();
})`,
`it("foo", async () => {
expect(await findByRole("button")).toBeInTheDocument();
})`
),
invalidCase(
`it("foo", async () => {
expect(await screen.findByText(/Compressing video/)).toBeDefined();
})`,
`it("foo", async () => {
expect(await screen.findByText(/Compressing video/)).toBeInTheDocument();
})`
),
invalidCase(
`it("foo", async () => {
expect(await screen.findByText(/Compressing video/)).not.toBeDefined();
})`,
`it("foo", async () => {
expect(await screen.findByText(/Compressing video/)).not.toBeInTheDocument();
})`
),
invalidCase(
`it("foo", async () => {
const compressingFeedback = await screen.findByText(/Compressing video/);
expect(compressingFeedback).toBeDefined();
});`,
`it("foo", async () => {
const compressingFeedback = await screen.findByText(/Compressing video/);
expect(compressingFeedback).toBeInTheDocument();
});`
),
invalidCase(
`it("foo", async () => {
const compressingFeedback = await screen.findByText(/Compressing video/);
expect(compressingFeedback).not.toBeNull();
});`,
`it("foo", async () => {
const compressingFeedback = await screen.findByText(/Compressing video/);
expect(compressingFeedback).toBeInTheDocument();
});`
),
invalidCase(
`it("foo", async () => {
let compressingFeedback;
compressingFeedback = await screen.findByText(/Compressing video/);
expect(compressingFeedback).toBeDefined();
});`,
`it("foo", async () => {
let compressingFeedback;
compressingFeedback = await screen.findByText(/Compressing video/);
expect(compressingFeedback).toBeInTheDocument();
});`
),
invalidCase(
`it("foo", async () => {
let compressingFeedback;
compressingFeedback = await screen.findByText(/Compressing video/);
expect(compressingFeedback).not.toBeDefined();
});`,
`it("foo", async () => {
let compressingFeedback;
compressingFeedback = await screen.findByText(/Compressing video/);
expect(compressingFeedback).not.toBeInTheDocument();
});`
),
];

const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2015 } });
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2017 } });
ruleTester.run("prefer-in-document", rule, {
valid: [].concat(...valid),
invalid: [].concat(...invalid),
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/lib/rules/prefer-to-have-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ruleTester.run("prefer-to-have-style", rule, {
invalid: [
{
code: `expect(a.style).toHaveProperty('transform')`,
errors
errors,
},
{
code: `expect(el.style.foo).toBe("bar")`,
Expand Down
6 changes: 0 additions & 6 deletions src/queries.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import { queries as allQueries } from "@testing-library/dom";

export const queries = Object.keys(allQueries);

export const queriesByVariant = {
query: queries.filter((q) => q.startsWith("query")),
get: queries.filter((q) => q.startsWith("get")),
find: queries.filter((q) => q.startsWith("find")),
};
Loading

0 comments on commit 7b6f524

Please sign in to comment.