Skip to content

Commit 781f00e

Browse files
authored
feat: improve how jest function calls are resolved to account for import aliases (#1122)
* feat: improve how jest function calls are resolved to account for import aliases * feat(no-focused-tests): switch to using new jest fn call parser * feat(require-top-level-describe): switch to using new jest fn call parser * feat(no-test-prefixes): switch to using new jest fn call parser * feat(prefer-lowercase-title): switch to using new jest fn call parser * feat(valid-title): switch to using new jest fn call parser * feat(no-identical-titles): switch to using new jest fn call parser * feat(no-duplicate-hooks): switch to using new jest fn call parser * feat(consistent-test-it): switch to using new jest fn call parser * feat: switch rules to using new jest fn call parser * chore: remove unused utils * refactor: move `scopeHasLocalReference` util function to deduplicate internal code * refactor: ensure complete test coverage * fix: consider imported `jest` property as a jest function * test: cover advanced cases for `parseJestFnCall` * chore: remove duplicated entries in valid jest fn call chains array * chore: linting fixes * fix: remove `failing` support (for now) * refactor: rename variable to be consistent * test: remove empty suggestions check
1 parent 91d61c4 commit 781f00e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1720
-1645
lines changed

src/rules/__tests__/consistent-test-it.test.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,52 @@ ruleTester.run('consistent-test-it with fn=test', rule, {
6161
},
6262
],
6363
},
64+
{
65+
code: dedent`
66+
import { it } from '@jest/globals';
67+
68+
it("foo")
69+
`,
70+
output: dedent`
71+
import { it } from '@jest/globals';
72+
73+
test("foo")
74+
`,
75+
options: [{ fn: TestCaseName.test }],
76+
parserOptions: { sourceType: 'module' },
77+
errors: [
78+
{
79+
messageId: 'consistentMethod',
80+
data: {
81+
testKeyword: TestCaseName.test,
82+
oppositeTestKeyword: TestCaseName.it,
83+
},
84+
},
85+
],
86+
},
87+
{
88+
code: dedent`
89+
import { it as testThisThing } from '@jest/globals';
90+
91+
testThisThing("foo")
92+
`,
93+
output: dedent`
94+
import { it as testThisThing } from '@jest/globals';
95+
96+
test("foo")
97+
`,
98+
options: [{ fn: TestCaseName.test }],
99+
parserOptions: { sourceType: 'module' },
100+
errors: [
101+
{
102+
messageId: 'consistentMethod',
103+
data: {
104+
testKeyword: TestCaseName.test,
105+
oppositeTestKeyword: TestCaseName.it,
106+
},
107+
},
108+
],
109+
},
64110
{
65111
code: 'xit("foo")',
66112
output: 'xtest("foo")',
@@ -495,6 +541,52 @@ ruleTester.run('consistent-test-it with fn=test and withinDescribe=it ', rule, {
495541
},
496542
],
497543
},
544+
{
545+
code: dedent`
546+
import { xtest as dontTestThis } from '@jest/globals';
547+
548+
describe("suite", () => { dontTestThis("foo") });
549+
`,
550+
output: dedent`
551+
import { xtest as dontTestThis } from '@jest/globals';
552+
553+
describe("suite", () => { xit("foo") });
554+
`,
555+
options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }],
556+
parserOptions: { sourceType: 'module' },
557+
errors: [
558+
{
559+
messageId: 'consistentMethodWithinDescribe',
560+
data: {
561+
testKeywordWithinDescribe: TestCaseName.it,
562+
oppositeTestKeyword: TestCaseName.test,
563+
},
564+
},
565+
],
566+
},
567+
{
568+
code: dedent`
569+
import { describe as context, xtest as dontTestThis } from '@jest/globals';
570+
571+
context("suite", () => { dontTestThis("foo") });
572+
`,
573+
output: dedent`
574+
import { describe as context, xtest as dontTestThis } from '@jest/globals';
575+
576+
context("suite", () => { xit("foo") });
577+
`,
578+
options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }],
579+
parserOptions: { sourceType: 'module' },
580+
errors: [
581+
{
582+
messageId: 'consistentMethodWithinDescribe',
583+
data: {
584+
testKeywordWithinDescribe: TestCaseName.it,
585+
oppositeTestKeyword: TestCaseName.test,
586+
},
587+
},
588+
],
589+
},
498590
{
499591
code: 'describe("suite", () => { test.skip("foo") })',
500592
output: 'describe("suite", () => { it.skip("foo") })',

src/rules/__tests__/expect-expect.test.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,82 @@ ruleTester.run('wildcards', rule, {
273273
},
274274
],
275275
});
276+
277+
ruleTester.run('expect-expect (aliases)', rule, {
278+
valid: [
279+
{
280+
code: dedent`
281+
import { test } from '@jest/globals';
282+
283+
test('should pass', () => {
284+
expect(true).toBeDefined();
285+
foo(true).toBe(true);
286+
});
287+
`,
288+
options: [{ assertFunctionNames: ['expect', 'foo'] }],
289+
parserOptions: { sourceType: 'module' },
290+
},
291+
{
292+
code: dedent`
293+
import { test as checkThat } from '@jest/globals';
294+
295+
checkThat('this passes', () => {
296+
expect(true).toBeDefined();
297+
foo(true).toBe(true);
298+
});
299+
`,
300+
options: [{ assertFunctionNames: ['expect', 'foo'] }],
301+
parserOptions: { sourceType: 'module' },
302+
},
303+
{
304+
code: dedent`
305+
const { test } = require('@jest/globals');
306+
307+
test('verifies chained expect method call', () => {
308+
tester
309+
.foo()
310+
.bar()
311+
.expect(456);
312+
});
313+
`,
314+
options: [{ assertFunctionNames: ['tester.foo.bar.expect'] }],
315+
parserOptions: { sourceType: 'module' },
316+
},
317+
],
318+
319+
invalid: [
320+
{
321+
code: dedent`
322+
import { test as checkThat } from '@jest/globals';
323+
324+
checkThat('this passes', () => {
325+
// ...
326+
});
327+
`,
328+
options: [{ assertFunctionNames: ['expect', 'foo'] }],
329+
parserOptions: { sourceType: 'module' },
330+
errors: [
331+
{
332+
messageId: 'noAssertions',
333+
type: AST_NODE_TYPES.CallExpression,
334+
},
335+
],
336+
},
337+
{
338+
code: dedent`
339+
import { test as checkThat } from '@jest/globals';
340+
341+
checkThat.skip('this passes', () => {
342+
// ...
343+
});
344+
`,
345+
parserOptions: { sourceType: 'module' },
346+
errors: [
347+
{
348+
messageId: 'noAssertions',
349+
type: AST_NODE_TYPES.CallExpression,
350+
},
351+
],
352+
},
353+
],
354+
});

