Skip to content

Commit 2e3e9f8

Browse files
authored
fix(prefer-called-exactly-once-with): preserve TypeScript generic parameters (#818)
* test(prefer-called-exactly-once-with): add cases for generics * fix(prefer-called-exactly-once-with): account for generics * refactor: we don't need to import `RuleTester` * refactor: run prettier
1 parent ee051f3 commit 2e3e9f8

File tree

2 files changed

+151
-1
lines changed

2 files changed

+151
-1
lines changed

src/rules/prefer-called-exactly-once-with.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,14 @@ export default createEslintRule<Options, MESSAGE_IDS>({
232232
firstCallExpression.parent.range[0],
233233
firstCallExpression.range[0],
234234
)
235-
const replacement = `${indentation}${expectedText}.toHaveBeenCalledExactlyOnceWith(${argsText})`
235+
const typesParam = targetArgNode.callExpression.typeArguments
236+
? sourceCode.text.slice(
237+
targetArgNode.callExpression.typeArguments.range[0],
238+
targetArgNode.callExpression.typeArguments.range[1],
239+
)
240+
: ''
241+
242+
const replacement = `${indentation}${expectedText}.toHaveBeenCalledExactlyOnceWith${typesParam}(${argsText})`
236243

237244
const lineStart = sourceCode.getIndexFromLoc({
238245
line: secondCallExpression.parent.loc.start.line,

tests/prefer-called-exactly-once-with.test.ts

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,146 @@ ruleTester.run(RULE_NAME, rule, {
179179
},
180180
],
181181
})
182+
183+
ruleTester.run('prefer-called-exactly-once-with: typescript edition', rule, {
184+
valid: [
185+
'expect(fn).toHaveBeenCalledExactlyOnceWith<[{ id: number }]>()',
186+
'expect(fn).toHaveBeenCalledExactlyOnceWith<[{ id: number }]>({id: 1})',
187+
],
188+
invalid: [
189+
{
190+
code: `
191+
expect(x).toHaveBeenCalledOnce();
192+
expect(x).toHaveBeenCalledWith<[string]>('hoge');
193+
`,
194+
errors: [
195+
{
196+
messageId: 'preferCalledExactlyOnceWith',
197+
column: 17,
198+
line: 3,
199+
},
200+
],
201+
output: `
202+
expect(x).toHaveBeenCalledExactlyOnceWith<[string]>('hoge');
203+
`,
204+
},
205+
{
206+
code: `
207+
expect(x).toHaveBeenCalledWith<[string]>('hoge');
208+
expect(x).toHaveBeenCalledOnce();
209+
`,
210+
errors: [
211+
{
212+
messageId: 'preferCalledExactlyOnceWith',
213+
column: 17,
214+
line: 3,
215+
},
216+
],
217+
output: `
218+
expect(x).toHaveBeenCalledExactlyOnceWith<[string]>('hoge');
219+
`,
220+
},
221+
{
222+
code: `
223+
expect(x).toHaveBeenCalledOnce<[number]>();
224+
expect(x).toHaveBeenCalledWith<[string]>('hoge');
225+
`,
226+
errors: [
227+
{
228+
messageId: 'preferCalledExactlyOnceWith',
229+
column: 17,
230+
line: 3,
231+
},
232+
],
233+
output: `
234+
expect(x).toHaveBeenCalledExactlyOnceWith<[string]>('hoge');
235+
`,
236+
},
237+
{
238+
code: `
239+
expect(x).toHaveBeenCalledOnce();
240+
expect(x).toHaveBeenCalledWith<
241+
[
242+
{
243+
id: number
244+
}
245+
]
246+
>('hoge');
247+
`,
248+
errors: [
249+
{
250+
messageId: 'preferCalledExactlyOnceWith',
251+
column: 17,
252+
line: 3,
253+
},
254+
],
255+
output: `
256+
expect(x).toHaveBeenCalledExactlyOnceWith<
257+
[
258+
{
259+
id: number
260+
}
261+
]
262+
>('hoge');
263+
`,
264+
},
265+
{
266+
code: `
267+
expect(x).toHaveBeenCalledWith<[string, number]>('hoge', 123);
268+
expect(x).toHaveBeenCalledOnce();
269+
`,
270+
errors: [
271+
{
272+
messageId: 'preferCalledExactlyOnceWith',
273+
column: 17,
274+
line: 3,
275+
},
276+
],
277+
output: `
278+
expect(x).toHaveBeenCalledExactlyOnceWith<[string, number]>('hoge', 123);
279+
`,
280+
},
281+
{
282+
code: `
283+
expect(x).toHaveBeenCalledWith<[string, number]>('hoge', 123);
284+
expect(x).toHaveBeenCalledOnce();
285+
expect(y).toHaveBeenCalledWith('foo', 456);
286+
expect(y).toHaveBeenCalledOnce();
287+
`,
288+
errors: [
289+
{
290+
messageId: 'preferCalledExactlyOnceWith',
291+
column: 17,
292+
line: 3,
293+
},
294+
{
295+
messageId: 'preferCalledExactlyOnceWith',
296+
column: 17,
297+
line: 5,
298+
},
299+
],
300+
output: `
301+
expect(x).toHaveBeenCalledExactlyOnceWith<[string, number]>('hoge', 123);
302+
expect(y).toHaveBeenCalledExactlyOnceWith('foo', 456);
303+
`,
304+
},
305+
{
306+
code: `
307+
expect(x).toHaveBeenCalledOnce();
308+
y.mockClear();
309+
expect(x).toHaveBeenCalledWith<[string]>('hoge');
310+
`,
311+
errors: [
312+
{
313+
messageId: 'preferCalledExactlyOnceWith',
314+
column: 17,
315+
line: 4,
316+
},
317+
],
318+
output: `
319+
expect(x).toHaveBeenCalledExactlyOnceWith<[string]>('hoge');
320+
y.mockClear();
321+
`,
322+
},
323+
],
324+
})

0 commit comments

Comments
 (0)