-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rules): added rule for prefer-to-have-class (#118)
* feat(rules): added rule prefer-to-have-class * more tests * fixed typeo * covg * Apply suggestions from code review Co-authored-by: Anton Niklasson <[email protected]> * classList Co-authored-by: Anton Niklasson <[email protected]>
- Loading branch information
1 parent
043e7bf
commit 00b65fa
Showing
5 changed files
with
430 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# prefer toHaveClass over checking element.class (prefer-to-have-class) | ||
|
||
This rule is an autofixable rule that reports usages of checking element className or classList in expect statements in preference of using the jest-dom | ||
`toHaveClass` matcher. | ||
|
||
## Rule Details | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```js | ||
expect(el.className).toBe("bar"); | ||
expect(el.className).not.toBe("bar"); | ||
expect(el.className).toHaveProperty("class", "foo"); | ||
expect(screen.getByTestId("foo").className).toBe("foo"); | ||
expect(el.className).toContain("bar"); | ||
expect(el.className).not.toContain("baz"); | ||
expect(el).toHaveAttribute("class", "qux"); | ||
|
||
expect(el.classList[0]).toBe("foo"); | ||
expect(el.classList[0]).toBe("bar"); | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```js | ||
expect(el).toHaveClass("bar"); | ||
expect(el).toHaveStyle({ foo: "bar" }); | ||
expect(el.class).toMatchSnapshot(); | ||
expect(el.class).toEqual(foo); | ||
``` | ||
|
||
## When Not To Use It | ||
|
||
If you don't care about using built in matchers for checking class on dom | ||
elements. | ||
|
||
## Further Reading | ||
|
||
- [jest-dom toHaveStyle](https://github.com/testing-library/jest-dom#tohaveclass) | ||
- [ElementCSSInlineStyle.class](https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/class) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import { RuleTester } from "eslint"; | ||
import * as rule from "../../../rules/prefer-to-have-class"; | ||
|
||
const errors = [{ messageId: "use-to-have-class" }]; | ||
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2015 } }); | ||
ruleTester.run("prefer-to-have-class", rule, { | ||
valid: [ | ||
`expect(el).toHaveClass("bar")`, | ||
`expect(el.class).toEqual(foo)`, | ||
`expect(el).toHaveAttribute("class")`, | ||
`expect(el).toHaveAttribute("className", "bar")`, | ||
`expect(el).toHaveAttribute("clazz", "bar")`, | ||
`expect(el).not.toHaveAttribute("clazz", "bar")`, | ||
`expect(el).not.toHaveAttribute("clazz", expect.stringContaining("bar"))`, | ||
`expect(el).toHaveAttribute("clazz", expect.stringContaining("bar"))`, | ||
`expect(el).toHaveProperty("class", "foo")`, | ||
`expect(el).toHaveProperty("clazz", "foo")`, | ||
`expect(el).not.toHaveProperty("clazz", "foo")`, | ||
`expect(el).toHaveProperty("clazz", expect.stringContaining("bar"))`, | ||
`expect(el).not.toHaveProperty("clazz", expect.stringContaining("bar"))`, | ||
`expect(closeButton).toHaveAttribute("class", expect.stringMatching("bar"));`, | ||
], | ||
invalid: [ | ||
{ | ||
code: `expect(screen.getByRole("button").className).toBe("foo")`, | ||
errors, | ||
output: `expect(screen.getByRole("button")).toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(screen.getByRole("button").className).not.toBe("foo")`, | ||
errors, | ||
output: `expect(screen.getByRole("button")).not.toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(el).toHaveProperty("className", "foo")`, | ||
errors, | ||
output: `expect(el).toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(el).toHaveAttribute("class", "foo")`, | ||
errors, | ||
output: `expect(el).toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(el).toHaveAttribute(\`class\`, "foo")`, | ||
errors, | ||
output: `expect(el).toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(el).toHaveAttribute("class", expect.stringContaining("bar"))`, | ||
errors, | ||
output: `expect(el).toHaveClass("bar")`, | ||
}, | ||
{ | ||
code: `expect(el).toHaveAttribute(\`class\`, expect.stringContaining("bar"))`, | ||
errors, | ||
output: `expect(el).toHaveClass("bar")`, | ||
}, | ||
{ | ||
code: `expect(el).not.toHaveProperty("className", "foo")`, | ||
errors, | ||
output: `expect(el).not.toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(el).not.toHaveAttribute("class", "foo")`, | ||
errors, | ||
output: `expect(el).not.toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(el.className).toContain("foo")`, | ||
errors, | ||
output: `expect(el).toHaveClass("foo")`, | ||
}, | ||
{ | ||
code: `expect(el.className).not.toContain("foo")`, | ||
errors, | ||
output: `expect(el).not.toHaveClass("foo")`, | ||
}, | ||
{ | ||
code: `expect(el.className).toBe("foo")`, | ||
errors, | ||
output: `expect(el).toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(el.className).toEqual("foo")`, | ||
errors, | ||
output: `expect(el).toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(el.className).toStrictEqual("foo")`, | ||
errors, | ||
output: `expect(el).toHaveClass("foo", { exact: true })`, | ||
}, | ||
{ | ||
code: `expect(el.className).toEqual(expect.stringContaining("foo"))`, | ||
errors, | ||
output: `expect(el).toHaveClass("foo")`, | ||
}, | ||
{ | ||
code: `expect(el.className).toEqual(expect.stringContaining(\`foo\`))`, | ||
errors, | ||
output: `expect(el).toHaveClass(\`foo\`)`, | ||
}, | ||
{ | ||
code: `expect(el.className).toStrictEqual(expect.stringContaining("foo"))`, | ||
errors, | ||
output: `expect(el).toHaveClass("foo")`, | ||
}, | ||
{ | ||
code: `expect(el.className).toEqual(expect.stringContaining("bar"))`, | ||
errors, | ||
output: `expect(el).toHaveClass("bar")`, | ||
}, | ||
{ | ||
code: `expect(el.classList).toContain("bar")`, | ||
errors, | ||
output: `expect(el).toHaveClass("bar")`, | ||
}, | ||
{ | ||
code: `expect(el.classList).toBe("bar")`, | ||
errors, | ||
}, | ||
{ | ||
code: `expect(el.classList[0]).toBe("bar")`, | ||
errors, | ||
output: `expect(el).toHaveClass("bar")`, | ||
}, | ||
{ | ||
code: `expect(el.classList[0]).not.toBe("bar")`, | ||
errors, | ||
}, | ||
{ | ||
code: `expect(el.classList[0]).toContain(("fo"))`, | ||
errors, | ||
}, | ||
], | ||
}); |
Oops, something went wrong.