eslint-plugin-jest 22.18.0 → 22.21.0
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/lowercase-name.md +16 -0
- package/docs/rules/valid-title.md +72 -0
- package/lib/__tests__/rules.test.js +1 -1
- package/lib/index.js +3 -1
- package/lib/rules/consistent-test-it.js +12 -12
- package/lib/rules/expect-expect.js +2 -2
- package/lib/rules/lowercase-name.js +16 -7
- package/lib/rules/no-empty-title.js +4 -4
- package/lib/rules/no-export.js +25 -6
- package/lib/rules/no-hooks.js +1 -1
- package/lib/rules/no-identical-title.js +5 -5
- package/lib/rules/no-mocks-import.js +1 -1
- package/lib/rules/no-test-callback.js +1 -1
- package/lib/rules/no-test-return-statement.js +1 -1
- package/lib/rules/prefer-expect-assertions.js +1 -1
- package/lib/rules/prefer-spy-on.js +1 -1
- package/lib/rules/prefer-to-contain.js +1 -1
- package/lib/rules/prefer-to-have-length.js +1 -1
- package/lib/rules/prefer-todo.js +1 -1
- package/lib/rules/utils.js +3 -5
- package/lib/rules/valid-describe.js +1 -1
- package/lib/rules/valid-expect-in-promise.js +1 -1
- package/lib/rules/valid-title.js +98 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -150,6 +150,7 @@ installations requiring long-term consistency.
|
|
|
150
150
|
| [valid-describe][] | Enforce valid `describe()` callback | ![recommended][] | |
|
|
151
151
|
| [valid-expect-in-promise][] | Enforce having return statement when testing with promises | ![recommended][] | |
|
|
152
152
|
| [valid-expect][] | Enforce valid `expect()` usage | ![recommended][] | |
|
|
153
|
+
| [valid-title][] | Enforce valid titles for jest blocks | | |
|
|
153
154
|
|
|
154
155
|
## Credit
|
|
155
156
|
|
|
@@ -205,6 +206,7 @@ https://github.com/dangreenisrael/eslint-plugin-jest-formatting
|
|
|
205
206
|
[valid-describe]: docs/rules/valid-describe.md
|
|
206
207
|
[valid-expect-in-promise]: docs/rules/valid-expect-in-promise.md
|
|
207
208
|
[valid-expect]: docs/rules/valid-expect.md
|
|
209
|
+
[valid-title]: docs/rules/valid-title.md
|
|
208
210
|
[fixable-green]: https://img.shields.io/badge/-fixable-green.svg
|
|
209
211
|
[fixable-yellow]: https://img.shields.io/badge/-fixable-yellow.svg
|
|
210
212
|
[recommended]: https://img.shields.io/badge/-recommended-lightgrey.svg
|
|
@@ -70,3 +70,19 @@ Example of **correct** code for the `{ "ignore": ["it"] }` option:
|
|
|
70
70
|
|
|
71
71
|
it('Uppercase description');
|
|
72
72
|
```
|
|
73
|
+
|
|
74
|
+
### `allow`
|
|
75
|
+
|
|
76
|
+
This array option whitelists prefixes that titles can start with with capitals.
|
|
77
|
+
This can be useful when writing tests for api endpoints, where you'd like to
|
|
78
|
+
prefix with the HTTP method.
|
|
79
|
+
|
|
80
|
+
By default, nothing is allowed (the equivalent of `{ "allow": [] }`).
|
|
81
|
+
|
|
82
|
+
Example of **correct** code for the `{ "allow": ["GET"] }` option:
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
/* eslint jest/lowercase-name: ["error", { "allow": ["GET"] }] */
|
|
86
|
+
|
|
87
|
+
describe('GET /live');
|
|
88
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# describe/test titles should be valid (valid-title)
|
|
2
|
+
|
|
3
|
+
Checks that the title of Jest blocks are valid by ensuring that titles are:
|
|
4
|
+
|
|
5
|
+
- not prefixed with their block name,
|
|
6
|
+
- have no leading or trailing spaces
|
|
7
|
+
|
|
8
|
+
## Rule Details
|
|
9
|
+
|
|
10
|
+
**duplicatePrefix**
|
|
11
|
+
|
|
12
|
+
A describe/ test block should not start with duplicatePrefix
|
|
13
|
+
|
|
14
|
+
Examples of **incorrect** code for this rule
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
test('test foo', () => {});
|
|
18
|
+
it('it foo', () => {});
|
|
19
|
+
|
|
20
|
+
describe('foo', () => {
|
|
21
|
+
test('test bar', () => {});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('describe foo', () => {
|
|
25
|
+
test('bar', () => {});
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Examples of **correct** code for this rule
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
test('foo', () => {});
|
|
33
|
+
it('foo', () => {});
|
|
34
|
+
|
|
35
|
+
describe('foo', () => {
|
|
36
|
+
test('bar', () => {});
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**accidentalSpace**
|
|
41
|
+
|
|
42
|
+
A describe/ test block should not contain accidentalSpace
|
|
43
|
+
|
|
44
|
+
Examples of **incorrect** code for this rule
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
test(' foo', () => {});
|
|
48
|
+
it(' foo', () => {});
|
|
49
|
+
|
|
50
|
+
describe('foo', () => {
|
|
51
|
+
test(' bar', () => {});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe(' foo', () => {
|
|
55
|
+
test('bar', () => {});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('foo ', () => {
|
|
59
|
+
test('bar', () => {});
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Examples of **correct** code for this rule
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
test('foo', () => {});
|
|
67
|
+
it('foo', () => {});
|
|
68
|
+
|
|
69
|
+
describe('foo', () => {
|
|
70
|
+
test('bar', () => {});
|
|
71
|
+
});
|
|
72
|
+
```
|
|
@@ -9,7 +9,7 @@ var _ = _interopRequireDefault(require("../"));
|
|
|
9
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
10
|
|
|
11
11
|
const ruleNames = Object.keys(_.default.rules);
|
|
12
|
-
const numberOfRules =
|
|
12
|
+
const numberOfRules = 41;
|
|
13
13
|
describe('rules', () => {
|
|
14
14
|
it('should have a corresponding doc for each rule', () => {
|
|
15
15
|
ruleNames.forEach(rule => {
|
package/lib/index.js
CHANGED
|
@@ -8,7 +8,9 @@ var _globals = _interopRequireDefault(require("./globals.json"));
|
|
|
8
8
|
|
|
9
9
|
var snapshotProcessor = _interopRequireWildcard(require("./processors/snapshot-processor"));
|
|
10
10
|
|
|
11
|
-
function
|
|
11
|
+
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
|
|
12
|
+
|
|
13
|
+
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
12
14
|
|
|
13
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
16
|
|
|
@@ -20,16 +20,16 @@ var _default = (0, _utils.createRule)({
|
|
|
20
20
|
fixable: 'code',
|
|
21
21
|
messages: {
|
|
22
22
|
consistentMethod: "Prefer using '{{ testKeyword }}' instead of '{{ oppositeTestKeyword }}'",
|
|
23
|
-
|
|
23
|
+
consistentMethodWithinDescribe: "Prefer using '{{ testKeywordWithinDescribe }}' instead of '{{ oppositeTestKeyword }}' within describe"
|
|
24
24
|
},
|
|
25
25
|
schema: [{
|
|
26
26
|
type: 'object',
|
|
27
27
|
properties: {
|
|
28
28
|
fn: {
|
|
29
|
-
enum: [
|
|
29
|
+
enum: [_utils.TestCaseName.it, _utils.TestCaseName.test]
|
|
30
30
|
},
|
|
31
31
|
withinDescribe: {
|
|
32
|
-
enum: [
|
|
32
|
+
enum: [_utils.TestCaseName.it, _utils.TestCaseName.test]
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
additionalProperties: false
|
|
@@ -37,14 +37,14 @@ var _default = (0, _utils.createRule)({
|
|
|
37
37
|
type: 'suggestion'
|
|
38
38
|
},
|
|
39
39
|
defaultOptions: [{
|
|
40
|
-
fn:
|
|
41
|
-
withinDescribe:
|
|
40
|
+
fn: _utils.TestCaseName.test,
|
|
41
|
+
withinDescribe: _utils.TestCaseName.it
|
|
42
42
|
}],
|
|
43
43
|
|
|
44
44
|
create(context) {
|
|
45
45
|
const configObj = context.options[0] || {};
|
|
46
|
-
const testKeyword = configObj.fn ||
|
|
47
|
-
const testKeywordWithinDescribe = configObj.withinDescribe || configObj.fn ||
|
|
46
|
+
const testKeyword = configObj.fn || _utils.TestCaseName.test;
|
|
47
|
+
const testKeywordWithinDescribe = configObj.withinDescribe || configObj.fn || _utils.TestCaseName.it;
|
|
48
48
|
let describeNestingLevel = 0;
|
|
49
49
|
return {
|
|
50
50
|
CallExpression(node) {
|
|
@@ -80,7 +80,7 @@ var _default = (0, _utils.createRule)({
|
|
|
80
80
|
if ((0, _utils.isTestCase)(node) && describeNestingLevel > 0 && !nodeName.includes(testKeywordWithinDescribe)) {
|
|
81
81
|
const oppositeTestKeyword = getOppositeTestKeyword(testKeywordWithinDescribe);
|
|
82
82
|
context.report({
|
|
83
|
-
messageId: '
|
|
83
|
+
messageId: 'consistentMethodWithinDescribe',
|
|
84
84
|
node: node.callee,
|
|
85
85
|
data: {
|
|
86
86
|
testKeywordWithinDescribe,
|
|
@@ -112,7 +112,7 @@ exports.default = _default;
|
|
|
112
112
|
|
|
113
113
|
function getPreferredNodeName(nodeName, preferredTestKeyword) {
|
|
114
114
|
switch (nodeName) {
|
|
115
|
-
case
|
|
115
|
+
case _utils.TestCaseName.fit:
|
|
116
116
|
return 'test.only';
|
|
117
117
|
|
|
118
118
|
default:
|
|
@@ -121,9 +121,9 @@ function getPreferredNodeName(nodeName, preferredTestKeyword) {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
function getOppositeTestKeyword(test) {
|
|
124
|
-
if (test ===
|
|
125
|
-
return
|
|
124
|
+
if (test === _utils.TestCaseName.test) {
|
|
125
|
+
return _utils.TestCaseName.it;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
return
|
|
128
|
+
return _utils.TestCaseName.test;
|
|
129
129
|
}
|
|
@@ -43,14 +43,14 @@ var _default = (0, _utils.createRule)({
|
|
|
43
43
|
}],
|
|
44
44
|
|
|
45
45
|
create(context, [{
|
|
46
|
-
assertFunctionNames
|
|
46
|
+
assertFunctionNames = ['expect']
|
|
47
47
|
}]) {
|
|
48
48
|
const unchecked = [];
|
|
49
49
|
return {
|
|
50
50
|
CallExpression(node) {
|
|
51
51
|
const name = (0, _utils.getNodeName)(node.callee);
|
|
52
52
|
|
|
53
|
-
if (name ===
|
|
53
|
+
if (name === _utils.TestCaseName.it || name === _utils.TestCaseName.test) {
|
|
54
54
|
unchecked.push(node);
|
|
55
55
|
} else if (name && assertFunctionNames.includes(name)) {
|
|
56
56
|
// Return early in case of nested `it` statements.
|
|
@@ -13,7 +13,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
13
13
|
|
|
14
14
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
15
|
|
|
16
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
|
@@ -35,10 +35,10 @@ const testDescription = argument => {
|
|
|
35
35
|
return argument.quasis[0].value.raw;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const jestFunctionName = node => {
|
|
38
|
+
const jestFunctionName = (node, allowedPrefixes) => {
|
|
39
39
|
const description = testDescription(node.arguments[0]);
|
|
40
40
|
|
|
41
|
-
if (description === null) {
|
|
41
|
+
if (description === null || allowedPrefixes.some(name => description.startsWith(name))) {
|
|
42
42
|
return null;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -74,7 +74,14 @@ var _default = (0, _utils.createRule)({
|
|
|
74
74
|
ignore: {
|
|
75
75
|
type: 'array',
|
|
76
76
|
items: {
|
|
77
|
-
enum: [
|
|
77
|
+
enum: [_utils.DescribeAlias.describe, _utils.TestCaseName.test, _utils.TestCaseName.it]
|
|
78
|
+
},
|
|
79
|
+
additionalItems: false
|
|
80
|
+
},
|
|
81
|
+
allowedPrefixes: {
|
|
82
|
+
type: 'array',
|
|
83
|
+
items: {
|
|
84
|
+
type: 'string'
|
|
78
85
|
},
|
|
79
86
|
additionalItems: false
|
|
80
87
|
}
|
|
@@ -83,11 +90,13 @@ var _default = (0, _utils.createRule)({
|
|
|
83
90
|
}]
|
|
84
91
|
},
|
|
85
92
|
defaultOptions: [{
|
|
86
|
-
ignore: []
|
|
93
|
+
ignore: [],
|
|
94
|
+
allowedPrefixes: []
|
|
87
95
|
}],
|
|
88
96
|
|
|
89
97
|
create(context, [{
|
|
90
|
-
ignore
|
|
98
|
+
ignore = [],
|
|
99
|
+
allowedPrefixes = []
|
|
91
100
|
}]) {
|
|
92
101
|
return {
|
|
93
102
|
CallExpression(node) {
|
|
@@ -95,7 +104,7 @@ var _default = (0, _utils.createRule)({
|
|
|
95
104
|
return;
|
|
96
105
|
}
|
|
97
106
|
|
|
98
|
-
const erroneousMethod = jestFunctionName(node);
|
|
107
|
+
const erroneousMethod = jestFunctionName(node, allowedPrefixes);
|
|
99
108
|
|
|
100
109
|
if (erroneousMethod && !ignore.includes(node.callee.name)) {
|
|
101
110
|
context.report({
|
|
@@ -11,7 +11,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
11
11
|
|
|
12
12
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
13
13
|
|
|
14
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
14
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
15
15
|
|
|
16
16
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
17
17
|
|
|
@@ -40,15 +40,15 @@ var _default = (0, _utils.createRule)({
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
const _node$arguments = _slicedToArray(node.arguments, 1),
|
|
43
|
-
|
|
43
|
+
argument = _node$arguments[0];
|
|
44
44
|
|
|
45
|
-
if (!
|
|
45
|
+
if (!argument || !(0, _utils.isStringNode)(argument, '')) {
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
context.report({
|
|
50
50
|
messageId: (0, _utils.isDescribe)(node) ? _utils.DescribeAlias.describe : _utils.TestCaseName.test,
|
|
51
|
-
node
|
|
51
|
+
node: argument
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
|
package/lib/rules/no-export.js
CHANGED
|
@@ -31,12 +31,31 @@ var _default = (0, _utils.createRule)({
|
|
|
31
31
|
return {
|
|
32
32
|
'Program:exit'() {
|
|
33
33
|
if (hasTestCase && exportNodes.length > 0) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
var _iteratorNormalCompletion = true;
|
|
35
|
+
var _didIteratorError = false;
|
|
36
|
+
var _iteratorError = undefined;
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
for (var _iterator = exportNodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
40
|
+
const node = _step.value;
|
|
41
|
+
context.report({
|
|
42
|
+
node,
|
|
43
|
+
messageId: 'unexpectedExport'
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
} catch (err) {
|
|
47
|
+
_didIteratorError = true;
|
|
48
|
+
_iteratorError = err;
|
|
49
|
+
} finally {
|
|
50
|
+
try {
|
|
51
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
52
|
+
_iterator.return();
|
|
53
|
+
}
|
|
54
|
+
} finally {
|
|
55
|
+
if (_didIteratorError) {
|
|
56
|
+
throw _iteratorError;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
40
59
|
}
|
|
41
60
|
}
|
|
42
61
|
},
|
package/lib/rules/no-hooks.js
CHANGED
|
@@ -11,7 +11,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
11
11
|
|
|
12
12
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
13
13
|
|
|
14
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
14
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
15
15
|
|
|
16
16
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
17
17
|
|
|
@@ -50,17 +50,17 @@ var _default = (0, _utils.createRule)({
|
|
|
50
50
|
const _node$arguments = _slicedToArray(node.arguments, 1),
|
|
51
51
|
argument = _node$arguments[0];
|
|
52
52
|
|
|
53
|
-
if (!argument || !(0, _utils.isStringNode)(argument)
|
|
53
|
+
if (!argument || !(0, _utils.isStringNode)(argument)) {
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
const title = (0, _utils.
|
|
57
|
+
const title = (0, _utils.getStringValue)(argument);
|
|
58
58
|
|
|
59
59
|
if ((0, _utils.isTestCase)(node)) {
|
|
60
60
|
if (currentLayer.testTitles.includes(title)) {
|
|
61
61
|
context.report({
|
|
62
62
|
messageId: 'multipleTestTitle',
|
|
63
|
-
node
|
|
63
|
+
node: argument
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -74,7 +74,7 @@ var _default = (0, _utils.createRule)({
|
|
|
74
74
|
if (currentLayer.describeTitles.includes(title)) {
|
|
75
75
|
context.report({
|
|
76
76
|
messageId: 'multipleDescribeTitle',
|
|
77
|
-
node
|
|
77
|
+
node: argument
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -13,7 +13,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
13
13
|
|
|
14
14
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
15
|
|
|
16
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
|
@@ -11,7 +11,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
11
11
|
|
|
12
12
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
13
13
|
|
|
14
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
14
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
15
15
|
|
|
16
16
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
17
17
|
|
|
@@ -11,7 +11,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
11
11
|
|
|
12
12
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
13
13
|
|
|
14
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
14
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
15
15
|
|
|
16
16
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
17
17
|
|
|
@@ -13,7 +13,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
13
13
|
|
|
14
14
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
15
|
|
|
16
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
13
13
|
|
|
14
14
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
15
|
|
|
16
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
13
13
|
|
|
14
14
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
15
|
|
|
16
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
13
13
|
|
|
14
14
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
15
|
|
|
16
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
package/lib/rules/prefer-todo.js
CHANGED
|
@@ -13,7 +13,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
13
13
|
|
|
14
14
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
15
|
|
|
16
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
package/lib/rules/utils.js
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getNodeName = getNodeName;
|
|
7
|
-
exports.scopeHasLocalReference = exports.isDescribe = exports.isTestCase = exports.isHook = exports.isFunction = exports.TestCaseProperty = exports.DescribeProperty = exports.HookName = exports.TestCaseName = exports.DescribeAlias = exports.parseExpectCall = exports.isParsedEqualityMatcherCall = exports.EqualityMatcher = exports.ModifierName = exports.isExpectMember = exports.isExpectCall = exports.getAccessorValue = exports.isSupportedAccessor = exports.hasOnlyOneArgument = exports.getStringValue = exports.isStringNode = exports.
|
|
7
|
+
exports.scopeHasLocalReference = exports.isDescribe = exports.isTestCase = exports.isHook = exports.isFunction = exports.TestCaseProperty = exports.DescribeProperty = exports.HookName = exports.TestCaseName = exports.DescribeAlias = exports.parseExpectCall = exports.isParsedEqualityMatcherCall = exports.EqualityMatcher = exports.ModifierName = exports.isExpectMember = exports.isExpectCall = exports.getAccessorValue = exports.isSupportedAccessor = exports.hasOnlyOneArgument = exports.getStringValue = exports.isStringNode = exports.followTypeAssertionChain = exports.createRule = void 0;
|
|
8
8
|
|
|
9
9
|
var _path = require("path");
|
|
10
10
|
|
|
@@ -67,10 +67,8 @@ const isStringLiteral = (node, value) => node.type === _experimentalUtils.AST_NO
|
|
|
67
67
|
*
|
|
68
68
|
* @template V
|
|
69
69
|
*/
|
|
70
|
-
const isTemplateLiteral = (node, value) => node.type === _experimentalUtils.AST_NODE_TYPES.TemplateLiteral &&
|
|
71
|
-
node.quasis[0].value.raw === value);
|
|
72
|
-
|
|
73
|
-
exports.isTemplateLiteral = isTemplateLiteral;
|
|
70
|
+
const isTemplateLiteral = (node, value) => node.type === _experimentalUtils.AST_NODE_TYPES.TemplateLiteral && node.quasis.length === 1 && ( // bail out if not simple
|
|
71
|
+
value === undefined || node.quasis[0].value.raw === value);
|
|
74
72
|
|
|
75
73
|
/**
|
|
76
74
|
* Checks if the given `node` is a {@link StringNode}.
|
|
@@ -13,7 +13,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
13
13
|
|
|
14
14
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
15
|
|
|
16
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
13
13
|
|
|
14
14
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
15
|
|
|
16
|
-
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
9
|
+
|
|
10
|
+
var _utils = require("./utils");
|
|
11
|
+
|
|
12
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
|
13
|
+
|
|
14
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
|
+
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
|
+
|
|
18
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
|
+
|
|
20
|
+
const trimFXprefix = word => ['f', 'x'].includes(word.charAt(0)) ? word.substr(1) : word;
|
|
21
|
+
|
|
22
|
+
var _default = (0, _utils.createRule)({
|
|
23
|
+
name: __filename,
|
|
24
|
+
meta: {
|
|
25
|
+
docs: {
|
|
26
|
+
category: 'Best Practices',
|
|
27
|
+
description: 'Enforce valid titles',
|
|
28
|
+
recommended: false
|
|
29
|
+
},
|
|
30
|
+
messages: {
|
|
31
|
+
duplicatePrefix: 'should not have duplicate prefix',
|
|
32
|
+
accidentalSpace: 'should not have leading or trailing spaces'
|
|
33
|
+
},
|
|
34
|
+
type: 'suggestion',
|
|
35
|
+
schema: [],
|
|
36
|
+
fixable: 'code'
|
|
37
|
+
},
|
|
38
|
+
defaultOptions: [],
|
|
39
|
+
|
|
40
|
+
create(context) {
|
|
41
|
+
return {
|
|
42
|
+
CallExpression(node) {
|
|
43
|
+
if (!((0, _utils.isDescribe)(node) || (0, _utils.isTestCase)(node)) || !node.arguments.length) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const _node$arguments = _slicedToArray(node.arguments, 1),
|
|
48
|
+
argument = _node$arguments[0];
|
|
49
|
+
|
|
50
|
+
if (!(0, _utils.isStringNode)(argument)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const title = (0, _utils.getStringValue)(argument);
|
|
55
|
+
|
|
56
|
+
if (!title) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (title.trim().length !== title.length) {
|
|
61
|
+
context.report({
|
|
62
|
+
messageId: 'accidentalSpace',
|
|
63
|
+
node: argument,
|
|
64
|
+
|
|
65
|
+
fix(fixer) {
|
|
66
|
+
const stringValue = argument.type === _experimentalUtils.AST_NODE_TYPES.TemplateLiteral ? `\`${argument.quasis[0].value.raw}\`` : argument.raw;
|
|
67
|
+
return [fixer.replaceTextRange(argument.range, stringValue.replace(/^([`'"]) +?/, '$1').replace(/ +?([`'"])$/, '$1'))];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const nodeName = trimFXprefix((0, _utils.getNodeName)(node.callee));
|
|
74
|
+
|
|
75
|
+
const _title$split = title.split(' '),
|
|
76
|
+
_title$split2 = _slicedToArray(_title$split, 1),
|
|
77
|
+
firstWord = _title$split2[0];
|
|
78
|
+
|
|
79
|
+
if (firstWord.toLowerCase() === nodeName) {
|
|
80
|
+
context.report({
|
|
81
|
+
messageId: 'duplicatePrefix',
|
|
82
|
+
node: argument,
|
|
83
|
+
|
|
84
|
+
fix(fixer) {
|
|
85
|
+
const stringValue = argument.type === _experimentalUtils.AST_NODE_TYPES.TemplateLiteral ? `\`${argument.quasis[0].value.raw}\`` : argument.raw;
|
|
86
|
+
return [fixer.replaceTextRange(argument.range, stringValue.replace(/^([`'"]).+? /, '$1'))];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
exports.default = _default;
|