Skip to content

Commit

Permalink
fix(prefer-to-have-style): properly handle index access of style pr…
Browse files Browse the repository at this point in the history
…operty (#266)

* fix(prefer-to-have-style): handle indexed style access

* fix(prefer-to-have-style): support computed properties

* fix(prefer-to-have-style): handle number assertions properly

* fix(prefer-to-have-style): handle regexp literals
  • Loading branch information
G-Rath committed May 21, 2022
1 parent 9b48d90 commit 8de3593
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 22 deletions.
35 changes: 35 additions & 0 deletions src/__tests__/lib/rules/prefer-to-have-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ ruleTester.run("prefer-to-have-style", rule, {
`expect().toBe(true)`,
`expect(el).toHaveStyle({foo:"bar"})`,
`expect(el.style).toMatchSnapshot()`,
`expect(el.style).toEqual(1)`,
`expect(el.style).toEqual(foo)`,
`expect(el.style[1]).toEqual([])`,
`expect(el.style[1]).toEqual({})`,
`expect(element.style[0]).toBe(new RegExp('reg'));`,
`expect(el).toHaveAttribute("style")`,
`React.useLayoutEffect(() => {
if (foo) {
Expand Down Expand Up @@ -132,5 +136,36 @@ ruleTester.run("prefer-to-have-style", rule, {
errors,
output: `expect(imageElement).not.toHaveStyle(\`box-shadow: inset 0px 0px 0px 400px 40px\`)`,
},
{
code: `expect(element.style[1]).toEqual('padding');`,
errors,
output: `expect(element).toHaveStyle({padding: expect.anything()});`,
},
{
code: `expect(element.style[1]).toBe(\`padding\`);`,
errors,
output: `expect(element).toHaveStyle({[\`padding\`]: expect.anything()});`,
},
{
code: `expect(element.style[1]).not.toEqual('padding');`,
errors,
},
{
code: `expect(element.style[1]).not.toBe(\`padding\`);`,
errors,
},
{
code: `expect(element.style[1]).toBe(x);`,
errors,
output: `expect(element).toHaveStyle({[x]: expect.anything()});`,
},
{
code: `expect(element.style[0]).toBe(1);`,
errors,
},
{
code: `expect(element.style[0]).toBe(/RegExp/);`,
errors,
},
],
});
69 changes: 47 additions & 22 deletions src/rules/prefer-to-have-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ export const meta = {
};

export const create = (context) => {
function getReplacementObjectProperty(styleName) {
if (styleName.type === "Literal") {
return camelCase(styleName.value);
}

return `[${context.getSourceCode().getText(styleName)}]`;
}
function getReplacementStyleParam(styleName, styleValue) {
return styleName.type === "Literal"
? `{${camelCase(styleName.value)}: ${context
Expand Down Expand Up @@ -148,7 +155,7 @@ export const create = (context) => {
},

//expect(el.style["foo-bar"]).toBe("baz")
[`MemberExpression[property.name=style][parent.computed=true][parent.parent.parent.property.name=/toBe$|to(Strict)?Equal/][parent.parent.parent.parent.arguments.0.type=/(Template)?Literal/][parent.parent.callee.name=expect]`](
[`MemberExpression[property.name=style][parent.computed=true][parent.parent.parent.property.name=/toBe$|to(Strict)?Equal/][parent.parent.parent.parent.arguments.0.type=/((Template)?Literal|Identifier)/][parent.parent.callee.name=expect]`](
node
) {
const styleName = node.parent.property;
Expand All @@ -157,10 +164,14 @@ export const create = (context) => {
const startOfStyleMemberExpression = node.object.range[1];
const endOfStyleMemberExpression =
node.parent.parent.arguments[0].range[1];
context.report({
node: node.property,
message: "Use toHaveStyle instead of asserting on element style",
fix(fixer) {

let fix = null;

if (
typeof styleValue.value !== "number" &&
!(styleValue.value instanceof RegExp)
) {
fix = (fixer) => {
return [
fixer.removeRange([
startOfStyleMemberExpression,
Expand All @@ -169,10 +180,20 @@ export const create = (context) => {
fixer.replaceText(matcher, "toHaveStyle"),
fixer.replaceText(
styleValue,
getReplacementStyleParam(styleName, styleValue)
typeof styleName.value === "number"
? `{${getReplacementObjectProperty(
styleValue
)}: expect.anything()}`
: getReplacementStyleParam(styleName, styleValue)
),
];
},
};
}

context.report({
node: node.property,
message: "Use toHaveStyle instead of asserting on element style",
fix,
});
},
//expect(el.style["foo-bar"]).not.toBe("baz")
Expand All @@ -185,10 +206,10 @@ export const create = (context) => {
const endOfStyleMemberExpression =
node.parent.parent.arguments[0].range[1];

context.report({
node: node.property,
message: "Use toHaveStyle instead of asserting on element style",
fix(fixer) {
let fix = null;

if (typeof styleName.value !== "number") {
fix = (fixer) => {
return [
fixer.removeRange([
node.object.range[1],
Expand All @@ -200,7 +221,13 @@ export const create = (context) => {
getReplacementStyleParam(styleName, styleValue)
),
];
},
};
}

context.report({
node: node.property,
message: "Use toHaveStyle instead of asserting on element style",
fix,
});
},
//expect(foo.style).toHaveProperty("foo", "bar")
Expand All @@ -225,9 +252,9 @@ export const create = (context) => {
fixer.replaceText(matcher, "toHaveStyle"),
fixer.replaceTextRange(
[styleName.range[0], styleValue.range[1]],
`{${camelCase(
styleName.value
)}: ${context.getSourceCode().getText(styleValue)}}`
`{${camelCase(styleName.value)}: ${context
.getSourceCode()
.getText(styleValue)}}`
),
];
},
Expand All @@ -238,10 +265,8 @@ export const create = (context) => {
[`MemberExpression[property.name=style][parent.parent.property.name=not][parent.parent.parent.property.name=toHaveProperty][parent.callee.name=expect]`](
node
) {
const [
styleName,
styleValue,
] = node.parent.parent.parent.parent.arguments;
const [styleName, styleValue] =
node.parent.parent.parent.parent.arguments;
const matcher = node.parent.parent.parent.property;

context.report({
Expand All @@ -259,9 +284,9 @@ export const create = (context) => {
fixer.replaceText(matcher, "toHaveStyle"),
fixer.replaceTextRange(
[styleName.range[0], styleValue.range[1]],
`{${camelCase(
styleName.value
)}: ${context.getSourceCode().getText(styleValue)}}`
`{${camelCase(styleName.value)}: ${context
.getSourceCode()
.getText(styleValue)}}`
),
];
},
Expand Down

0 comments on commit 8de3593

Please sign in to comment.