diff --git a/CHANGELOG.md b/CHANGELOG.md index 25e5ef463e13..5e18666805f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,7 +50,8 @@ * `[jest-jasmine2]` Add `testLocationInResults` flag to add location information per spec to test results ([#4782](https://github.com/facebook/jest/pull/4782)) ### Chore & Maintenance -* `[*]` [**BREAKING**] Drop support for Node.js version 4 +* `[*]` [**BREAKING**] Drop support for Node.js version 4 ([#4769](https://github.com/facebook/jest/pull/4769)) +* `[eslint-plugin-jest]` Removed from the Jest core repo, and moved to https://github.com/jest-community/eslint-plugin-jest ([#4867](https://github.com/facebook/jest/pull/4867)) * `[babel-jest]` Explicitly bump istanbul to newer versions ([#4616](https://github.com/facebook/jest/pull/4616)) * `[expect]` Upgrade mocha and rollup for browser testing ([#4642](https://github.com/facebook/jest/pull/4642)) * `[docs]` Add info about `coveragePathIgnorePatterns` ([#4602](https://github.com/facebook/jest/pull/4602)) diff --git a/packages/eslint-plugin-jest/.npmignore b/packages/eslint-plugin-jest/.npmignore deleted file mode 100644 index 85e48fe7b0a4..000000000000 --- a/packages/eslint-plugin-jest/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -**/__mocks__/** -**/__tests__/** -src diff --git a/packages/eslint-plugin-jest/README.md b/packages/eslint-plugin-jest/README.md deleted file mode 100644 index 727455e837dd..000000000000 --- a/packages/eslint-plugin-jest/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# eslint-plugin-jest - -Eslint plugin for Jest - -## Installation - -``` -$ yarn add --dev eslint eslint-plugin-jest -``` - -**Note:** If you installed ESLint globally then you must also install `eslint-plugin-jest` globally. - -## Usage - -Add `jest` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix: - -```json -{ - "plugins": [ - "jest" - ] -} -``` - - -Then configure the rules you want to use under the rules section. - -```json -{ - "rules": { - "jest/no-disabled-tests": "warn", - "jest/no-focused-tests": "error", - "jest/no-identical-title": "error", - "jest/valid-expect": "error" - } -} -``` - -You can also whitelist the environment variables provided by Jest by doing: - -```json -{ - "env": { - "jest/globals": true - } -} -``` - -## Supported Rules - -- [no-disabled-tests](/packages/eslint-plugin-jest/docs/rules/no-disabled-tests.md) - disallow disabled tests. -- [no-focused-tests](/packages/eslint-plugin-jest/docs/rules/no-focused-tests.md) - disallow focused tests. -- [no-identical-title](/packages/eslint-plugin-jest/docs/rules/no-identical-title.md) - disallow identical titles. -- [valid-expect](/packages/eslint-plugin-jest/docs/rules/valid-expect.md) - ensure expect is called correctly. - -## Shareable configurations - -### Recommended - -This plugin exports a recommended configuration that enforces good testing practices. - -To enable this configuration use the `extends` property in your `.eslintrc` config file: - -```json -{ - "extends": ["plugin:jest/recommended"] -} -``` - -See [ESLint documentation](http://eslint.org/docs/user-guide/configuring#extending-configuration-files) for more information about extending configuration files. - -The rules enabled in this configuration are: - -- [jest/no-disabled-tests](/packages/eslint-plugin-jest/docs/rules/no-disabled-tests.md) -- [jest/no-focused-tests](/packages/eslint-plugin-jest/docs/rules/no-focused-tests.md) -- [jest/no-identical-title](/packages/eslint-plugin-jest/docs/rules/no-identical-title.md) -- [jest/valid-expect](/packages/eslint-plugin-jest/docs/rules/valid-expect.md) - -## Credit - -* [eslint-plugin-mocha](https://github.com/lo1tuma/eslint-plugin-mocha) -* [eslint-plugin-jasmine](https://github.com/tlvince/eslint-plugin-jasmine) diff --git a/packages/eslint-plugin-jest/docs/rules/no-disabled-tests.md b/packages/eslint-plugin-jest/docs/rules/no-disabled-tests.md deleted file mode 100644 index 9df966140af9..000000000000 --- a/packages/eslint-plugin-jest/docs/rules/no-disabled-tests.md +++ /dev/null @@ -1,64 +0,0 @@ -# Disallow Disabled Tests (no-disabled-tests) - -Jest has a feature that allows you to temporarily mark tests as disabled. This -feature is often helpful while debugging or to create placeholders for future -tests. Before committing changes we may want to check that all tests are -running. - -This rule raises a warning about disabled tests. - -## Rule Details - -There are a number of ways to disable tests in Jest: -* by appending `.skip` to the test-suite or test-case -* by prepending the test function name with `x` -* by declaring a test with a name but no function body -* by making a call to `pending()` anywhere within the test - -The following patterns are considered warnings: - -```js -describe.skip('foo', () => {}); -it.skip('foo', () => {}); -test.skip('foo', () => {}); - -describe['skip']('bar', () => {}); -it['skip']('bar', () => {}); -test['skip']('bar', () => {}); - -xdescribe('foo', () => {}); -xit('foo', () => {}); -xtest('foo', () => {}); - -it('bar'); -test('bar'); - -it('foo', () => { - pending() -}); -``` - -These patterns would not be considered warnings: - -```js -describe('foo', () => {}); -it('foo', () => {}); -test('foo', () => {}); - -describe.only('bar', () => {}); -it.only('bar', () => {}); -test.only('bar', () => {}); -``` - -### Limitations - -The plugin looks at the literal function names within test code, so will not -catch more complex examples of disabled tests, such as: - -```js -const testSkip = test.skip; -testSkip('skipped test', () => {}); - -const myTest = test; -myTest('does not have function body'); -``` diff --git a/packages/eslint-plugin-jest/docs/rules/no-focused-tests.md b/packages/eslint-plugin-jest/docs/rules/no-focused-tests.md deleted file mode 100644 index 28581a576943..000000000000 --- a/packages/eslint-plugin-jest/docs/rules/no-focused-tests.md +++ /dev/null @@ -1,42 +0,0 @@ -# Disallow Focused Tests (no-focused-tests) - -Jest has a feature that allows you to focus tests by appending `.only` or prepending `f` to a test-suite or a test-case. -This feature is really helpful to debug a failing test, so you don’t have to execute all of your tests. -After you have fixed your test and before committing the changes you have to remove `.only` to ensure all tests are executed on your build system. - -This rule reminds you to remove `.only` from your tests by raising a warning whenever you are using the exclusivity feature. - -## Rule Details - -This rule looks for every `describe.only`, `it.only`, `test.only`, `fdescribe`, `fit` and `ftest` occurrences within the source code. -Of course there are some edge-cases which can’t be detected by this rule e.g.: - -```js -const describeOnly = describe.only; -describeOnly.apply(describe); -``` - -The following patterns are considered warnings: - -```js -describe.only('foo', () => {}); -it.only('foo', () => {}); -describe['only']('bar', () => {}); -it['only']('bar', () => {}); -test.only('foo', () => {}); -test['only']('bar', () => {}); -fdescribe('foo', () => {}); -fit('foo', () => {}); -ftest('bar', () => {}); -``` - -These patterns would not be considered warnings: - -```js -describe('foo', () => {}); -it('foo', () => {}); -describe.skip('bar', () => {}); -it.skip('bar', () => {}); -test('foo', () => {}); -test.skip('bar', () => {}); -``` diff --git a/packages/eslint-plugin-jest/docs/rules/no-identical-title.md b/packages/eslint-plugin-jest/docs/rules/no-identical-title.md deleted file mode 100644 index b150ed5f4085..000000000000 --- a/packages/eslint-plugin-jest/docs/rules/no-identical-title.md +++ /dev/null @@ -1,45 +0,0 @@ -# Disallow identical titles (no-identical-title) - -Having identical titles for two different tests or test suites may create confusion. For example, when a test with the same title as another test in the same test suite fails, it is harder to know which one failed and thus harder to fix. - -## Rule Details - -This rule looks at the title of every test and test suites. It will report when two test suites or two test cases at the same level of a test suite have the same title. - -The following patterns are considered warnings: - -```js -describe('foo', () => { - it('should do bar', () => {}); - it('should do bar', () => {}); // Has the same title as the previous test - - describe('baz', () => { - // ... - }); - - describe('baz', () => { // Has the same title as a previous test suite - // ... - }); -}); -``` - -These patterns would not be considered warnings: - -```js -describe('foo', () => { - it('should do foo', () => {}); - it('should do bar', () => {}); - - // Has the same name as a parent test suite, which is fine - describe('foo', () => { - // Has the same name as a test in a parent test suite, which is fine - it('should do foo', () => {}); - it('should work', () => {}); - }); - - describe('baz', () => { // Has the same title as a previous test suite - // Has the same name as a test in a sibling test suite, which is fine - it('should work', () => {}); - }); -}); -``` diff --git a/packages/eslint-plugin-jest/docs/rules/prefer-to-have-length.md b/packages/eslint-plugin-jest/docs/rules/prefer-to-have-length.md deleted file mode 100644 index 0e86f89e12bc..000000000000 --- a/packages/eslint-plugin-jest/docs/rules/prefer-to-have-length.md +++ /dev/null @@ -1,27 +0,0 @@ -# Suggest using `toHaveLength()` (prefer-to-have-length) - -In order to have a better failure message, `toHaveLength()` should be used upon asserting expections on object's length property. - -## Rule details - -This rule triggers a warning if `toBe()` is used to assert object's length property. - -```js -expect(files.length).toBe(1); -``` - -This rule is enabled by default. - -### Default configuration - -The following pattern is considered warning: - -```js -expect(files.length).toBe(1); -``` - -The following pattern is not warning: - -```js -expect(files).toHaveLength(1); -``` diff --git a/packages/eslint-plugin-jest/docs/rules/valid-expect.md b/packages/eslint-plugin-jest/docs/rules/valid-expect.md deleted file mode 100644 index 2c140e62c74e..000000000000 --- a/packages/eslint-plugin-jest/docs/rules/valid-expect.md +++ /dev/null @@ -1,41 +0,0 @@ -# Enforce valid `expect()` usage (valid-expect) - -Ensure `expect()` is called with a single argument and there is an actual expectation made. - -## Rule details - -This rule triggers a warning if `expect()` is called with more than one argument or without arguments. -It would also issue a warning if there is nothing called on `expect()`, e.g.: - -```js -expect(); -expect('something'); -``` - -or when a matcher function was not called, e.g.: - -```js -expect(true).toBeDefined; -``` - -This rule is enabled by default. - -### Default configuration - -The following patterns are considered warnings: - -```js -expect(); -expect().toEqual('something'); -expect('something', 'else'); -expect('something'); -expect(true).toBeDefined; -``` - -The following patterns are not warnings: - -```js -expect('something').toEqual('something'); -expect([1, 2, 3]).toEqual([1, 2, 3]); -expect(true).toBeDefined(); -``` diff --git a/packages/eslint-plugin-jest/package.json b/packages/eslint-plugin-jest/package.json deleted file mode 100644 index c8ca585f1e5d..000000000000 --- a/packages/eslint-plugin-jest/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "eslint-plugin-jest", - "version": "21.2.0", - "description": "Eslint rules for Jest", - "repository": { - "type": "git", - "url": "https://github.com/facebook/jest.git" - }, - "license": "MIT", - "keywords": [ - "eslint", - "eslintplugin", - "eslint-plugin" - ], - "author": { - "name": "Jonathan Kim", - "email": "hello@jkimbo.com", - "url": "jkimbo.com" - }, - "main": "build/index.js", - "peerDependencies": { - "eslint": ">=3.6" - } -} diff --git a/packages/eslint-plugin-jest/src/index.js b/packages/eslint-plugin-jest/src/index.js deleted file mode 100644 index 83b270b3ca10..000000000000 --- a/packages/eslint-plugin-jest/src/index.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import noDisabledTests from './rules/no_disabled_tests'; -import noFocusedTests from './rules/no_focused_tests'; -import noIdenticalTitle from './rules/no_identical_title'; -import preferToHaveLength from './rules/prefer_to_have_length'; -import validExpect from './rules/valid_expect'; - -module.exports = { - configs: { - recommended: { - rules: { - 'jest/no-disabled-tests': 'warn', - 'jest/no-focused-tests': 'error', - 'jest/no-identical-title': 'error', - 'jest/prefer-to-have-length': 'warn', - 'jest/valid-expect': 'error', - }, - }, - }, - environments: { - globals: { - globals: { - afterAll: false, - afterEach: false, - beforeAll: false, - beforeEach: false, - describe: false, - expect: false, - fit: false, - it: false, - jasmine: false, - jest: false, - pending: false, - pit: false, - require: false, - test: false, - xdescribe: false, - xit: false, - xtest: false, - }, - }, - }, - rules: { - 'no-disabled-tests': noDisabledTests, - 'no-focused-tests': noFocusedTests, - 'no-identical-title': noIdenticalTitle, - 'prefer-to-have-length': preferToHaveLength, - 'valid-expect': validExpect, - }, -}; diff --git a/packages/eslint-plugin-jest/src/rules/__tests__/no_focused_tests.test.js b/packages/eslint-plugin-jest/src/rules/__tests__/no_focused_tests.test.js deleted file mode 100644 index 541c8b40dad2..000000000000 --- a/packages/eslint-plugin-jest/src/rules/__tests__/no_focused_tests.test.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -/* eslint-disable sort-keys */ - -'use strict'; - -import {RuleTester} from 'eslint'; -const {rules} = require('../../'); - -const ruleTester = new RuleTester(); -const expectedErrorMessage = 'Unexpected focused test.'; - -ruleTester.run('no-focused-tests', rules['no-focused-tests'], { - valid: [ - 'describe()', - 'it()', - 'describe.skip()', - 'it.skip()', - 'test()', - 'test.skip()', - 'var appliedOnly = describe.only; appliedOnly.apply(describe)', - 'var calledOnly = it.only; calledOnly.call(it)', - ], - - invalid: [ - { - code: 'describe.only()', - errors: [{message: expectedErrorMessage, column: 10, line: 1}], - }, - { - code: 'describe["only"]()', - errors: [{message: expectedErrorMessage, column: 10, line: 1}], - }, - { - code: 'it.only()', - errors: [{message: expectedErrorMessage, column: 4, line: 1}], - }, - { - code: 'it["only"]()', - errors: [{message: expectedErrorMessage, column: 4, line: 1}], - }, - { - code: 'test.only()', - errors: [{message: expectedErrorMessage, column: 6, line: 1}], - }, - { - code: 'test["only"]()', - errors: [{message: expectedErrorMessage, column: 6, line: 1}], - }, - { - code: 'fdescribe()', - errors: [{message: expectedErrorMessage, column: 1, line: 1}], - }, - { - code: 'fit()', - errors: [{message: expectedErrorMessage, column: 1, line: 1}], - }, - ], -}); diff --git a/packages/eslint-plugin-jest/src/rules/__tests__/no_identical_title.test.js b/packages/eslint-plugin-jest/src/rules/__tests__/no_identical_title.test.js deleted file mode 100644 index 62b2e02eb979..000000000000 --- a/packages/eslint-plugin-jest/src/rules/__tests__/no_identical_title.test.js +++ /dev/null @@ -1,218 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -/* eslint-disable sort-keys */ - -'use strict'; - -import {RuleTester} from 'eslint'; -const {rules} = require('../../'); - -const ruleTester = new RuleTester(); - -ruleTester.run('no-identical-title', rules['no-identical-title'], { - valid: [ - [ - 'describe("describe", function() {', - ' it("it", function() {});', - '});', - ].join('\n'), - [ - 'describe("describe1", function() {', - ' it("it1", function() {});', - ' it("it2", function() {});', - '});', - ].join('\n'), - ['it("it1", function() {});', 'it("it2", function() {});'].join('\n'), - ['it.only("it1", function() {});', 'it("it2", function() {});'].join('\n'), - ['it.only("it1", function() {});', 'it.only("it2", function() {});'].join( - '\n', - ), - ['describe("title", function() {});', 'it("title", function() {});'].join( - '\n', - ), - [ - 'describe("describe1", function() {', - ' it("it1", function() {});', - ' describe("describe2", function() {', - ' it("it1", function() {});', - ' });', - '});', - ].join('\n'), - [ - 'describe("describe1", function() {', - ' describe("describe2", function() {', - ' it("it1", function() {});', - ' });', - ' it("it1", function() {});', - '});', - ].join('\n'), - [ - 'describe("describe1", function() {', - ' describe("describe2", function() {});', - '});', - ].join('\n'), - [ - 'describe("describe1", function() {', - ' describe("describe2", function() {});', - '});', - 'describe("describe2", function() {});', - ].join('\n'), - [ - 'describe("describe1", function() {});', - 'describe("describe2", function() {});', - ].join('\n'), - ['it("it" + n, function() {});', 'it("it" + n, function() {});'].join('\n'), - { - code: [ - 'it(`it${n}`, function() {});', - 'it(`it${n}`, function() {});', - ].join('\n'), - env: { - es6: true, - }, - }, - [ - 'describe("title " + foo, function() {', - ' describe("describe1", function() {});', - '});', - 'describe("describe1", function() {});', - ].join('\n'), - [ - 'describe("describe1", function() {', - ' describe("describe2", function() {});', - ' describe("title " + foo, function() {', - ' describe("describe2", function() {});', - ' });', - '});', - ].join('\n'), - ], - - invalid: [ - { - code: [ - 'describe("describe1", function() {', - ' it("it1", function() {});', - ' it("it1", function() {});', - '});', - ].join('\n'), - errors: [ - { - message: 'Test title is used multiple times in the same test suite.', - column: 4, - line: 3, - }, - ], - }, - { - code: ['it("it1", function() {});', 'it("it1", function() {});'].join( - '\n', - ), - errors: [ - { - message: 'Test title is used multiple times in the same test suite.', - column: 1, - line: 2, - }, - ], - }, - { - code: [ - 'it.only("it1", function() {});', - 'it("it1", function() {});', - ].join('\n'), - errors: [ - { - message: 'Test title is used multiple times in the same test suite.', - column: 1, - line: 2, - }, - ], - }, - { - code: ['fit("it1", function() {});', 'it("it1", function() {});'].join( - '\n', - ), - errors: [ - { - message: 'Test title is used multiple times in the same test suite.', - column: 1, - line: 2, - }, - ], - }, - { - code: [ - 'it.only("it1", function() {});', - 'it.only("it1", function() {});', - ].join('\n'), - errors: [ - { - message: 'Test title is used multiple times in the same test suite.', - column: 1, - line: 2, - }, - ], - }, - { - code: [ - 'describe("describe1", function() {});', - 'describe("describe1", function() {});', - ].join('\n'), - errors: [ - { - message: 'Test suite title is used multiple times.', - column: 1, - line: 2, - }, - ], - }, - { - code: [ - 'describe("describe1", function() {});', - 'xdescribe("describe1", function() {});', - ].join('\n'), - errors: [ - { - message: 'Test suite title is used multiple times.', - column: 1, - line: 2, - }, - ], - }, - { - code: [ - 'fdescribe("describe1", function() {});', - 'describe("describe1", function() {});', - ].join('\n'), - errors: [ - { - message: 'Test suite title is used multiple times.', - column: 1, - line: 2, - }, - ], - }, - { - code: [ - 'describe("describe1", function() {', - ' describe("describe2", function() {});', - '});', - 'describe("describe1", function() {});', - ].join('\n'), - errors: [ - { - message: 'Test suite title is used multiple times.', - column: 1, - line: 4, - }, - ], - }, - ], -}); diff --git a/packages/eslint-plugin-jest/src/rules/__tests__/no_skipped_tests.test.js b/packages/eslint-plugin-jest/src/rules/__tests__/no_skipped_tests.test.js deleted file mode 100644 index c9cf1fd83f3b..000000000000 --- a/packages/eslint-plugin-jest/src/rules/__tests__/no_skipped_tests.test.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -/* eslint-disable sort-keys */ - -'use strict'; - -import {RuleTester} from 'eslint'; -const {rules} = require('../../'); - -const ruleTester = new RuleTester(); - -ruleTester.run('no-disabled-tests', rules['no-disabled-tests'], { - valid: [ - 'describe("foo", function () {})', - 'it("foo", function () {})', - 'describe.only("foo", function () {})', - 'it.only("foo", function () {})', - 'test("foo", function () {})', - 'test.only("foo", function () {})', - 'var appliedSkip = describe.skip; appliedSkip.apply(describe)', - 'var calledSkip = it.skip; calledSkip.call(it)', - ], - - invalid: [ - { - code: 'describe.skip("foo", function () {})', - errors: [{message: 'Skipped test suite', column: 1, line: 1}], - }, - { - code: 'describe["skip"]("foo", function () {})', - errors: [{message: 'Skipped test suite', column: 1, line: 1}], - }, - { - code: 'it.skip("foo", function () {})', - errors: [{message: 'Skipped test', column: 1, line: 1}], - }, - { - code: 'it["skip"]("foo", function () {})', - errors: [{message: 'Skipped test', column: 1, line: 1}], - }, - { - code: 'test.skip("foo", function () {})', - errors: [{message: 'Skipped test', column: 1, line: 1}], - }, - { - code: 'test["skip"]("foo", function () {})', - errors: [{message: 'Skipped test', column: 1, line: 1}], - }, - { - code: 'xdescribe("foo", function () {})', - errors: [{message: 'Disabled test suite', column: 1, line: 1}], - }, - { - code: 'xit("foo", function () {})', - errors: [{message: 'Disabled test', column: 1, line: 1}], - }, - { - code: 'xtest("foo", function () {})', - errors: [{message: 'Disabled test', column: 1, line: 1}], - }, - { - code: 'it("has title but no callback")', - errors: [ - { - message: 'Test is missing function argument', - column: 1, - line: 1, - }, - ], - }, - { - code: 'test("has title but no callback")', - errors: [ - { - message: 'Test is missing function argument', - column: 1, - line: 1, - }, - ], - }, - { - code: 'it("contains a call to pending", function () { pending() })', - errors: [{message: 'Call to pending() within test', column: 48, line: 1}], - }, - { - code: 'describe("contains a call to pending", function () { pending() })', - errors: [ - { - message: 'Call to pending() within test suite', - column: 54, - line: 1, - }, - ], - }, - ], -}); diff --git a/packages/eslint-plugin-jest/src/rules/__tests__/prefer_to_have_length.test.js b/packages/eslint-plugin-jest/src/rules/__tests__/prefer_to_have_length.test.js deleted file mode 100644 index d3f510acff5c..000000000000 --- a/packages/eslint-plugin-jest/src/rules/__tests__/prefer_to_have_length.test.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -/* eslint-disable sort-keys */ - -'use strict'; - -import {RuleTester} from 'eslint'; -const {rules} = require('../../'); - -const ruleTester = new RuleTester(); - -ruleTester.run('prefer_to_have_length', rules['prefer-to-have-length'], { - valid: ['expect(files).toHaveLength(1);', "expect(files.name).toBe('file');"], - - invalid: [ - { - code: 'expect(files.length).toBe(1);', - errors: [ - { - message: 'Use toHaveLength() instead', - column: 22, - line: 1, - }, - ], - output: 'expect(files).toHaveLength(1);', - }, - ], -}); diff --git a/packages/eslint-plugin-jest/src/rules/__tests__/valid_expect.test.js b/packages/eslint-plugin-jest/src/rules/__tests__/valid_expect.test.js deleted file mode 100644 index fe75859eb7e7..000000000000 --- a/packages/eslint-plugin-jest/src/rules/__tests__/valid_expect.test.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -/* eslint-disable sort-keys */ - -'use strict'; - -import {RuleTester} from 'eslint'; -const {rules} = require('../../'); - -const ruleTester = new RuleTester(); - -ruleTester.run('valid-expect', rules['valid-expect'], { - valid: [ - 'expect("something").toEqual("else");', - 'expect(true).toBeDefined();', - 'expect([1, 2, 3]).toEqual([1, 2, 3]);', - 'expect(undefined).not.toBeDefined();', - 'expect(Promise.resolve(2)).resolves.toBeDefined();', - 'expect(Promise.reject(2)).rejects.toBeDefined();', - ], - - invalid: [ - { - code: 'expect().toBe(true);', - errors: [ - { - endColumn: 8, - column: 7, - message: 'No arguments were passed to expect().', - }, - ], - }, - { - code: 'expect().toEqual("something");', - errors: [ - { - endColumn: 8, - column: 7, - message: 'No arguments were passed to expect().', - }, - ], - }, - { - code: 'expect("something", "else").toEqual("something");', - errors: [ - { - endColumn: 26, - column: 21, - message: 'More than one argument was passed to expect().', - }, - ], - }, - { - code: 'expect("something");', - errors: [ - { - endColumn: 20, - column: 1, - message: 'No assertion was called on expect().', - }, - ], - }, - { - code: 'expect();', - errors: [ - { - endColumn: 9, - column: 1, - message: 'No assertion was called on expect().', - }, - { - endColumn: 8, - column: 7, - message: 'No arguments were passed to expect().', - }, - ], - }, - { - code: 'expect(true).toBeDefined;', - errors: [ - { - endColumn: 25, - column: 14, - message: '"toBeDefined" was not called.', - }, - ], - }, - { - code: 'expect(true).not.toBeDefined;', - errors: [ - { - endColumn: 29, - column: 18, - message: '"toBeDefined" was not called.', - }, - ], - }, - { - code: 'expect(true).nope.toBeDefined;', - errors: [ - { - endColumn: 18, - column: 14, - message: '"nope" is not a valid property of expect.', - }, - ], - }, - ], -}); diff --git a/packages/eslint-plugin-jest/src/rules/no_disabled_tests.js b/packages/eslint-plugin-jest/src/rules/no_disabled_tests.js deleted file mode 100644 index 1733bfef6d75..000000000000 --- a/packages/eslint-plugin-jest/src/rules/no_disabled_tests.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import type {Node, EslintContext, CallExpression} from './types'; - -function getName(node: ?Node): ?string { - function joinNames(a: ?string, b: ?string): ?string { - return a && b ? a + '.' + b : null; - } - - switch (node && node.type) { - case 'Identifier': - // $FlowFixMe: ignore duck-typed node property - return node.name; - case 'Literal': - // $FlowFixMe: ignore duck-typed node property - return node.value; - case 'MemberExpression': - // $FlowFixMe: ignore duck-typed node properties - return joinNames(getName(node.object), getName(node.property)); - } - - return null; -} - -export default (context: EslintContext) => { - let suiteDepth = 0; - let testDepth = 0; - - return { - CallExpression: (node: CallExpression) => { - const functionName = getName(node.callee); - - switch (functionName) { - case 'describe': - suiteDepth++; - break; - - case 'describe.skip': - context.report({message: 'Skipped test suite', node}); - break; - - case 'it': - case 'test': - testDepth++; - if (node.arguments.length < 2) { - context.report({ - message: 'Test is missing function argument', - node, - }); - } - break; - - case 'it.skip': - case 'test.skip': - context.report({message: 'Skipped test', node}); - break; - - case 'pending': - if (testDepth > 0) { - context.report({ - message: 'Call to pending() within test', - node, - }); - } else if (suiteDepth > 0) { - context.report({ - message: 'Call to pending() within test suite', - node, - }); - } - break; - - case 'xdescribe': - context.report({message: 'Disabled test suite', node}); - break; - - case 'xit': - case 'xtest': - context.report({message: 'Disabled test', node}); - break; - } - }, - - 'CallExpression:exit': (node: CallExpression) => { - const functionName = getName(node.callee); - - switch (functionName) { - case 'describe': - suiteDepth--; - break; - - case 'it': - case 'test': - testDepth--; - break; - } - }, - }; -}; diff --git a/packages/eslint-plugin-jest/src/rules/no_focused_tests.js b/packages/eslint-plugin-jest/src/rules/no_focused_tests.js deleted file mode 100644 index 23ee223511cc..000000000000 --- a/packages/eslint-plugin-jest/src/rules/no_focused_tests.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import type {EslintContext, CallExpression} from './types'; - -const testFunctions = Object.assign(Object.create(null), { - describe: true, - it: true, - test: true, -}); - -const matchesTestFunction = object => object && testFunctions[object.name]; - -const isCallToFocusedTestFunction = object => - object && object.name[0] === 'f' && testFunctions[object.name.substring(1)]; - -const isPropertyNamedOnly = property => - property && (property.name === 'only' || property.value === 'only'); - -const isCallToTestOnlyFunction = callee => - matchesTestFunction(callee.object) && isPropertyNamedOnly(callee.property); - -export default (context: EslintContext) => ({ - CallExpression(node: CallExpression) { - const callee = node.callee; - if (!callee) { - return; - } - - if ( - callee.type === 'MemberExpression' && - isCallToTestOnlyFunction(callee) - ) { - context.report({ - message: 'Unexpected focused test.', - node: callee.property, - }); - return; - } - - if (callee.type === 'Identifier' && isCallToFocusedTestFunction(callee)) { - context.report({ - message: 'Unexpected focused test.', - node: callee, - }); - return; - } - }, -}); diff --git a/packages/eslint-plugin-jest/src/rules/no_identical_title.js b/packages/eslint-plugin-jest/src/rules/no_identical_title.js deleted file mode 100644 index 86e363d639db..000000000000 --- a/packages/eslint-plugin-jest/src/rules/no_identical_title.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import type {EslintContext, CallExpression} from './types'; - -const describeAliases = Object.assign(Object.create(null), { - describe: true, - 'describe.only': true, - 'describe.skip': true, - fdescribe: true, - xdescribe: true, -}); - -const testCaseNames = Object.assign(Object.create(null), { - fit: true, - it: true, - 'it.only': true, - 'it.skip': true, - test: true, - 'test.only': true, - 'test.skip': true, - xit: true, - xtest: true, -}); - -const getNodeName = node => { - if (node.type === 'MemberExpression') { - return node.object.name + '.' + node.property.name; - } - return node.name; -}; - -const isDescribe = node => - node && - node.type === 'CallExpression' && - describeAliases[getNodeName(node.callee)]; - -const isTestCase = node => - node && - node.type === 'CallExpression' && - testCaseNames[getNodeName(node.callee)]; - -const newDescribeContext = () => ({ - describeTitles: [], - testTitles: [], -}); - -const handleTestCaseTitles = (context, titles, node, title) => { - if (isTestCase(node)) { - if (titles.indexOf(title) !== -1) { - context.report({ - message: 'Test title is used multiple times in the same test suite.', - node, - }); - } - titles.push(title); - } -}; - -const handleTestSuiteTitles = (context, titles, node, title) => { - if (!isDescribe(node)) { - return; - } - if (titles.indexOf(title) !== -1) { - context.report({ - message: 'Test suite title is used multiple times.', - node, - }); - } - titles.push(title); -}; - -const isFirstArgLiteral = node => - node.arguments && node.arguments[0] && node.arguments[0].type === 'Literal'; - -export default (context: EslintContext) => { - const contexts = [newDescribeContext()]; - return { - CallExpression(node: CallExpression) { - const currentLayer = contexts[contexts.length - 1]; - if (isDescribe(node)) { - contexts.push(newDescribeContext()); - } - if (!isFirstArgLiteral(node)) { - return; - } - - const title = node.arguments[0].value; - handleTestCaseTitles(context, currentLayer.testTitles, node, title); - handleTestSuiteTitles(context, currentLayer.describeTitles, node, title); - }, - 'CallExpression:exit'(node: CallExpression) { - if (isDescribe(node)) { - contexts.pop(); - } - }, - }; -}; diff --git a/packages/eslint-plugin-jest/src/rules/prefer_to_have_length.js b/packages/eslint-plugin-jest/src/rules/prefer_to_have_length.js deleted file mode 100644 index 725468cab08b..000000000000 --- a/packages/eslint-plugin-jest/src/rules/prefer_to_have_length.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import type {EslintContext, CallExpression} from './types'; - -export default (context: EslintContext) => { - return { - CallExpression(node: CallExpression) { - const calleeName = node.callee.name; - - if ( - calleeName === 'expect' && - node.arguments.length == 1 && - node.parent && - node.parent.type === 'MemberExpression' && - node.parent.parent - ) { - const parentProperty = node.parent.property; - const propertyName = parentProperty.name; - const argumentObject = node.arguments[0].object; - const argumentProperty = node.arguments[0].property; - - if (propertyName === 'toBe' && argumentProperty.name === 'length') { - // $FlowFixMe - const propertyDot = context - .getSourceCode() - .getFirstTokenBetween( - argumentObject, - argumentProperty, - token => token.value === '.', - ); - context.report({ - fix(fixer) { - return [ - fixer.remove(propertyDot), - fixer.remove(argumentProperty), - fixer.replaceText(parentProperty, 'toHaveLength'), - ]; - }, - message: 'Use toHaveLength() instead', - node: parentProperty, - }); - } - } - }, - }; -}; diff --git a/packages/eslint-plugin-jest/src/rules/types.js b/packages/eslint-plugin-jest/src/rules/types.js deleted file mode 100644 index 393ba04a6419..000000000000 --- a/packages/eslint-plugin-jest/src/rules/types.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -type Location = { - column: number, - line: number, -}; - -type NodeLocation = { - end: Location, - start: Location, -}; - -type ParentNode = CallExpression | MemberExpression; - -export type Node = CallExpression | MemberExpression | Identifier | Literal; - -export type Identifier = { - type: 'Identifier', - name: string, - value: string, - parent: ParentNode, - loc: NodeLocation, -}; - -export type MemberExpression = { - type: 'MemberExpression', - name: string, - expression: CallExpression, - property: Identifier, - object: Identifier, - parent: ParentNode, - loc: NodeLocation, -}; - -export type Literal = { - type: 'Literal', - value?: string, - rawValue?: string, - parent: ParentNode, - property: Identifier, - object: Identifier, - loc: NodeLocation, -}; - -export type CallExpression = { - type: 'CallExpression', - arguments: Array, - callee: Identifier | MemberExpression, - parent: ParentNode, - loc: NodeLocation, -}; - -export type EslintContext = {| - report: ({loc?: NodeLocation, message: string, node: any}) => void, -|}; diff --git a/packages/eslint-plugin-jest/src/rules/valid_expect.js b/packages/eslint-plugin-jest/src/rules/valid_expect.js deleted file mode 100644 index 0fe527951e5a..000000000000 --- a/packages/eslint-plugin-jest/src/rules/valid_expect.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -/* - * This implementation is ported from from eslint-plugin-jasmine. - * MIT license, Tom Vincent. - */ - -import type {EslintContext, CallExpression} from './types'; - -const expectProperties = ['not', 'resolves', 'rejects']; - -export default (context: EslintContext) => { - return { - CallExpression(node: CallExpression) { - const calleeName = node.callee.name; - - if (calleeName === 'expect') { - // checking "expect()" arguments - if (node.arguments.length > 1) { - const secondArgumentLocStart = node.arguments[1].loc.start; - const lastArgumentLocEnd = - node.arguments[node.arguments.length - 1].loc.end; - - context.report({ - loc: { - end: { - column: lastArgumentLocEnd.column - 1, - line: lastArgumentLocEnd.line, - }, - start: secondArgumentLocStart, - }, - message: 'More than one argument was passed to expect().', - node, - }); - } else if (node.arguments.length === 0) { - const expectLength = calleeName.length; - context.report({ - loc: { - end: { - column: node.loc.start.column + expectLength + 1, - line: node.loc.start.line, - }, - start: { - column: node.loc.start.column + expectLength, - line: node.loc.start.line, - }, - }, - message: 'No arguments were passed to expect().', - node, - }); - } - - // something was called on `expect()` - if ( - node.parent && - node.parent.type === 'MemberExpression' && - node.parent.parent - ) { - let parentNode = node.parent; - let parentProperty = parentNode.property; - let propertyName = parentProperty.name; - let grandParent = parentNode.parent; - - // a property is accessed, get the next node - if (grandParent.type === 'MemberExpression') { - // a modifier is used, just get the next one - if (expectProperties.indexOf(propertyName) > -1) { - grandParent = grandParent.parent; - } else { - // only a few properties are allowed - context.report({ - // For some reason `endColumn` isn't set in tests if `loc` is - // not added - loc: parentProperty.loc, - message: `"${propertyName}" is not a valid property of expect.`, - node: parentProperty, - }); - } - - // this next one should be the matcher - parentNode = parentNode.parent; - // $FlowFixMe - parentProperty = parentNode.property; - propertyName = parentProperty.name; - } - - // matcher was not called - if (grandParent.type === 'ExpressionStatement') { - context.report({ - // For some reason `endColumn` isn't set in tests if `loc` is not - // added - loc: parentProperty.loc, - message: `"${propertyName}" was not called.`, - node: parentProperty, - }); - } - } - } - }, - - // nothing called on "expect()" - 'CallExpression:exit'(node: CallExpression) { - if ( - node.callee.name === 'expect' && - node.parent.type === 'ExpressionStatement' - ) { - context.report({ - // For some reason `endColumn` isn't set in tests if `loc` is not - // added - loc: node.loc, - message: 'No assertion was called on expect().', - node, - }); - } - }, - }; -}; diff --git a/yarn.lock b/yarn.lock index f029af596a36..bb675637c7ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2306,6 +2306,10 @@ eslint-plugin-import@^2.6.0: minimatch "^3.0.3" read-pkg-up "^2.0.0" +eslint-plugin-jest@^21.0.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-21.2.0.tgz#292044df9cf0866ad9c530e78e6528fae287b926" + eslint-plugin-jsx-a11y@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.0.2.tgz#659277a758b036c305a7e4a13057c301cd3be73f"