Skip to content

Commit aa4be21

Browse files
authored
feat: resolve expect based on scope (#1173)
1 parent baa76cf commit aa4be21

35 files changed

+1068
-916
lines changed

src/rules/__tests__/no-restricted-matchers.test.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ ruleTester.run('no-restricted-matchers', rule, {
7070
],
7171
},
7272
{
73-
code: 'expect(a).not',
73+
code: 'expect(a).not[x]()',
7474
options: [{ not: null }],
7575
errors: [
7676
{
@@ -159,6 +159,22 @@ ruleTester.run('no-restricted-matchers', rule, {
159159
},
160160
],
161161
},
162+
{
163+
code: 'expect(a).resolves.not.toBe(b)',
164+
options: [{ 'not.toBe': null }],
165+
errors: [
166+
{
167+
messageId: 'restrictedChain',
168+
data: {
169+
message: null,
170+
chain: 'not.toBe',
171+
},
172+
endColumn: 28,
173+
column: 20,
174+
line: 1,
175+
},
176+
],
177+
},
162178
{
163179
code: 'expect(a).not.toBe(b)',
164180
options: [{ 'not.toBe': null }],

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

+30-22
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ ruleTester.run('no-standalone-expect', rule, {
2020
'it("an it", () => expect(1).toBe(1))',
2121
'const func = function(){ expect(1).toBe(1); };',
2222
'const func = () => expect(1).toBe(1);',
23-
'expect.hasAssertions()',
2423
'{}',
2524
'it.each([1, true])("trues", value => { expect(value).toBe(true); });',
2625
'it.each([1, true])("trues", value => { expect(value).toBe(true); }); it("an it", () => { expect(1).toBe(1) });',
@@ -59,27 +58,31 @@ ruleTester.run('no-standalone-expect', rule, {
5958
],
6059
invalid: [
6160
{
62-
code: "(() => {})('testing', () => expect(true))",
63-
errors: [{ endColumn: 41, column: 29, messageId: 'unexpectedExpect' }],
61+
code: "(() => {})('testing', () => expect(true).toBe(false))",
62+
errors: [{ endColumn: 53, column: 29, messageId: 'unexpectedExpect' }],
63+
},
64+
{
65+
code: 'expect.hasAssertions()',
66+
errors: [{ endColumn: 23, column: 1, messageId: 'unexpectedExpect' }],
6467
},
6568
{
6669
code: dedent`
6770
describe('scenario', () => {
6871
const t = Math.random() ? it.only : it;
69-
t('testing', () => expect(true));
72+
t('testing', () => expect(true).toBe(false));
7073
});
7174
`,
72-
errors: [{ endColumn: 34, column: 22, messageId: 'unexpectedExpect' }],
75+
errors: [{ endColumn: 46, column: 22, messageId: 'unexpectedExpect' }],
7376
},
7477
{
7578
code: dedent`
7679
describe('scenario', () => {
7780
const t = Math.random() ? it.only : it;
78-
t('testing', () => expect(true));
81+
t('testing', () => expect(true).toBe(false));
7982
});
8083
`,
8184
options: [{ additionalTestBlockFunctions: undefined }],
82-
errors: [{ endColumn: 34, column: 22, messageId: 'unexpectedExpect' }],
85+
errors: [{ endColumn: 46, column: 22, messageId: 'unexpectedExpect' }],
8386
},
8487
{
8588
code: dedent`
@@ -91,7 +94,7 @@ ruleTester.run('no-standalone-expect', rule, {
9194
expect(a + b).toBe(expected);
9295
});
9396
`,
94-
errors: [{ endColumn: 16, column: 3, messageId: 'unexpectedExpect' }],
97+
errors: [{ endColumn: 31, column: 3, messageId: 'unexpectedExpect' }],
9598
},
9699
{
97100
code: dedent`
@@ -104,7 +107,7 @@ ruleTester.run('no-standalone-expect', rule, {
104107
});
105108
`,
106109
options: [{ additionalTestBlockFunctions: ['each'] }],
107-
errors: [{ endColumn: 16, column: 3, messageId: 'unexpectedExpect' }],
110+
errors: [{ endColumn: 31, column: 3, messageId: 'unexpectedExpect' }],
108111
},
109112
{
110113
code: dedent`
@@ -117,43 +120,48 @@ ruleTester.run('no-standalone-expect', rule, {
117120
});
118121
`,
119122
options: [{ additionalTestBlockFunctions: ['test'] }],
120-
errors: [{ endColumn: 16, column: 3, messageId: 'unexpectedExpect' }],
123+
errors: [{ endColumn: 31, column: 3, messageId: 'unexpectedExpect' }],
121124
},
122125
{
123126
code: 'describe("a test", () => { expect(1).toBe(1); });',
124-
errors: [{ endColumn: 37, column: 28, messageId: 'unexpectedExpect' }],
127+
errors: [{ endColumn: 45, column: 28, messageId: 'unexpectedExpect' }],
125128
},
126129
{
127130
code: 'describe("a test", () => expect(1).toBe(1));',
128-
errors: [{ endColumn: 35, column: 26, messageId: 'unexpectedExpect' }],
131+
errors: [{ endColumn: 43, column: 26, messageId: 'unexpectedExpect' }],
129132
},
130133
{
131134
code: 'describe("a test", () => { const func = () => { expect(1).toBe(1); }; expect(1).toBe(1); });',
132-
errors: [{ endColumn: 80, column: 71, messageId: 'unexpectedExpect' }],
135+
errors: [{ endColumn: 88, column: 71, messageId: 'unexpectedExpect' }],
133136
},
134137
{
135138
code: 'describe("a test", () => { it(() => { expect(1).toBe(1); }); expect(1).toBe(1); });',
136-
errors: [{ endColumn: 72, column: 63, messageId: 'unexpectedExpect' }],
139+
errors: [{ endColumn: 80, column: 63, messageId: 'unexpectedExpect' }],
137140
},
138141
{
139142
code: 'expect(1).toBe(1);',
140-
errors: [{ endColumn: 10, column: 1, messageId: 'unexpectedExpect' }],
141-
},
142-
{
143-
code: 'expect(1).toBe',
144-
errors: [{ endColumn: 10, column: 1, messageId: 'unexpectedExpect' }],
143+
errors: [{ endColumn: 18, column: 1, messageId: 'unexpectedExpect' }],
145144
},
146145
{
147146
code: '{expect(1).toBe(1)}',
148-
errors: [{ endColumn: 11, column: 2, messageId: 'unexpectedExpect' }],
147+
errors: [{ endColumn: 19, column: 2, messageId: 'unexpectedExpect' }],
149148
},
150149
{
151150
code: 'it.each([1, true])("trues", value => { expect(value).toBe(true); }); expect(1).toBe(1);',
152-
errors: [{ endColumn: 79, column: 70, messageId: 'unexpectedExpect' }],
151+
errors: [{ endColumn: 87, column: 70, messageId: 'unexpectedExpect' }],
153152
},
154153
{
155154
code: 'describe.each([1, true])("trues", value => { expect(value).toBe(true); });',
156-
errors: [{ endColumn: 59, column: 46, messageId: 'unexpectedExpect' }],
155+
errors: [{ endColumn: 70, column: 46, messageId: 'unexpectedExpect' }],
156+
},
157+
{
158+
code: dedent`
159+
import { expect as pleaseExpect } from '@jest/globals';
160+
161+
describe("a test", () => { pleaseExpect(1).toBe(1); });
162+
`,
163+
parserOptions: { sourceType: 'module' },
164+
errors: [{ endColumn: 51, column: 28, messageId: 'unexpectedExpect' }],
157165
},
158166
],
159167
});

src/rules/__tests__/prefer-comparison-matcher.test.ts

+4
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,10 @@ testComparisonOperator('<=', 'toBeLessThanOrEqual', 'toBeGreaterThan');
263263

264264
ruleTester.run(`prefer-to-be-comparison`, rule, {
265265
valid: [
266+
'expect.hasAssertions',
267+
'expect.hasAssertions()',
268+
'expect.assertions(1)',
269+
'expect(true).toBe(...true)',
266270
'expect()',
267271
'expect({}).toStrictEqual({})',
268272
'expect(a === b).toBe(true)',

src/rules/__tests__/prefer-equality-matcher.test.ts

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ const expectSuggestions = (
3232

3333
ruleTester.run('prefer-equality-matcher: ===', rule, {
3434
valid: [
35+
'expect.hasAssertions',
36+
'expect.hasAssertions()',
37+
'expect.assertions(1)',
38+
'expect(true).toBe(...true)',
3539
'expect(a == 1).toBe(true)',
3640
'expect(1 == a).toBe(true)',
3741
'expect(a == b).toBe(true)',
@@ -172,6 +176,10 @@ ruleTester.run('prefer-equality-matcher: ===', rule, {
172176

173177
ruleTester.run('prefer-equality-matcher: !==', rule, {
174178
valid: [
179+
'expect.hasAssertions',
180+
'expect.hasAssertions()',
181+
'expect.assertions(1)',
182+
'expect(true).toBe(...true)',
175183
'expect(a != 1).toBe(true)',
176184
'expect(1 != a).toBe(true)',
177185
'expect(a != b).toBe(true)',

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

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

1313
ruleTester.run('prefer-expect-resolves', rule, {
1414
valid: [
15+
'expect.hasAssertions()',
1516
dedent`
1617
it('passes', async () => {
1718
await expect(someValue()).resolves.toBe(true);
@@ -61,5 +62,27 @@ ruleTester.run('prefer-expect-resolves', rule, {
6162
`,
6263
errors: [{ endColumn: 25, column: 10, messageId: 'expectResolves' }],
6364
},
65+
{
66+
code: dedent`
67+
import { expect as pleaseExpect } from '@jest/globals';
68+
69+
it('is true', async () => {
70+
const myPromise = Promise.resolve(true);
71+
72+
pleaseExpect(await myPromise).toBe(true);
73+
});
74+
`,
75+
output: dedent`
76+
import { expect as pleaseExpect } from '@jest/globals';
77+
78+
it('is true', async () => {
79+
const myPromise = Promise.resolve(true);
80+
81+
await pleaseExpect(myPromise).resolves.toBe(true);
82+
});
83+
`,
84+
parserOptions: { sourceType: 'module' },
85+
errors: [{ endColumn: 31, column: 16, messageId: 'expectResolves' }],
86+
},
6487
],
6588
});

src/rules/__tests__/prefer-to-be.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ ruleTester.run('prefer-to-be', rule, {
1414
'expect(null).toBeNull();',
1515
'expect(null).not.toBeNull();',
1616
'expect(null).toBe(1);',
17+
'expect(null).toBe(...1);',
1718
'expect(obj).toStrictEqual([ x, 1 ]);',
1819
'expect(obj).toStrictEqual({ x: 1 });',
1920
'expect(obj).not.toStrictEqual({ x: 1 });',

src/rules/__tests__/prefer-to-contain.test.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
import { TSESLint } from '@typescript-eslint/utils';
2+
import dedent from 'dedent';
23
import rule from '../prefer-to-contain';
4+
import { espreeParser } from './test-utils';
35

4-
const ruleTester = new TSESLint.RuleTester();
6+
const ruleTester = new TSESLint.RuleTester({
7+
parser: espreeParser,
8+
parserOptions: {
9+
ecmaVersion: 2015,
10+
},
11+
});
512

613
ruleTester.run('prefer-to-contain', rule, {
714
valid: [
15+
'expect.hasAssertions',
16+
'expect.hasAssertions()',
17+
'expect.assertions(1)',
818
'expect().toBe(false);',
919
'expect(a).toContain(b);',
1020
"expect(a.name).toBe('b');",
@@ -24,6 +34,8 @@ ruleTester.run('prefer-to-contain', rule, {
2434
`expect(a.test(b)).resolves.toEqual(true)`,
2535
`expect(a.test(b)).resolves.not.toEqual(true)`,
2636
`expect(a).not.toContain(b)`,
37+
'expect(a.includes(...[])).toBe(true)',
38+
'expect(a.includes(b)).toBe(...true)',
2739
'expect(a);',
2840
],
2941
invalid: [
@@ -177,6 +189,20 @@ ruleTester.run('prefer-to-contain', rule, {
177189
output: 'expect([{a:1}]).toContain({a:1});',
178190
errors: [{ messageId: 'useToContain', column: 37, line: 1 }],
179191
},
192+
{
193+
code: dedent`
194+
import { expect as pleaseExpect } from '@jest/globals';
195+
196+
pleaseExpect([{a:1}].includes({a:1})).not.toStrictEqual(false);
197+
`,
198+
output: dedent`
199+
import { expect as pleaseExpect } from '@jest/globals';
200+
201+
pleaseExpect([{a:1}]).toContain({a:1});
202+
`,
203+
parserOptions: { sourceType: 'module' },
204+
errors: [{ messageId: 'useToContain', column: 43, line: 3 }],
205+
},
180206
],
181207
});
182208

src/rules/__tests__/prefer-to-have-length.test.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const ruleTester = new TSESLint.RuleTester({
1111

1212
ruleTester.run('prefer-to-have-length', rule, {
1313
valid: [
14+
'expect.hasAssertions',
15+
'expect.hasAssertions()',
1416
'expect(files).toHaveLength(1);',
1517
"expect(files.name).toBe('file');",
1618
"expect(files[`name`]).toBe('file');",

0 commit comments

Comments
 (0)