src/rules/__tests__/no-conditional-in-test.test.ts

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ ruleTester.run('conditional expressions', rule, {
3131
foo();
3232
});
3333
`,
34+
dedent`
35+
fit.concurrent('foo', () => {
36+
switch('bar') {}
37+
})
38+
`,
3439
],
3540
invalid: [
3641
{
@@ -341,20 +346,6 @@ ruleTester.run('switch statements', rule, {
341346
},
342347
],
343348
},
344-
{
345-
code: dedent`
346-
fit.concurrent('foo', () => {
347-
switch('bar') {}
348-
})
349-
`,
350-
errors: [
351-
{
352-
messageId: 'conditionalInTest',
353-
column: 3,
354-
line: 2,
355-
},
356-
],
357-
},
358349
{
359350
code: dedent`
360351
test('foo', () => {
@@ -616,6 +607,11 @@ ruleTester.run('if statements', rule, {
616607
});
617608
});
618609
`,
610+
dedent`
611+
fit.concurrent('foo', () => {
612+
if ('bar') {}
613+
})
614+
`,
619615
],
620616
invalid: [
621617
{
@@ -770,20 +766,6 @@ ruleTester.run('if statements', rule, {
770766
},
771767
],
772768
},
773-
{
774-
code: dedent`
775-
fit.concurrent('foo', () => {
776-
if ('bar') {}
777-
})
778-
`,
779-
errors: [
780-
{
781-
messageId: 'conditionalInTest',
782-
column: 3,
783-
line: 2,
784-
},
785-
],
786-
},
787769
{
788770
code: dedent`
789771
test('foo', () => {

src/rules/__tests__/no-done-callback.test.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,66 @@ ruleTester.run('no-done-callback', rule, {
392392
},
393393
],
394394
},
395+
{
396+
code: dedent`
397+
import { beforeEach } from '@jest/globals';
398+
399+
beforeEach((done) => {
400+
done();
401+
});
402+
`,
403+
parserOptions: { sourceType: 'module' },
404+
errors: [
405+
{
406+
messageId: 'noDoneCallback',
407+
line: 3,
408+
column: 13,
409+
suggestions: [
410+
{
411+
messageId: 'suggestWrappingInPromise',
412+
data: { callback: 'done' },
413+
output: dedent`
414+
import { beforeEach } from '@jest/globals';
415+
416+
beforeEach(() => {return new Promise((done) => {
417+
done();
418+
})});
419+
`,
420+
},
421+
],
422+
},
423+
],
424+
},
425+
{
426+
code: dedent`
427+
import { beforeEach as atTheStartOfEachTest } from '@jest/globals';
428+
429+
atTheStartOfEachTest((done) => {
430+
done();
431+
});
432+
`,
433+
parserOptions: { sourceType: 'module' },
434+
errors: [
435+
{
436+
messageId: 'noDoneCallback',
437+
line: 3,
438+
column: 23,
439+
suggestions: [
440+
{
441+
messageId: 'suggestWrappingInPromise',
442+
data: { callback: 'done' },
443+
output: dedent`
444+
import { beforeEach as atTheStartOfEachTest } from '@jest/globals';
445+
446+
atTheStartOfEachTest(() => {return new Promise((done) => {
447+
done();
448+
})});
449+
`,
450+
},
451+
],
452+
},
453+
],
454+
},
395455
{
396456
code: 'test.each``("something", ({ a, b }, done) => { done(); })',
397457
errors: [

src/rules/__tests__/no-duplicate-hooks.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,50 @@ ruleTester.run('basic describe block', rule, {
9999
},
100100
],
101101
},
102+
{
103+
code: dedent`
104+
import { afterEach } from '@jest/globals';
105+
106+
describe.skip("foo", () => {
107+
afterEach(() => {}),
108+
afterEach(() => {}),
109+
test("bar", () => {
110+
someFn();
111+
})
112+
})
113+
`,
114+
parserOptions: { sourceType: 'module' },
115+
errors: [
116+
{
117+
messageId: 'noDuplicateHook',
118+
data: { hook: 'afterEach' },
119+
column: 3,
120+
line: 5,
121+
},
122+
],
123+
},
124+
{
125+
code: dedent`
126+
import { afterEach, afterEach as somethingElse } from '@jest/globals';
127+
128+
describe.skip("foo", () => {
129+
afterEach(() => {}),
130+
somethingElse(() => {}),
131+
test("bar", () => {
132+
someFn();
133+
})
134+
})
135+
`,
136+
parserOptions: { sourceType: 'module' },
137+
errors: [
138+
{
139+
messageId: 'noDuplicateHook',
140+
data: { hook: 'afterEach' },
141+
column: 3,
142+
line: 5,
143+
},
144+
],
145+
},
102146
{
103147
code: dedent`
104148
describe.skip("foo", () => {

0 commit comments

Comments
 (0)