Skip to content

Commit

Permalink
feat: improve how jest function calls are resolved to account for imp…
Browse files Browse the repository at this point in the history
…ort 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
  • Loading branch information
G-Rath committed May 28, 2022
1 parent 91d61c4 commit 781f00e
Show file tree
Hide file tree
Showing 42 changed files with 1,720 additions and 1,645 deletions.
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

0 comments on commit 781f00e

Please sign in to comment.