eslint-plugin-jest 22.3.0 → 22.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/docs/rules/no-empty-title.md +36 -0
- package/index.js +12 -60
- package/package.json +2 -2
- package/rules/__tests__/no-empty-title.js +108 -0
- package/rules/__tests__/no-identical-title.test.js +53 -0
- package/rules/no-empty-title.js +54 -0
- package/rules/no-identical-title.js +20 -6
- package/rules/util.js +11 -1
package/README.md
CHANGED
|
@@ -96,6 +96,7 @@ for more information about extending configuration files.
|
|
|
96
96
|
| [lowercase-name][] | Disallow capitalized test names | | ![fixable-green][] |
|
|
97
97
|
| [no-alias-methods][] | Disallow alias methods | ![recommended][] | ![fixable-green][] |
|
|
98
98
|
| [no-disabled-tests][] | Disallow disabled tests | ![recommended][] | |
|
|
99
|
+
| [no-empty-title][] | Disallow empty titles | | |
|
|
99
100
|
| [no-focused-tests][] | Disallow focused tests | ![recommended][] | |
|
|
100
101
|
| [no-hooks][] | Disallow setup and teardown hooks | | |
|
|
101
102
|
| [no-identical-title][] | Disallow identical titles | ![recommended][] | |
|
|
@@ -131,6 +132,7 @@ for more information about extending configuration files.
|
|
|
131
132
|
[lowercase-name]: docs/rules/lowercase-name.md
|
|
132
133
|
[no-alias-methods]: docs/rules/no-alias-methods.md
|
|
133
134
|
[no-disabled-tests]: docs/rules/no-disabled-tests.md
|
|
135
|
+
[no-empty-title]: docs/rules/no-empty-title.md
|
|
134
136
|
[no-focused-tests]: docs/rules/no-focused-tests.md
|
|
135
137
|
[no-hooks]: docs/rules/no-hooks.md
|
|
136
138
|
[no-identical-title]: docs/rules/no-identical-title.md
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Disallow empty titles
|
|
2
|
+
|
|
3
|
+
Having an empty string as your test title is pretty useless. This rule reports
|
|
4
|
+
an error if it finds an empty string as s test title.
|
|
5
|
+
|
|
6
|
+
This rule is not auto-fixable.
|
|
7
|
+
|
|
8
|
+
## Rule Details
|
|
9
|
+
|
|
10
|
+
The following patterns are considered warnings:
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
describe('', () => {});
|
|
14
|
+
describe('foo', () => {
|
|
15
|
+
it('', () => {});
|
|
16
|
+
});
|
|
17
|
+
it('', () => {});
|
|
18
|
+
test('', () => {});
|
|
19
|
+
xdescribe('', () => {});
|
|
20
|
+
xit('', () => {});
|
|
21
|
+
xtest('', () => {});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
These patterns would not be considered warnings:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
describe('foo', () => {});
|
|
28
|
+
describe('foo', () => {
|
|
29
|
+
it('bar', () => {});
|
|
30
|
+
});
|
|
31
|
+
test('foo', () => {});
|
|
32
|
+
it('foo', () => {});
|
|
33
|
+
xdescribe('foo', () => {});
|
|
34
|
+
xit('foo', () => {});
|
|
35
|
+
xtest('foo', () => {});
|
|
36
|
+
```
|
package/index.js
CHANGED
|
@@ -1,34 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const noTestReturnStatement = require('./rules/no-test-return-statement');
|
|
15
|
-
const preferSpyOn = require('./rules/prefer-spy-on');
|
|
16
|
-
const preferToBeNull = require('./rules/prefer-to-be-null');
|
|
17
|
-
const preferToBeUndefined = require('./rules/prefer-to-be-undefined');
|
|
18
|
-
const preferToContain = require('./rules/prefer-to-contain');
|
|
19
|
-
const preferToHaveLength = require('./rules/prefer-to-have-length');
|
|
20
|
-
const validDescribe = require('./rules/valid-describe');
|
|
21
|
-
const validExpect = require('./rules/valid-expect');
|
|
22
|
-
const preferExpectAssertions = require('./rules/prefer-expect-assertions');
|
|
23
|
-
const validExpectInPromise = require('./rules/valid-expect-in-promise');
|
|
24
|
-
const preferInlineSnapshots = require('./rules/prefer-inline-snapshots');
|
|
25
|
-
const preferStrictEqual = require('./rules/prefer-strict-equal');
|
|
26
|
-
const requireTothrowMessage = require('./rules/require-tothrow-message');
|
|
27
|
-
const noAliasMethods = require('./rules/no-alias-methods');
|
|
28
|
-
const noTestCallback = require('./rules/no-test-callback');
|
|
29
|
-
const noTruthyFalsy = require('./rules/no-truthy-falsy');
|
|
30
|
-
const preferTodo = require('./rules/prefer-todo');
|
|
31
|
-
const preferCalledWith = require('./rules/prefer-called-with');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const rules = fs
|
|
7
|
+
.readdirSync(path.join(__dirname, 'rules'))
|
|
8
|
+
.filter(rule => rule !== '__tests__' && rule !== 'util.js')
|
|
9
|
+
.map(rule => path.basename(rule, '.js'))
|
|
10
|
+
.reduce(
|
|
11
|
+
(acc, curr) => Object.assign(acc, { [curr]: require(`./rules/${curr}`) }),
|
|
12
|
+
{}
|
|
13
|
+
);
|
|
32
14
|
|
|
33
15
|
const snapshotProcessor = require('./processors/snapshot-processor');
|
|
34
16
|
|
|
@@ -88,35 +70,5 @@ module.exports = {
|
|
|
88
70
|
processors: {
|
|
89
71
|
'.snap': snapshotProcessor,
|
|
90
72
|
},
|
|
91
|
-
rules
|
|
92
|
-
'consistent-test-it': consistentTestIt,
|
|
93
|
-
'expect-expect': expectExpect,
|
|
94
|
-
'lowercase-name': lowercaseName,
|
|
95
|
-
'no-disabled-tests': noDisabledTests,
|
|
96
|
-
'no-focused-tests': noFocusedTests,
|
|
97
|
-
'no-hooks': noHooks,
|
|
98
|
-
'no-identical-title': noIdenticalTitle,
|
|
99
|
-
'no-jasmine-globals': noJasmineGlobals,
|
|
100
|
-
'no-jest-import': noJestImport,
|
|
101
|
-
'no-large-snapshots': noLargeSnapshots,
|
|
102
|
-
'no-test-prefixes': noTestPrefixes,
|
|
103
|
-
'no-test-return-statement': noTestReturnStatement,
|
|
104
|
-
'prefer-spy-on': preferSpyOn,
|
|
105
|
-
'prefer-to-be-null': preferToBeNull,
|
|
106
|
-
'prefer-to-be-undefined': preferToBeUndefined,
|
|
107
|
-
'prefer-to-contain': preferToContain,
|
|
108
|
-
'prefer-to-have-length': preferToHaveLength,
|
|
109
|
-
'valid-describe': validDescribe,
|
|
110
|
-
'valid-expect': validExpect,
|
|
111
|
-
'prefer-expect-assertions': preferExpectAssertions,
|
|
112
|
-
'valid-expect-in-promise': validExpectInPromise,
|
|
113
|
-
'prefer-inline-snapshots': preferInlineSnapshots,
|
|
114
|
-
'prefer-strict-equal': preferStrictEqual,
|
|
115
|
-
'require-tothrow-message': requireTothrowMessage,
|
|
116
|
-
'no-alias-methods': noAliasMethods,
|
|
117
|
-
'no-test-callback': noTestCallback,
|
|
118
|
-
'no-truthy-falsy': noTruthyFalsy,
|
|
119
|
-
'prefer-todo': preferTodo,
|
|
120
|
-
'prefer-called-with': preferCalledWith,
|
|
121
|
-
},
|
|
73
|
+
rules,
|
|
122
74
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-jest",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.4.1",
|
|
4
4
|
"description": "Eslint rules for Jest",
|
|
5
5
|
"repository": "jest-community/eslint-plugin-jest",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@commitlint/cli": "^7.0.0",
|
|
36
36
|
"@commitlint/config-conventional": "^7.0.1",
|
|
37
37
|
"eslint": "^5.1.0",
|
|
38
|
-
"eslint-config-prettier": "^
|
|
38
|
+
"eslint-config-prettier": "^4.1.0",
|
|
39
39
|
"eslint-plugin-eslint-plugin": "^2.0.0",
|
|
40
40
|
"eslint-plugin-node": "^8.0.0",
|
|
41
41
|
"eslint-plugin-prettier": "^3.0.0",
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { RuleTester } = require('eslint');
|
|
4
|
+
const rule = require('../no-empty-title');
|
|
5
|
+
|
|
6
|
+
const ruleTester = new RuleTester({
|
|
7
|
+
parserOptions: {
|
|
8
|
+
sourceType: 'module',
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
ruleTester.run('no-empty-title', rule, {
|
|
13
|
+
valid: [
|
|
14
|
+
'someFn("", function () {})',
|
|
15
|
+
'describe(1, function () {})',
|
|
16
|
+
'describe("foo", function () {})',
|
|
17
|
+
'describe("foo", function () { it("bar", function () {}) })',
|
|
18
|
+
'test("foo", function () {})',
|
|
19
|
+
'test(`foo`, function () {})',
|
|
20
|
+
'test(`${foo}`, function () {})',
|
|
21
|
+
"it('foo', function () {})",
|
|
22
|
+
"xdescribe('foo', function () {})",
|
|
23
|
+
"xit('foo', function () {})",
|
|
24
|
+
"xtest('foo', function () {})",
|
|
25
|
+
],
|
|
26
|
+
invalid: [
|
|
27
|
+
{
|
|
28
|
+
code: 'describe("", function () {})',
|
|
29
|
+
errors: [
|
|
30
|
+
{
|
|
31
|
+
message: rule.errorMessages.describe,
|
|
32
|
+
column: 1,
|
|
33
|
+
line: 1,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
code: ["describe('foo', () => {", "it('', () => {})", '})'].join('\n'),
|
|
39
|
+
errors: [
|
|
40
|
+
{
|
|
41
|
+
message: rule.errorMessages.test,
|
|
42
|
+
column: 1,
|
|
43
|
+
line: 2,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
code: 'it("", function () {})',
|
|
49
|
+
errors: [
|
|
50
|
+
{
|
|
51
|
+
message: rule.errorMessages.test,
|
|
52
|
+
column: 1,
|
|
53
|
+
line: 1,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
code: 'test("", function () {})',
|
|
59
|
+
errors: [
|
|
60
|
+
{
|
|
61
|
+
message: rule.errorMessages.test,
|
|
62
|
+
column: 1,
|
|
63
|
+
line: 1,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
code: 'test(``, function () {})',
|
|
69
|
+
errors: [
|
|
70
|
+
{
|
|
71
|
+
message: rule.errorMessages.test,
|
|
72
|
+
column: 1,
|
|
73
|
+
line: 1,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
code: "xdescribe('', () => {})",
|
|
79
|
+
errors: [
|
|
80
|
+
{
|
|
81
|
+
message: rule.errorMessages.describe,
|
|
82
|
+
column: 1,
|
|
83
|
+
line: 1,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
code: "xit('', () => {})",
|
|
89
|
+
errors: [
|
|
90
|
+
{
|
|
91
|
+
message: rule.errorMessages.test,
|
|
92
|
+
column: 1,
|
|
93
|
+
line: 1,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
code: "xtest('', () => {})",
|
|
99
|
+
errors: [
|
|
100
|
+
{
|
|
101
|
+
message: rule.errorMessages.test,
|
|
102
|
+
column: 1,
|
|
103
|
+
line: 1,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
});
|
|
@@ -12,6 +12,8 @@ ruleTester.run('no-identical-title', rule, {
|
|
|
12
12
|
' it("it", function() {});',
|
|
13
13
|
'});',
|
|
14
14
|
].join('\n'),
|
|
15
|
+
['describe();describe();'].join('\n'),
|
|
16
|
+
['it();it();'].join('\n'),
|
|
15
17
|
[
|
|
16
18
|
'describe("describe1", function() {',
|
|
17
19
|
' it("it1", function() {});',
|
|
@@ -67,6 +69,12 @@ ruleTester.run('no-identical-title', rule, {
|
|
|
67
69
|
es6: true,
|
|
68
70
|
},
|
|
69
71
|
},
|
|
72
|
+
{
|
|
73
|
+
code: 'it(`${n}`, function() {});',
|
|
74
|
+
env: {
|
|
75
|
+
es6: true,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
70
78
|
[
|
|
71
79
|
'describe("title " + foo, function() {',
|
|
72
80
|
' describe("describe1", function() {});',
|
|
@@ -81,6 +89,32 @@ ruleTester.run('no-identical-title', rule, {
|
|
|
81
89
|
' });',
|
|
82
90
|
'});',
|
|
83
91
|
].join('\n'),
|
|
92
|
+
{
|
|
93
|
+
code: [
|
|
94
|
+
'describe("describe", () => {',
|
|
95
|
+
' it(`testing ${someVar} with the same title`, () => {});',
|
|
96
|
+
' it(`testing ${someVar} with the same title`, () => {});',
|
|
97
|
+
'});',
|
|
98
|
+
].join('\n'),
|
|
99
|
+
env: {
|
|
100
|
+
es6: true,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
code: ['it(`it1`, () => {});', 'it(`it2`, () => {});'].join('\n'),
|
|
105
|
+
env: {
|
|
106
|
+
es6: true,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
code: [
|
|
111
|
+
'describe(`describe1`, () => {});',
|
|
112
|
+
'describe(`describe2`, () => {});',
|
|
113
|
+
].join('\n'),
|
|
114
|
+
env: {
|
|
115
|
+
es6: true,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
84
118
|
],
|
|
85
119
|
|
|
86
120
|
invalid: [
|
|
@@ -212,5 +246,24 @@ ruleTester.run('no-identical-title', rule, {
|
|
|
212
246
|
},
|
|
213
247
|
],
|
|
214
248
|
},
|
|
249
|
+
{
|
|
250
|
+
code: [
|
|
251
|
+
'describe("describe", () => {',
|
|
252
|
+
' it(`testing backticks with the same title`, () => {});',
|
|
253
|
+
' it(`testing backticks with the same title`, () => {});',
|
|
254
|
+
'});',
|
|
255
|
+
].join('\n'),
|
|
256
|
+
env: {
|
|
257
|
+
es6: true,
|
|
258
|
+
},
|
|
259
|
+
errors: [
|
|
260
|
+
{
|
|
261
|
+
message:
|
|
262
|
+
'Test title is used multiple times in the same describe block.',
|
|
263
|
+
column: 5,
|
|
264
|
+
line: 3,
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
},
|
|
215
268
|
],
|
|
216
269
|
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
getDocsUrl,
|
|
5
|
+
hasExpressions,
|
|
6
|
+
isDescribe,
|
|
7
|
+
isTestCase,
|
|
8
|
+
isTemplateLiteral,
|
|
9
|
+
isString,
|
|
10
|
+
getStringValue,
|
|
11
|
+
} = require('./util');
|
|
12
|
+
|
|
13
|
+
const errorMessages = {
|
|
14
|
+
describe: 'describe should not have an empty title',
|
|
15
|
+
test: 'test should not have an empty title',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
meta: {
|
|
20
|
+
docs: {
|
|
21
|
+
url: getDocsUrl(__filename),
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
create(context) {
|
|
25
|
+
return {
|
|
26
|
+
CallExpression(node) {
|
|
27
|
+
const is = {
|
|
28
|
+
describe: isDescribe(node),
|
|
29
|
+
testCase: isTestCase(node),
|
|
30
|
+
};
|
|
31
|
+
if (!is.describe && !is.testCase) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const [firstArgument] = node.arguments;
|
|
35
|
+
if (!isString(firstArgument)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (isTemplateLiteral(firstArgument) && hasExpressions(firstArgument)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (getStringValue(firstArgument) === '') {
|
|
42
|
+
const message = is.describe
|
|
43
|
+
? errorMessages.describe
|
|
44
|
+
: errorMessages.test;
|
|
45
|
+
context.report({
|
|
46
|
+
message,
|
|
47
|
+
node,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
errorMessages,
|
|
54
|
+
};
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
getDocsUrl,
|
|
5
|
+
isDescribe,
|
|
6
|
+
isTestCase,
|
|
7
|
+
isString,
|
|
8
|
+
hasExpressions,
|
|
9
|
+
getStringValue,
|
|
10
|
+
} = require('./util');
|
|
4
11
|
|
|
5
12
|
const newDescribeContext = () => ({
|
|
6
13
|
describeTitles: [],
|
|
@@ -34,8 +41,15 @@ const handleDescribeBlockTitles = (context, titles, node, title) => {
|
|
|
34
41
|
titles.push(title);
|
|
35
42
|
};
|
|
36
43
|
|
|
37
|
-
const
|
|
38
|
-
|
|
44
|
+
const isFirstArgValid = arg => {
|
|
45
|
+
if (!arg || !isString(arg)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
if (arg.type === 'TemplateLiteral' && hasExpressions(arg)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
};
|
|
39
53
|
|
|
40
54
|
module.exports = {
|
|
41
55
|
meta: {
|
|
@@ -51,11 +65,11 @@ module.exports = {
|
|
|
51
65
|
if (isDescribe(node)) {
|
|
52
66
|
contexts.push(newDescribeContext());
|
|
53
67
|
}
|
|
54
|
-
|
|
68
|
+
const [firstArgument] = node.arguments;
|
|
69
|
+
if (!isFirstArgValid(firstArgument)) {
|
|
55
70
|
return;
|
|
56
71
|
}
|
|
57
|
-
|
|
58
|
-
const title = node.arguments[0].value;
|
|
72
|
+
const title = getStringValue(firstArgument);
|
|
59
73
|
handleTestCaseTitles(context, currentLayer.testTitles, node, title);
|
|
60
74
|
handleDescribeBlockTitles(
|
|
61
75
|
context,
|
package/rules/util.js
CHANGED
|
@@ -132,7 +132,14 @@ const isFunction = node =>
|
|
|
132
132
|
|
|
133
133
|
const isString = node =>
|
|
134
134
|
(node.type === 'Literal' && typeof node.value === 'string') ||
|
|
135
|
-
node
|
|
135
|
+
isTemplateLiteral(node);
|
|
136
|
+
|
|
137
|
+
const isTemplateLiteral = node => node.type === 'TemplateLiteral';
|
|
138
|
+
|
|
139
|
+
const hasExpressions = node => node.expressions && node.expressions.length > 0;
|
|
140
|
+
|
|
141
|
+
const getStringValue = arg =>
|
|
142
|
+
isTemplateLiteral(arg) ? arg.quasis[0].value.raw : arg.value;
|
|
136
143
|
|
|
137
144
|
/**
|
|
138
145
|
* Generates the URL to documentation for the given rule name. It uses the
|
|
@@ -208,10 +215,13 @@ module.exports = {
|
|
|
208
215
|
expectToEqualCase,
|
|
209
216
|
expectNotToEqualCase,
|
|
210
217
|
getNodeName,
|
|
218
|
+
getStringValue,
|
|
211
219
|
isDescribe,
|
|
212
220
|
isFunction,
|
|
221
|
+
isTemplateLiteral,
|
|
213
222
|
isTestCase,
|
|
214
223
|
isString,
|
|
224
|
+
hasExpressions,
|
|
215
225
|
getDocsUrl,
|
|
216
226
|
scopeHasLocalReference,
|
|
217
227
|
composeFixers,
|