Files

Return to Package Diff Home.
Brought to you by Intrinsic.

Package Diff: eslint-plugin-jest @ 22.3.2 .. 22.4.1

docs/rules/no-empty-title.md

@@ -0,0 +1,36 @@
+# 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', () => {});
+```

index.js

@@ -1,34 +1,16 @@
'use strict';
-const consistentTestIt = require('./rules/consistent-test-it');
-const expectExpect = require('./rules/expect-expect');
-const lowercaseName = require('./rules/lowercase-name');
-const noDisabledTests = require('./rules/no-disabled-tests');
-const noFocusedTests = require('./rules/no-focused-tests');
-const noHooks = require('./rules/no-hooks');
-const noIdenticalTitle = require('./rules/no-identical-title');
-const noJasmineGlobals = require('./rules/no-jasmine-globals');
-const noJestImport = require('./rules/no-jest-import');
-const noLargeSnapshots = require('./rules/no-large-snapshots');
-const noTestPrefixes = require('./rules/no-test-prefixes');
-const noTestReturnStatement = require('./rules/no-test-return-statement');
-const preferSpyOn = require('./rules/prefer-spy-on');
-const preferToBeNull = require('./rules/prefer-to-be-null');
-const preferToBeUndefined = require('./rules/prefer-to-be-undefined');
-const preferToContain = require('./rules/prefer-to-contain');
-const preferToHaveLength = require('./rules/prefer-to-have-length');
-const validDescribe = require('./rules/valid-describe');
-const validExpect = require('./rules/valid-expect');
-const preferExpectAssertions = require('./rules/prefer-expect-assertions');
-const validExpectInPromise = require('./rules/valid-expect-in-promise');
-const preferInlineSnapshots = require('./rules/prefer-inline-snapshots');
-const preferStrictEqual = require('./rules/prefer-strict-equal');
-const requireTothrowMessage = require('./rules/require-tothrow-message');
-const noAliasMethods = require('./rules/no-alias-methods');
-const noTestCallback = require('./rules/no-test-callback');
-const noTruthyFalsy = require('./rules/no-truthy-falsy');
-const preferTodo = require('./rules/prefer-todo');
-const preferCalledWith = require('./rules/prefer-called-with');
+const fs = require('fs');
+const path = require('path');
+
+const rules = fs
+ .readdirSync(path.join(__dirname, 'rules'))
+ .filter(rule => rule !== '__tests__' && rule !== 'util.js')
+ .map(rule => path.basename(rule, '.js'))
+ .reduce(
+ (acc, curr) => Object.assign(acc, { [curr]: require(`./rules/${curr}`) }),
+ {}
+ );
const snapshotProcessor = require('./processors/snapshot-processor');
@@ -88,35 +70,5 @@
processors: {
'.snap': snapshotProcessor,
},
- rules: {
- 'consistent-test-it': consistentTestIt,
- 'expect-expect': expectExpect,
- 'lowercase-name': lowercaseName,
- 'no-disabled-tests': noDisabledTests,
- 'no-focused-tests': noFocusedTests,
- 'no-hooks': noHooks,
- 'no-identical-title': noIdenticalTitle,
- 'no-jasmine-globals': noJasmineGlobals,
- 'no-jest-import': noJestImport,
- 'no-large-snapshots': noLargeSnapshots,
- 'no-test-prefixes': noTestPrefixes,
- 'no-test-return-statement': noTestReturnStatement,
- 'prefer-spy-on': preferSpyOn,
- 'prefer-to-be-null': preferToBeNull,
- 'prefer-to-be-undefined': preferToBeUndefined,
- 'prefer-to-contain': preferToContain,
- 'prefer-to-have-length': preferToHaveLength,
- 'valid-describe': validDescribe,
- 'valid-expect': validExpect,
- 'prefer-expect-assertions': preferExpectAssertions,
- 'valid-expect-in-promise': validExpectInPromise,
- 'prefer-inline-snapshots': preferInlineSnapshots,
- 'prefer-strict-equal': preferStrictEqual,
- 'require-tothrow-message': requireTothrowMessage,
- 'no-alias-methods': noAliasMethods,
- 'no-test-callback': noTestCallback,
- 'no-truthy-falsy': noTruthyFalsy,
- 'prefer-todo': preferTodo,
- 'prefer-called-with': preferCalledWith,
- },
+ rules,
};

package.json

@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-jest",
- "version": "22.3.2",
+ "version": "22.4.1",
"description": "Eslint rules for Jest",
"repository": "jest-community/eslint-plugin-jest",
"license": "MIT",

README.md

@@ -96,6 +96,7 @@
| [lowercase-name][] | Disallow capitalized test names | | ![fixable-green][] |
| [no-alias-methods][] | Disallow alias methods | ![recommended][] | ![fixable-green][] |
| [no-disabled-tests][] | Disallow disabled tests | ![recommended][] | |
+| [no-empty-title][] | Disallow empty titles | | |
| [no-focused-tests][] | Disallow focused tests | ![recommended][] | |
| [no-hooks][] | Disallow setup and teardown hooks | | |
| [no-identical-title][] | Disallow identical titles | ![recommended][] | |
@@ -131,6 +132,7 @@
[lowercase-name]: docs/rules/lowercase-name.md
[no-alias-methods]: docs/rules/no-alias-methods.md
[no-disabled-tests]: docs/rules/no-disabled-tests.md
+[no-empty-title]: docs/rules/no-empty-title.md
[no-focused-tests]: docs/rules/no-focused-tests.md
[no-hooks]: docs/rules/no-hooks.md
[no-identical-title]: docs/rules/no-identical-title.md

rules/no-empty-title.js

@@ -0,0 +1,54 @@
+'use strict';
+
+const {
+ getDocsUrl,
+ hasExpressions,
+ isDescribe,
+ isTestCase,
+ isTemplateLiteral,
+ isString,
+ getStringValue,
+} = require('./util');
+
+const errorMessages = {
+ describe: 'describe should not have an empty title',
+ test: 'test should not have an empty title',
+};
+
+module.exports = {
+ meta: {
+ docs: {
+ url: getDocsUrl(__filename),
+ },
+ },
+ create(context) {
+ return {
+ CallExpression(node) {
+ const is = {
+ describe: isDescribe(node),
+ testCase: isTestCase(node),
+ };
+ if (!is.describe && !is.testCase) {
+ return;
+ }
+ const [firstArgument] = node.arguments;
+ if (!isString(firstArgument)) {
+ return;
+ }
+ if (isTemplateLiteral(firstArgument) && hasExpressions(firstArgument)) {
+ return;
+ }
+ if (getStringValue(firstArgument) === '') {
+ const message = is.describe
+ ? errorMessages.describe
+ : errorMessages.test;
+ context.report({
+ message,
+ node,
+ });
+ }
+ },
+ };
+ },
+ errorMessages,
+};

rules/no-identical-title.js

@@ -6,6 +6,7 @@
isTestCase,
isString,
hasExpressions,
+ getStringValue,
} = require('./util');
const newDescribeContext = () => ({
@@ -50,14 +51,6 @@
return true;
};
-const getArgValue = arg => {
- if (arg.type === 'TemplateLiteral') {
- return arg.quasis[0].value.raw;
- }
-
- return arg.value;
-};
-
module.exports = {
meta: {
docs: {
@@ -76,7 +69,7 @@
if (!isFirstArgValid(firstArgument)) {
return;
}
- const title = getArgValue(firstArgument);
+ const title = getStringValue(firstArgument);
handleTestCaseTitles(context, currentLayer.testTitles, node, title);
handleDescribeBlockTitles(
context,

rules/__tests__/no-empty-title.js

@@ -0,0 +1,108 @@
+'use strict';
+
+const { RuleTester } = require('eslint');
+const rule = require('../no-empty-title');
+
+const ruleTester = new RuleTester({
+ parserOptions: {
+ sourceType: 'module',
+ },
+});
+
+ruleTester.run('no-empty-title', rule, {
+ valid: [
+ '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: [
+ {
+ message: rule.errorMessages.describe,
+ column: 1,
+ line: 1,
+ },
+ ],
+ },
+ {
+ code: ["describe('foo', () => {", "it('', () => {})", '})'].join('\n'),
+ errors: [
+ {
+ message: rule.errorMessages.test,
+ column: 1,
+ line: 2,
+ },
+ ],
+ },
+ {
+ code: 'it("", function () {})',
+ errors: [
+ {
+ message: rule.errorMessages.test,
+ column: 1,
+ line: 1,
+ },
+ ],
+ },
+ {
+ code: 'test("", function () {})',
+ errors: [
+ {
+ message: rule.errorMessages.test,
+ column: 1,
+ line: 1,
+ },
+ ],
+ },
+ {
+ code: 'test(``, function () {})',
+ errors: [
+ {
+ message: rule.errorMessages.test,
+ column: 1,
+ line: 1,
+ },
+ ],
+ },
+ {
+ code: "xdescribe('', () => {})",
+ errors: [
+ {
+ message: rule.errorMessages.describe,
+ column: 1,
+ line: 1,
+ },
+ ],
+ },
+ {
+ code: "xit('', () => {})",
+ errors: [
+ {
+ message: rule.errorMessages.test,
+ column: 1,
+ line: 1,
+ },
+ ],
+ },
+ {
+ code: "xtest('', () => {})",
+ errors: [
+ {
+ message: rule.errorMessages.test,
+ column: 1,
+ line: 1,
+ },
+ ],
+ },
+ ],
+});

rules/__tests__/no-identical-title.test.js

@@ -69,6 +69,12 @@
es6: true,
},
},
+ {
+ code: 'it(`${n}`, function() {});',
+ env: {
+ es6: true,
+ },
+ },
[
'describe("title " + foo, function() {',
' describe("describe1", function() {});',

rules/util.js

@@ -132,10 +132,15 @@
const isString = node =>
(node.type === 'Literal' && typeof node.value === 'string') ||
- node.type === 'TemplateLiteral';
+ isTemplateLiteral(node);
+
+const isTemplateLiteral = node => node.type === 'TemplateLiteral';
const hasExpressions = node => node.expressions && node.expressions.length > 0;
+const getStringValue = arg =>
+ isTemplateLiteral(arg) ? arg.quasis[0].value.raw : arg.value;
+
/**
* Generates the URL to documentation for the given rule name. It uses the
* package version to build the link to a tagged version of the
@@ -210,8 +215,10 @@
expectToEqualCase,
expectNotToEqualCase,
getNodeName,
+ getStringValue,
isDescribe,
isFunction,
+ isTemplateLiteral,
isTestCase,
isString,
hasExpressions,