Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve how jest function calls are resolved to account for import aliases #1122

Merged
merged 20 commits into from May 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
394f07f
feat: improve how jest function calls are resolved to account for imp…
G-Rath May 22, 2022
317e4a8
feat(no-focused-tests): switch to using new jest fn call parser
G-Rath May 27, 2022
691bf4a
feat(require-top-level-describe): switch to using new jest fn call pa…
G-Rath May 22, 2022
b2eb13c
feat(no-test-prefixes): switch to using new jest fn call parser
G-Rath May 22, 2022
0b7ff49
feat(prefer-lowercase-title): switch to using new jest fn call parser
G-Rath May 22, 2022
dc3cc69
feat(valid-title): switch to using new jest fn call parser
G-Rath May 22, 2022
9963bcf
feat(no-identical-titles): switch to using new jest fn call parser
G-Rath May 21, 2022
9e7d98f
feat(no-duplicate-hooks): switch to using new jest fn call parser
G-Rath May 21, 2022
bf63e3b
feat(consistent-test-it): switch to using new jest fn call parser
G-Rath May 21, 2022
5ccbe59
feat: switch rules to using new jest fn call parser
G-Rath May 27, 2022
7b9e646
chore: remove unused utils
G-Rath May 27, 2022
cba5e16
refactor: move `scopeHasLocalReference` util function to deduplicate …
G-Rath May 27, 2022
bdcbed4
refactor: ensure complete test coverage
G-Rath May 27, 2022
44ed6a2
fix: consider imported `jest` property as a jest function
G-Rath May 28, 2022
8439c37
test: cover advanced cases for `parseJestFnCall`
G-Rath May 28, 2022
7287588
chore: remove duplicated entries in valid jest fn call chains array
G-Rath May 28, 2022
f014ede
chore: linting fixes
G-Rath May 28, 2022
66d6a64
fix: remove `failing` support (for now)
G-Rath May 28, 2022
be217e2
refactor: rename variable to be consistent
G-Rath May 28, 2022
92ef9e3
test: remove empty suggestions check
G-Rath May 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
92 changes: 92 additions & 0 deletions src/rules/__tests__/consistent-test-it.test.ts
Expand Up @@ -61,6 +61,52 @@ ruleTester.run('consistent-test-it with fn=test', rule, {
},
],
},
{
code: dedent`
import { it } from '@jest/globals';

it("foo")
`,
output: dedent`
import { it } from '@jest/globals';

test("foo")
`,
options: [{ fn: TestCaseName.test }],
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'consistentMethod',
data: {
testKeyword: TestCaseName.test,
oppositeTestKeyword: TestCaseName.it,
},
},
],
},
{
code: dedent`
import { it as testThisThing } from '@jest/globals';

testThisThing("foo")
`,
output: dedent`
import { it as testThisThing } from '@jest/globals';

test("foo")
`,
options: [{ fn: TestCaseName.test }],
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'consistentMethod',
data: {
testKeyword: TestCaseName.test,
oppositeTestKeyword: TestCaseName.it,
},
},
],
},
{
code: 'xit("foo")',
output: 'xtest("foo")',
Expand Down Expand Up @@ -495,6 +541,52 @@ ruleTester.run('consistent-test-it with fn=test and withinDescribe=it ', rule, {
},
],
},
{
code: dedent`
import { xtest as dontTestThis } from '@jest/globals';

describe("suite", () => { dontTestThis("foo") });
`,
output: dedent`
import { xtest as dontTestThis } from '@jest/globals';

describe("suite", () => { xit("foo") });
`,
options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }],
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'consistentMethodWithinDescribe',
data: {
testKeywordWithinDescribe: TestCaseName.it,
oppositeTestKeyword: TestCaseName.test,
},
},
],
},
{
code: dedent`
import { describe as context, xtest as dontTestThis } from '@jest/globals';

context("suite", () => { dontTestThis("foo") });
`,
output: dedent`
import { describe as context, xtest as dontTestThis } from '@jest/globals';

context("suite", () => { xit("foo") });
`,
options: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }],
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'consistentMethodWithinDescribe',
data: {
testKeywordWithinDescribe: TestCaseName.it,
oppositeTestKeyword: TestCaseName.test,
},
},
],
},
{
code: 'describe("suite", () => { test.skip("foo") })',
output: 'describe("suite", () => { it.skip("foo") })',
Expand Down
79 changes: 79 additions & 0 deletions src/rules/__tests__/expect-expect.test.ts
Expand Up @@ -273,3 +273,82 @@ ruleTester.run('wildcards', rule, {
},
],
});

