Skip to content

Commit 5ab24d9

Browse files
authored
fix(prefer-in-document): handle toHaveLength without any arguments and with trailing commas (#276)
* fix(prefer-in-document): crash when on matcher args in toHaveLength * fix(prefer-in-document): properly remove all matcher args and commas * fix(prefer-in-document): update comment on comma removal logic
1 parent 4299024 commit 5ab24d9

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

src/__tests__/lib/rules/prefer-in-document.js

+80
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ const valid = [
5151
expect(foo).not.toHaveLength(0)`,
5252
`let foo;
5353
expect(foo).toHaveLength(1);`,
54+
`let foo;
55+
expect(foo).toHaveLength()`,
56+
`let foo;
57+
expect(foo).toHaveLength(1, 2, 3)`,
5458
`expect(screen.notAQuery('foo-bar')).toHaveLength(1)`,
5559
`expect(screen.getAllByText('foo-bar')).toHaveLength(2)`,
5660
`import foo from "./foo";
@@ -99,6 +103,82 @@ const valid = [
99103
expect(element).toBeInTheDocument`,
100104
];
101105
const invalid = [
106+
invalidCase(
107+
`expect(screen.getByText('foo')).toHaveLength()`,
108+
`expect(screen.getByText('foo')).not.toBeInTheDocument()`
109+
),
110+
invalidCase(
111+
`expect(screen.getAllByText('foo')).toHaveLength()`,
112+
`expect(screen.getByText('foo')).not.toBeInTheDocument()`
113+
),
114+
invalidCase(
115+
`expect(screen.getByRole('foo')).toHaveLength()`,
116+
`expect(screen.getByRole('foo')).not.toBeInTheDocument()`
117+
),
118+
invalidCase(
119+
`expect(screen.getAllByRole('foo')).toHaveLength()`,
120+
`expect(screen.getByRole('foo')).not.toBeInTheDocument()`
121+
),
122+
invalidCase(
123+
`expect(screen.getByRole('foo')).toHaveLength(0,2,3)`,
124+
`expect(screen.getByRole('foo')).not.toBeInTheDocument()`
125+
),
126+
invalidCase(
127+
`expect(screen.getAllByRole('foo')).toHaveLength(0,2,3,)`,
128+
`expect(screen.getByRole('foo')).not.toBeInTheDocument()`
129+
),
130+
invalidCase(
131+
`expect(screen.getByRole('foo')).toHaveLength(1,2,3)`,
132+
`expect(screen.getByRole('foo')).toBeInTheDocument()`
133+
),
134+
invalidCase(
135+
`expect(screen.getAllByRole('foo')).toHaveLength(1,2,3,)`,
136+
`expect(screen.getByRole('foo')).toBeInTheDocument()`
137+
),
138+
invalidCase(
139+
`expect(screen.getAllByRole('foo')).toHaveLength(0//comment
140+
)`,
141+
`expect(screen.getByRole('foo')).not.toBeInTheDocument(//comment
142+
)`
143+
),
144+
invalidCase(
145+
`expect(screen.getAllByRole('foo')).toHaveLength(1,//comment
146+
)`,
147+
`expect(screen.getByRole('foo')).toBeInTheDocument(//comment
148+
)`
149+
),
150+
invalidCase(
151+
`expect(screen.getAllByRole('foo')).toHaveLength(0,2,3//comment
152+
)`,
153+
`expect(screen.getByRole('foo')).not.toBeInTheDocument(//comment
154+
)`
155+
),
156+
invalidCase(
157+
`expect(screen.getAllByRole('foo')).toHaveLength(1,2,3,//comment
158+
)`,
159+
`expect(screen.getByRole('foo')).toBeInTheDocument(//comment
160+
)`
161+
),
162+
invalidCase(
163+
`expect(screen.getAllByRole('foo')).toHaveLength(0,2,//comment
164+
3,4)`,
165+
`expect(screen.getByRole('foo')).not.toBeInTheDocument(//comment
166+
)`
167+
),
168+
invalidCase(
169+
`expect(screen.getAllByRole('foo')).toHaveLength(1,2,//comment
170+
3,4,)`,
171+
`expect(screen.getByRole('foo')).toBeInTheDocument(//comment
172+
)`
173+
),
174+
invalidCase(
175+
`expect(screen.getAllByRole('foo')).toHaveLength(0,2/*comment*/,3)`,
176+
`expect(screen.getByRole('foo')).not.toBeInTheDocument(/*comment*/)`
177+
),
178+
invalidCase(
179+
`expect(screen.getAllByRole('foo')).toHaveLength(1,2,/*comment*/3,)`,
180+
`expect(screen.getByRole('foo')).toBeInTheDocument(/*comment*/)`
181+
),
102182
invalidCase(
103183
`expect(screen.getByText('foo')).toHaveLength(1)`,
104184
`expect(screen.getByText('foo')).toBeInTheDocument()`

src/rules/prefer-in-document.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ function usesToBeOrToEqualWithNull(matcherNode, matcherArguments) {
4040
}
4141

4242
function usesToHaveLengthZero(matcherNode, matcherArguments) {
43-
return matcherNode.name === "toHaveLength" && matcherArguments[0].value === 0;
43+
// matcherArguments.length === 0: toHaveLength() will cause jest matcher error
44+
// matcherArguments[0].value: toHaveLength(0, ...) means zero length
45+
return (
46+
matcherNode.name === "toHaveLength" &&
47+
(matcherArguments.length === 0 || matcherArguments[0].value === 0)
48+
);
4449
}
4550

4651
export const create = (context) => {
@@ -117,6 +122,12 @@ export const create = (context) => {
117122

118123
// Remove any arguments in the matcher
119124
for (const argument of Array.from(matcherArguments)) {
125+
const sourceCode = context.getSourceCode();
126+
const token = sourceCode.getTokenAfter(argument);
127+
if (token.value === "," && token.type === "Punctuator") {
128+
// Remove commas if toHaveLength had more than one argument or a trailing comma
129+
operations.push(fixer.replaceText(token, ""));
130+
}
120131
operations.push(fixer.remove(argument));
121132
}
122133

0 commit comments

Comments
 (0)