Skip to content

Commit 0968b55

Browse files
authored
fix: support all variations of describe, it, & test (#792)
* refactor(utils): support matching all variations of `describe` & `test` * test(consistent-test-it): add case for `describe.only.each` * test(require-top-level-describe): add cases for modifiers and `each` * test(no-conditional-expect): add cases for `.each` with template literal * test(no-export): add cases for `.each` * test(no-if): add cases for `.each` calls * test(no-test-return-statement): add cases for `.each` * test(prefer-hooks-on-top): add cases for `.each` * test(valid-title): add cases for `.each` * test(utils): deduplicate code * test(utils): refactor to deduplicate code
1 parent d68093b commit 0968b55

28 files changed

+708
-77
lines changed

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

+26
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,32 @@ ruleTester.run('consistent-test-it with fn=test', rule, {
213213
},
214214
],
215215
},
216+
{
217+
code: dedent`
218+
describe.only.each()("%s", () => {
219+
test("is valid, but should not be", () => {});
220+
221+
it("is not valid, but should be", () => {});
222+
});
223+
`,
224+
output: dedent`
225+
describe.only.each()("%s", () => {
226+
it("is valid, but should not be", () => {});
227+
228+
it("is not valid, but should be", () => {});
229+
});
230+
`,
231+
options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }],
232+
errors: [
233+
{
234+
messageId: 'consistentMethodWithinDescribe',
235+
data: {
236+
testKeywordWithinDescribe: TestCaseName.it,
237+
oppositeTestKeyword: TestCaseName.test,
238+
},
239+
},
240+
],
241+
},
216242
{
217243
code: 'describe("suite", () => { it("foo") })',
218244
output: 'describe("suite", () => { test("foo") })',

src/rules/__tests__/lowercase-name.test.ts

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ ruleTester.run('lowercase-name', rule, {
5252
'describe(function () {})',
5353
'describe(``)',
5454
'describe("")',
55+
dedent`
56+
describe.each()(1);
57+
describe.each()(2);
58+
`,
5559
'describe(42)',
5660
{
5761
code: 'describe(42)',

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

+65
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ ruleTester.run('logical conditions', rule, {
143143
`,
144144
errors: [{ messageId: 'conditionalExpect' }],
145145
},
146+
{
147+
code: `
148+
it.each\`\`('foo', () => {
149+
something || expect(something).toHaveBeenCalled();
150+
})
151+
`,
152+
errors: [{ messageId: 'conditionalExpect' }],
153+
},
146154
{
147155
code: `
148156
function getValue() {
@@ -202,6 +210,14 @@ ruleTester.run('conditional conditions', rule, {
202210
`,
203211
errors: [{ messageId: 'conditionalExpect' }],
204212
},
213+
{
214+
code: `
215+
it.each\`\`('foo', () => {
216+
something ? noop() : expect(something).toHaveBeenCalled();
217+
})
218+
`,
219+
errors: [{ messageId: 'conditionalExpect' }],
220+
},
205221
{
206222
code: `
207223
function getValue() {
@@ -275,6 +291,19 @@ ruleTester.run('switch conditions', rule, {
275291
`,
276292
errors: [{ messageId: 'conditionalExpect' }],
277293
},
294+
{
295+
code: `
296+
it.each\`\`('foo', () => {
297+
switch(something) {
298+
case 'value':
299+
expect(something).toHaveBeenCalled();
300+
default:
301+
break;
302+
}
303+
})
304+
`,
305+
errors: [{ messageId: 'conditionalExpect' }],
306+
},
278307
{
279308
code: `
280309
function getValue() {
@@ -343,6 +372,18 @@ ruleTester.run('if conditions', rule, {
343372
`,
344373
errors: [{ messageId: 'conditionalExpect' }],
345374
},
375+
{
376+
code: `
377+
it.each\`\`('foo', () => {
378+
if(!doSomething) {
379+
// do nothing
380+
} else {
381+
expect(something).toHaveBeenCalled();
382+
}
383+
})
384+
`,
385+
errors: [{ messageId: 'conditionalExpect' }],
386+
},
346387
{
347388
code: `
348389
function getValue() {
@@ -438,6 +479,30 @@ ruleTester.run('catch conditions', rule, {
438479
`,
439480
errors: [{ messageId: 'conditionalExpect' }],
440481
},
482+
{
483+
code: `
484+
it.each\`\`('foo', () => {
485+
try {
486+
487+
} catch (err) {
488+
expect(err).toMatch('Error');
489+
}
490+
})
491+
`,
492+
errors: [{ messageId: 'conditionalExpect' }],
493+
},
494+
{
495+
code: `
496+
it.skip.each\`\`('foo', () => {
497+
try {
498+
499+
} catch (err) {
500+
expect(err).toMatch('Error');
501+
}
502+
})
503+
`,
504+
errors: [{ messageId: 'conditionalExpect' }],
505+
},
441506
{
442507
code: `
443508
function getValue() {

src/rules/__tests__/no-export.test.ts

+35-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { TSESLint } from '@typescript-eslint/experimental-utils';
2+
import dedent from 'dedent';
23
import resolveFrom from 'resolve-from';
34
import rule from '../no-export';
45

@@ -23,7 +24,40 @@ ruleTester.run('no-export', rule, {
2324
invalid: [
2425
{
2526
code:
26-
'export const myThing = "invalid"; test("a test", () => { expect(1).toBe(1);});',
27+
'export const myThing = "invalid"; test("a test", () => { expect(1).toBe(1);});',
28+
parserOptions: { sourceType: 'module' },
29+
errors: [{ endColumn: 34, column: 1, messageId: 'unexpectedExport' }],
30+
},
31+
{
32+
code: dedent`
33+
export const myThing = 'invalid';
34+
35+
test.each()('my code', () => {
36+
expect(1).toBe(1);
37+
});
38+
`,
39+
parserOptions: { sourceType: 'module' },
40+
errors: [{ endColumn: 34, column: 1, messageId: 'unexpectedExport' }],
41+
},
42+
{
43+
code: dedent`
44+
export const myThing = 'invalid';
45+
46+
test.each\`\`('my code', () => {
47+
expect(1).toBe(1);
48+
});
49+
`,
50+
parserOptions: { sourceType: 'module' },
51+
errors: [{ endColumn: 34, column: 1, messageId: 'unexpectedExport' }],
52+
},
53+
{
54+
code: dedent`
55+
export const myThing = 'invalid';
56+
57+
test.only.each\`\`('my code', () => {
58+
expect(1).toBe(1);
59+
});
60+
`,
2761
parserOptions: { sourceType: 'module' },
2862
errors: [{ endColumn: 34, column: 1, messageId: 'unexpectedExport' }],
2963
},

src/rules/__tests__/no-if.test.ts

+28
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,34 @@ ruleTester.run('if statements', rule, {
812812
},
813813
],
814814
},
815+
{
816+
code: dedent`
817+
it.each\`\`('foo', () => {
818+
callExpression()
819+
if ('bar') {}
820+
})
821+
`,
822+
errors: [
823+
{
824+
data: { condition: 'if' },
825+
messageId: 'conditionalInTest',
826+
},
827+
],
828+
},
829+
{
830+
code: dedent`
831+
it.only.each\`\`('foo', () => {
832+
callExpression()
833+
if ('bar') {}
834+
})
835+
`,
836+
errors: [
837+
{
838+
data: { condition: 'if' },
839+
messageId: 'conditionalInTest',
840+
},
841+
],
842+
},
815843
{
816844
code: dedent`
817845
describe('valid', () => {

src/rules/__tests__/no-test-return-statement.test.ts

+24
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,30 @@ ruleTester.run('no-test-return-statement', rule, {
5252
`,
5353
errors: [{ messageId: 'noReturnValue', column: 3, line: 2 }],
5454
},
55+
{
56+
code: dedent`
57+
it.skip("one", function () {
58+
return expect(1).toBe(1);
59+
});
60+
`,
61+
errors: [{ messageId: 'noReturnValue', column: 3, line: 2 }],
62+
},
63+
{
64+
code: dedent`
65+
it.each\`\`("one", function () {
66+
return expect(1).toBe(1);
67+
});
68+
`,
69+
errors: [{ messageId: 'noReturnValue', column: 3, line: 2 }],
70+
},
71+
{
72+
code: dedent`
73+
it.only.each\`\`("one", function () {
74+
return expect(1).toBe(1);
75+
});
76+
`,
77+
errors: [{ messageId: 'noReturnValue', column: 3, line: 2 }],
78+
},
5579
{
5680
code: dedent`
5781
it("one", myTest);

src/rules/__tests__/prefer-hooks-on-top.test.ts

+42
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,48 @@ ruleTester.run('basic describe block', rule, {
4545
},
4646
],
4747
},
48+
{
49+
code: dedent`
50+
describe('foo', () => {
51+
beforeEach(() => {});
52+
test.each\`\`('bar', () => {
53+
someFn();
54+
});
55+
beforeAll(() => {});
56+
test.only('bar', () => {
57+
someFn();
58+
});
59+
});
60+
`,
61+
errors: [
62+
{
63+
messageId: 'noHookOnTop',
64+
column: 3,
65+
line: 6,
66+
},
67+
],
68+
},
69+
{
70+
code: dedent`
71+
describe('foo', () => {
72+
beforeEach(() => {});
73+
test.only.each\`\`('bar', () => {
74+
someFn();
75+
});
76+
beforeAll(() => {});
77+
test.only('bar', () => {
78+
someFn();
79+
});
80+
});
81+
`,
82+
errors: [
83+
{
84+
messageId: 'noHookOnTop',
85+
column: 3,
86+
line: 6,
87+
},
88+
],
89+
},
4890
],
4991
});
5092

src/rules/__tests__/require-top-level-describe.test.ts

+17
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const ruleTester = new TSESLint.RuleTester({
1212

1313
ruleTester.run('require-top-level-describe', rule, {
1414
valid: [
15+
'it.each()',
1516
'describe("test suite", () => { test("my test") });',
1617
'describe("test suite", () => { it("my test") });',
1718
dedent`
@@ -89,9 +90,25 @@ ruleTester.run('require-top-level-describe', rule, {
8990
`,
9091
errors: [{ messageId: 'unexpectedHook' }],
9192
},
93+
{
94+
code: "it.skip('test', () => {});",
95+
errors: [{ messageId: 'unexpectedTestCase' }],
96+
},
9297
{
9398
code: "it.each([1, 2, 3])('%n', () => {});",
9499
errors: [{ messageId: 'unexpectedTestCase' }],
95100
},
101+
{
102+
code: "it.skip.each([1, 2, 3])('%n', () => {});",
103+
errors: [{ messageId: 'unexpectedTestCase' }],
104+
},
105+
{
106+
code: "it.skip.each``('%n', () => {});",
107+
errors: [{ messageId: 'unexpectedTestCase' }],
108+
},
109+
{
110+
code: "it.each``('%n', () => {});",
111+
errors: [{ messageId: 'unexpectedTestCase' }],
112+
},
96113
],
97114
});

0 commit comments

Comments
 (0)