ruleTester.run('expect-expect (aliases)', rule, {
valid: [
{
code: dedent`
import { test } from '@jest/globals';

test('should pass', () => {
expect(true).toBeDefined();
foo(true).toBe(true);
});
`,
options: [{ assertFunctionNames: ['expect', 'foo'] }],
parserOptions: { sourceType: 'module' },
},
{
code: dedent`
import { test as checkThat } from '@jest/globals';

checkThat('this passes', () => {
expect(true).toBeDefined();
foo(true).toBe(true);
});
`,
options: [{ assertFunctionNames: ['expect', 'foo'] }],
parserOptions: { sourceType: 'module' },
},
{
code: dedent`
const { test } = require('@jest/globals');

test('verifies chained expect method call', () => {
tester
.foo()
.bar()
.expect(456);
});
`,
options: [{ assertFunctionNames: ['tester.foo.bar.expect'] }],
parserOptions: { sourceType: 'module' },
},
],

invalid: [
{
code: dedent`
import { test as checkThat } from '@jest/globals';

checkThat('this passes', () => {
// ...
});
`,
options: [{ assertFunctionNames: ['expect', 'foo'] }],
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'noAssertions',
type: AST_NODE_TYPES.CallExpression,
},
],
},
{
code: dedent`
import { test as checkThat } from '@jest/globals';

checkThat.skip('this passes', () => {
// ...
});
`,
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'noAssertions',
type: AST_NODE_TYPES.CallExpression,
},
],
},
],
});
38 changes: 10 additions & 28 deletions src/rules/__tests__/no-conditional-in-test.test.ts
Expand Up @@ -31,6 +31,11 @@ ruleTester.run('conditional expressions', rule, {
foo();
});
`,
dedent`
fit.concurrent('foo', () => {
switch('bar') {}
})
`,
],
invalid: [
{
Expand Down Expand Up @@ -341,20 +346,6 @@ ruleTester.run('switch statements', rule, {
},
],
},
{
code: dedent`
fit.concurrent('foo', () => {
switch('bar') {}
})
`,
errors: [
{
messageId: 'conditionalInTest',
column: 3,
line: 2,
},
],
},
{
code: dedent`
test('foo', () => {
Expand Down Expand Up @@ -616,6 +607,11 @@ ruleTester.run('if statements', rule, {
});
});
`,
dedent`
fit.concurrent('foo', () => {
if ('bar') {}
})
`,
],
invalid: [
{
Expand Down Expand Up @@ -770,20 +766,6 @@ ruleTester.run('if statements', rule, {
},
],
},
{
code: dedent`
fit.concurrent('foo', () => {
if ('bar') {}
})
`,
errors: [
{
messageId: 'conditionalInTest',
column: 3,
line: 2,
},
],
},
{
code: dedent`
test('foo', () => {
Expand Down
60 changes: 60 additions & 0 deletions src/rules/__tests__/no-done-callback.test.ts
Expand Up @@ -392,6 +392,66 @@ ruleTester.run('no-done-callback', rule, {
},
],
},
{
code: dedent`
import { beforeEach } from '@jest/globals';

beforeEach((done) => {
done();
});
`,
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'noDoneCallback',
line: 3,
column: 13,
suggestions: [
{
messageId: 'suggestWrappingInPromise',
data: { callback: 'done' },
output: dedent`
import { beforeEach } from '@jest/globals';

beforeEach(() => {return new Promise((done) => {
done();
})});
`,
},
],
},
],
},
{
code: dedent`
import { beforeEach as atTheStartOfEachTest } from '@jest/globals';

atTheStartOfEachTest((done) => {
done();
});
`,
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'noDoneCallback',
line: 3,
column: 23,
suggestions: [
{
messageId: 'suggestWrappingInPromise',
data: { callback: 'done' },
output: dedent`
import { beforeEach as atTheStartOfEachTest } from '@jest/globals';

atTheStartOfEachTest(() => {return new Promise((done) => {
done();
})});
`,
},
],
},
],
},
{
code: 'test.each``("something", ({ a, b }, done) => { done(); })',
errors: [
Expand Down
44 changes: 44 additions & 0 deletions src/rules/__tests__/no-duplicate-hooks.test.ts
Expand Up @@ -99,6 +99,50 @@ ruleTester.run('basic describe block', rule, {
},
],
},
{
code: dedent`
import { afterEach } from '@jest/globals';

describe.skip("foo", () => {
afterEach(() => {}),
afterEach(() => {}),
test("bar", () => {
someFn();
})
})
`,
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'noDuplicateHook',
data: { hook: 'afterEach' },
column: 3,
line: 5,
},
],
},
{
code: dedent`
import { afterEach, afterEach as somethingElse } from '@jest/globals';

describe.skip("foo", () => {
afterEach(() => {}),
somethingElse(() => {}),
test("bar", () => {
someFn();
})
})
`,
parserOptions: { sourceType: 'module' },
errors: [
{
messageId: 'noDuplicateHook',
data: { hook: 'afterEach' },
column: 3,
line: 5,
},
],
},
{
code: dedent`
describe.skip("foo", () => {
Expand Down