diff --git a/README.md b/README.md index 79667dfb5..ec65f0ca1 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,6 @@ installations requiring long-term consistency. | [no-commented-out-tests][] | Disallow commented out tests | | | | [no-disabled-tests][] | Disallow disabled tests | ![recommended][] | | | [no-duplicate-hooks][] | Disallow duplicate hooks within a `describe` block | | | -| [no-empty-title][] | Disallow empty titles | | | | [no-expect-resolves][] | Disallow using `expect().resolves` | | | | [no-export][] | Disallow export from test files | | | | [no-focused-tests][] | Disallow focused tests | ![recommended][] | | @@ -173,7 +172,6 @@ https://github.com/dangreenisrael/eslint-plugin-jest-formatting [no-commented-out-tests]: docs/rules/no-commented-out-tests.md [no-disabled-tests]: docs/rules/no-disabled-tests.md [no-duplicate-hooks]: docs/rules/no-duplicate-hooks.md -[no-empty-title]: docs/rules/no-empty-title.md [no-expect-resolves]: docs/rules/no-expect-resolves.md [no-export]: docs/rules/no-export.md [no-focused-tests]: docs/rules/no-focused-tests.md diff --git a/docs/rules/no-empty-title.md b/docs/rules/no-empty-title.md deleted file mode 100644 index 02552810c..000000000 --- a/docs/rules/no-empty-title.md +++ /dev/null @@ -1,36 +0,0 @@ -# Disallow empty titles - -Having an empty string as your test title is pretty useless. This rule reports -an error if it finds an empty string as s test title. - -This rule is not auto-fixable. - -## Rule Details - -The following patterns are considered warnings: - -```js -describe('', () => {}); -describe('foo', () => { - it('', () => {}); -}); -it('', () => {}); -test('', () => {}); -xdescribe('', () => {}); -xit('', () => {}); -xtest('', () => {}); -``` - -These patterns would not be considered warnings: - -```js -describe('foo', () => {}); -describe('foo', () => { - it('bar', () => {}); -}); -test('foo', () => {}); -it('foo', () => {}); -xdescribe('foo', () => {}); -xit('foo', () => {}); -xtest('foo', () => {}); -``` diff --git a/docs/rules/valid-title.md b/docs/rules/valid-title.md index e9a8fe678..455060a36 100644 --- a/docs/rules/valid-title.md +++ b/docs/rules/valid-title.md @@ -2,11 +2,44 @@ Checks that the title of Jest blocks are valid by ensuring that titles are: +- not empty, - not prefixed with their block name, - have no leading or trailing spaces ## Rule Details +**emptyTitle** + +An empty title is not informative, and serves little purpose. + +Examples of **incorrect** code for this rule: + +```js +describe('', () => {}); +describe('foo', () => { + it('', () => {}); +}); +it('', () => {}); +test('', () => {}); +xdescribe('', () => {}); +xit('', () => {}); +xtest('', () => {}); +``` + +Examples of **correct** code for this rule: + +```js +describe('foo', () => {}); +describe('foo', () => { + it('bar', () => {}); +}); +test('foo', () => {}); +it('foo', () => {}); +xdescribe('foo', () => {}); +xit('foo', () => {}); +xtest('foo', () => {}); +``` + **duplicatePrefix** A describe/ test block should not start with duplicatePrefix diff --git a/src/__tests__/rules.test.ts b/src/__tests__/rules.test.ts index 4fb7048be..6b6e12fcc 100644 --- a/src/__tests__/rules.test.ts +++ b/src/__tests__/rules.test.ts @@ -3,7 +3,7 @@ import { resolve } from 'path'; import plugin from '../'; const ruleNames = Object.keys(plugin.rules); -const numberOfRules = 41; +const numberOfRules = 40; describe('rules', () => { it('should have a corresponding doc for each rule', () => { diff --git a/src/rules/__tests__/no-empty-title.test.ts b/src/rules/__tests__/no-empty-title.test.ts deleted file mode 100644 index 371c50da2..000000000 --- a/src/rules/__tests__/no-empty-title.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { TSESLint } from '@typescript-eslint/experimental-utils'; -import rule from '../no-empty-title'; - -const ruleTester = new TSESLint.RuleTester({ - parserOptions: { - sourceType: 'module', - }, -}); - -ruleTester.run('no-empty-title', rule, { - valid: [ - 'describe()', - 'someFn("", function () {})', - 'describe(1, function () {})', - 'describe("foo", function () {})', - 'describe("foo", function () { it("bar", function () {}) })', - 'test("foo", function () {})', - 'test(`foo`, function () {})', - 'test(`${foo}`, function () {})', - "it('foo', function () {})", - "xdescribe('foo', function () {})", - "xit('foo', function () {})", - "xtest('foo', function () {})", - ], - invalid: [ - { - code: 'describe("", function () {})', - errors: [{ messageId: 'describe', column: 10, line: 1 }], - }, - { - code: ["describe('foo', () => {", "it('', () => {})", '})'].join('\n'), - errors: [{ messageId: 'test', column: 4, line: 2 }], - }, - { - code: 'it("", function () {})', - errors: [{ messageId: 'test', column: 4, line: 1 }], - }, - { - code: 'test("", function () {})', - errors: [{ messageId: 'test', column: 6, line: 1 }], - }, - { - code: 'test(``, function () {})', - errors: [{ messageId: 'test', column: 6, line: 1 }], - }, - { - code: "xdescribe('', () => {})", - errors: [{ messageId: 'describe', column: 11, line: 1 }], - }, - { - code: "xit('', () => {})", - errors: [{ messageId: 'test', column: 5, line: 1 }], - }, - { - code: "xtest('', () => {})", - errors: [{ messageId: 'test', column: 7, line: 1 }], - }, - ], -}); diff --git a/src/rules/__tests__/valid-title.test.ts b/src/rules/__tests__/valid-title.test.ts index 76e4aad11..d0f0056db 100644 --- a/src/rules/__tests__/valid-title.test.ts +++ b/src/rules/__tests__/valid-title.test.ts @@ -7,11 +7,117 @@ const ruleTester = new TSESLint.RuleTester({ }, }); +ruleTester.run('no-empty-title', rule, { + valid: [ + 'describe()', + 'someFn("", function () {})', + 'describe(1, function () {})', + 'describe("foo", function () {})', + 'describe("foo", function () { it("bar", function () {}) })', + 'test("foo", function () {})', + 'test(`foo`, function () {})', + 'test(`${foo}`, function () {})', + "it('foo', function () {})", + "xdescribe('foo', function () {})", + "xit('foo', function () {})", + "xtest('foo', function () {})", + ], + invalid: [ + { + code: 'describe("", function () {})', + errors: [ + { + messageId: 'emptyTitle', + column: 1, + line: 1, + data: { jestFunctionName: 'describe' }, + }, + ], + }, + { + code: ["describe('foo', () => {", "it('', () => {})", '})'].join('\n'), + errors: [ + { + messageId: 'emptyTitle', + column: 1, + line: 2, + data: { jestFunctionName: 'test' }, + }, + ], + }, + { + code: 'it("", function () {})', + errors: [ + { + messageId: 'emptyTitle', + column: 1, + line: 1, + data: { jestFunctionName: 'test' }, + }, + ], + }, + { + code: 'test("", function () {})', + errors: [ + { + messageId: 'emptyTitle', + column: 1, + line: 1, + data: { jestFunctionName: 'test' }, + }, + ], + }, + { + code: 'test(``, function () {})', + errors: [ + { + messageId: 'emptyTitle', + column: 1, + line: 1, + data: { jestFunctionName: 'test' }, + }, + ], + }, + { + code: "xdescribe('', () => {})", + errors: [ + { + messageId: 'emptyTitle', + column: 1, + line: 1, + data: { jestFunctionName: 'describe' }, + }, + ], + }, + { + code: "xit('', () => {})", + errors: [ + { + messageId: 'emptyTitle', + column: 1, + line: 1, + data: { jestFunctionName: 'test' }, + }, + ], + }, + { + code: "xtest('', () => {})", + errors: [ + { + messageId: 'emptyTitle', + column: 1, + line: 1, + data: { jestFunctionName: 'test' }, + }, + ], + }, + ], +}); + ruleTester.run('no-accidental-space', rule, { valid: [ 'it()', 'describe()', - 'it("")', 'it.each()()', 'describe("foo", function () {})', 'describe(6, function () {})', diff --git a/src/rules/no-empty-title.ts b/src/rules/no-empty-title.ts deleted file mode 100644 index 0d39c35b8..000000000 --- a/src/rules/no-empty-title.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { - DescribeAlias, - TestCaseName, - createRule, - isDescribe, - isStringNode, - isTestCase, -} from './utils'; - -export default createRule({ - name: __filename, - meta: { - docs: { - category: 'Best Practices', - description: 'Disallow empty titles', - recommended: false, - }, - messages: { - describe: 'describe should not have an empty title', - test: 'test should not have an empty title', - }, - type: 'suggestion', - schema: [], - }, - defaultOptions: [], - create(context) { - return { - CallExpression(node) { - if (!isDescribe(node) && !isTestCase(node)) { - return; - } - const [argument] = node.arguments; - if (!argument || !isStringNode(argument, '')) { - return; - } - - context.report({ - messageId: isDescribe(node) - ? DescribeAlias.describe - : TestCaseName.test, - node: argument, - }); - }, - }; - }, -}); diff --git a/src/rules/valid-title.ts b/src/rules/valid-title.ts index 4a122aee3..0ad79c23e 100644 --- a/src/rules/valid-title.ts +++ b/src/rules/valid-title.ts @@ -3,6 +3,8 @@ import { TSESTree, } from '@typescript-eslint/experimental-utils'; import { + DescribeAlias, + TestCaseName, createRule, getNodeName, getStringValue, @@ -23,6 +25,7 @@ export default createRule({ recommended: false, }, messages: { + emptyTitle: '{{ jestFunctionName }} should not have an empty title', duplicatePrefix: 'should not have duplicate prefix', accidentalSpace: 'should not have leading or trailing spaces', }, @@ -47,6 +50,18 @@ export default createRule({ const title = getStringValue(argument); if (!title) { + if (typeof title === 'string') { + context.report({ + messageId: 'emptyTitle', + data: { + jestFunctionName: isDescribe(node) + ? DescribeAlias.describe + : TestCaseName.test, + }, + node, + }); + } + return; }