Skip to content

Commit 2a8ac30

Browse files
authored
chore: minor tidy up of code (#603)
* test: ensure `cwd` is restored after each test * chore: add `eslint-plugin-eslint-config` * chore: replace `ban-ts-ignore` with `ban-ts-comment` rule * chore: enable `padding-line-between-statements` rule * chore: remove some unneeded conditional checks * chore: use correct jsdoc syntax for optional params
1 parent 0456d2e commit 2a8ac30

25 files changed

+87
-18
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
coverage/
22
lib/
3+
!.eslintrc.js

.eslintrc.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const globals = require('./src/globals.json');
55
module.exports = {
66
parser: require.resolve('@typescript-eslint/parser'),
77
extends: [
8+
'plugin:eslint-config/rc',
89
'plugin:eslint-plugin/recommended',
910
'plugin:eslint-comments/recommended',
1011
'plugin:node/recommended',
@@ -13,6 +14,7 @@ module.exports = {
1314
'prettier/@typescript-eslint',
1415
],
1516
plugins: [
17+
'eslint-config',
1618
'eslint-plugin',
1719
'eslint-comments',
1820
'node',
@@ -30,7 +32,7 @@ module.exports = {
3032
rules: {
3133
'@typescript-eslint/array-type': ['error', { default: 'array-simple' }],
3234
'@typescript-eslint/no-require-imports': 'error',
33-
'@typescript-eslint/ban-ts-ignore': 'warn',
35+
'@typescript-eslint/ban-ts-comment': 'warn',
3436
'@typescript-eslint/ban-types': 'error',
3537
'@typescript-eslint/no-unused-vars': 'error',
3638
'eslint-comments/no-unused-disable': 'error',
@@ -58,6 +60,18 @@ module.exports = {
5860
'error',
5961
{ alphabetize: { order: 'asc' }, 'newlines-between': 'never' },
6062
],
63+
'padding-line-between-statements': [
64+
'error',
65+
{ blankLine: 'always', prev: '*', next: 'return' },
66+
{ blankLine: 'always', prev: ['const', 'let', 'var'], next: '*' },
67+
{
68+
blankLine: 'any',
69+
prev: ['const', 'let', 'var'],
70+
next: ['const', 'let', 'var'],
71+
},
72+
{ blankLine: 'always', prev: 'directive', next: '*' },
73+
{ blankLine: 'any', prev: 'directive', next: 'directive' },
74+
],
6175
},
6276
overrides: [
6377
{

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
"eslint": "^5.1.0 || ^6.0.0",
110110
"eslint-config-prettier": "^6.5.0",
111111
"eslint-plugin-eslint-comments": "^3.1.2",
112+
"eslint-plugin-eslint-config": "^1.0.2",
112113
"eslint-plugin-eslint-plugin": "^2.0.0",
113114
"eslint-plugin-import": "^2.20.2",
114115
"eslint-plugin-node": "^11.0.0",

src/__tests__/rules.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ describe('rules', () => {
3636

3737
it('should have the correct amount of rules', () => {
3838
const { length } = ruleNames;
39+
3940
if (length !== numberOfRules) {
4041
throw new Error(
4142
`There should be exactly ${numberOfRules} rules, but there are ${length}. If you've added a new rule, please update this number.`,
@@ -65,6 +66,7 @@ describe('rules', () => {
6566
allConfigRules.forEach(rule => {
6667
const ruleNamePrefix = 'jest/';
6768
const ruleName = rule.slice(ruleNamePrefix.length);
69+
6870
expect(rule.startsWith(ruleNamePrefix)).toBe(true);
6971
expect(ruleNames).toContain(ruleName);
7072
// eslint-disable-next-line @typescript-eslint/no-require-imports

src/rules/expect-expect.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ function matchesAssertFunctionName(
3131
.split('.')
3232
.map(x => {
3333
if (x === '**') return '[a-z\\.]*';
34+
3435
return x.replace(/\*/gu, '[a-z]*');
3536
})
3637
.join('\\.')}(\\.|$)`,
@@ -97,6 +98,7 @@ export default createRule<
9798
return {
9899
CallExpression(node) {
99100
const name = getNodeName(node.callee);
101+
100102
if (name === TestCaseName.it || name === TestCaseName.test) {
101103
unchecked.push(node);
102104
} else if (

src/rules/lowercase-name.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const jestFunctionName = (
4343
allowedPrefixes: readonly string[],
4444
) => {
4545
const description = getStringValue(node.arguments[0]);
46+
4647
if (allowedPrefixes.some(name => description.startsWith(name))) {
4748
return null;
4849
}

src/rules/no-alias-methods.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export default createRule({
4545
}
4646

4747
const alias = matcher.name;
48+
4849
if (alias in methodNames) {
4950
const canonical = methodNames[alias];
5051

src/rules/no-duplicate-hooks.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export default createRule({
2424
defaultOptions: [],
2525
create(context) {
2626
const hookContexts = [newHookContext()];
27+
2728
return {
2829
CallExpression(node) {
2930
if (isDescribe(node)) {
@@ -32,6 +33,7 @@ export default createRule({
3233

3334
if (isHook(node)) {
3435
const currentLayer = hookContexts[hookContexts.length - 1];
36+
3537
currentLayer[node.callee.name] += 1;
3638
if (currentLayer[node.callee.name] > 1) {
3739
context.report({

src/rules/no-focused-tests.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ interface ConcurrentExpression extends TSESTree.MemberExpressionComputedName {
2424
const isConcurrentExpression = (
2525
expression: TSESTree.MemberExpression,
2626
): expression is ConcurrentExpression =>
27-
expression.type === AST_NODE_TYPES.MemberExpression &&
2827
isSupportedAccessor(expression.property, TestCaseProperty.concurrent) &&
2928
!!expression.parent &&
3029
expression.parent.type === AST_NODE_TYPES.MemberExpression;
@@ -72,6 +71,7 @@ export default createRule({
7271
isCallToFocusedTestFunction(callee.object)
7372
) {
7473
context.report({ messageId: 'focusedTest', node: callee.object });
74+
7575
return;
7676
}
7777

@@ -83,11 +83,13 @@ export default createRule({
8383
messageId: 'focusedTest',
8484
node: callee.object.property,
8585
});
86+
8687
return;
8788
}
8889

8990
if (isCallToTestOnlyFunction(callee)) {
9091
context.report({ messageId: 'focusedTest', node: callee.property });
92+
9193
return;
9294
}
9395
}

src/rules/no-identical-title.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,16 @@ export default createRule({
3636
defaultOptions: [],
3737
create(context) {
3838
const contexts = [newDescribeContext()];
39+
3940
return {
4041
CallExpression(node) {
4142
const currentLayer = contexts[contexts.length - 1];
43+
4244
if (isDescribe(node)) {
4345
contexts.push(newDescribeContext());
4446
}
4547
const [argument] = node.arguments;
48+
4649
if (!argument || !isStringNode(argument)) {
4750
return;
4851
}

src/rules/no-jasmine-globals.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export default createRule({
6767
context.report({ node, messageId: 'illegalPending' });
6868
break;
6969
}
70+
7071
return;
7172
}
7273

@@ -92,6 +93,7 @@ export default createRule({
9293
replacement: `expect.${functionName}`,
9394
},
9495
});
96+
9597
return;
9698
}
9799

@@ -104,6 +106,7 @@ export default createRule({
104106
replacement: 'expect.extend',
105107
},
106108
});
109+
107110
return;
108111
}
109112

@@ -116,6 +119,7 @@ export default createRule({
116119
replacement: 'jest.fn',
117120
},
118121
});
122+
119123
return;
120124
}
121125

@@ -141,6 +145,7 @@ export default createRule({
141145
node,
142146
messageId: 'illegalJasmine',
143147
});
148+
144149
return;
145150
}
146151
}

src/rules/no-large-snapshots.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ const reportOnViolation = (
4343
let isWhitelisted = false;
4444

4545
if (
46-
whitelistedSnapshots &&
4746
node.type === AST_NODE_TYPES.ExpressionStatement &&
4847
'left' in node.expression &&
4948
isExpectMember(node.expression.left)
@@ -53,6 +52,7 @@ const reportOnViolation = (
5352

5453
if (whitelistedSnapshotsInFile) {
5554
const snapshotName = getAccessorValue(node.expression.left.property);
55+
5656
isWhitelisted = whitelistedSnapshotsInFile.some(name => {
5757
if (name instanceof RegExp) {
5858
return name.test(snapshotName);

src/rules/no-mocks-import.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default createRule({
2828
create(context) {
2929
return {
3030
ImportDeclaration(node: TSESTree.ImportDeclaration) {
31-
if (node.source && isMockImportLiteral(node.source)) {
31+
if (isMockImportLiteral(node.source)) {
3232
context.report({ node, messageId: 'noManualImport' });
3333
}
3434
},

src/rules/no-standalone-expect.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const getBlockType = (
2929
}
3030
if (isFunction(func) && func.parent) {
3131
const expr = func.parent;
32+
3233
// arrowfunction or function expr
3334
if (expr.type === AST_NODE_TYPES.VariableDeclarator) {
3435
return 'function';
@@ -38,6 +39,7 @@ const getBlockType = (
3839
return DescribeAlias.describe;
3940
}
4041
}
42+
4143
return null;
4244
};
4345

@@ -78,9 +80,11 @@ export default createRule({
7880
CallExpression(node) {
7981
if (isExpectCall(node)) {
8082
const parent = callStack[callStack.length - 1];
83+
8184
if (!parent || parent === DescribeAlias.describe) {
8285
context.report({ node, messageId: 'unexpectedExpect' });
8386
}
87+
8488
return;
8589
}
8690
if (isTestCase(node)) {
@@ -92,6 +96,7 @@ export default createRule({
9296
},
9397
'CallExpression:exit'(node: TSESTree.CallExpression) {
9498
const top = callStack[callStack.length - 1];
99+
95100
if (
96101
(((isTestCase(node) &&
97102
node.callee.type !== AST_NODE_TYPES.MemberExpression) ||
@@ -105,12 +110,14 @@ export default createRule({
105110
},
106111
BlockStatement(stmt) {
107112
const blockType = getBlockType(stmt);
113+
108114
if (blockType) {
109115
callStack.push(blockType);
110116
}
111117
},
112118
'BlockStatement:exit'(stmt: TSESTree.BlockStatement) {
113119
const blockType = getBlockType(stmt);
120+
114121
if (blockType && blockType === callStack[callStack.length - 1]) {
115122
callStack.pop();
116123
}

src/rules/no-test-return-statement.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const getBody = (args: TSESTree.Expression[]) => {
2020
) {
2121
return secondArg.body.body;
2222
}
23+
2324
return [];
2425
};
2526

@@ -46,6 +47,7 @@ export default createRule({
4647
const returnStmt = body.find(
4748
t => t.type === AST_NODE_TYPES.ReturnStatement,
4849
);
50+
4951
if (!returnStmt) return;
5052

5153
context.report({ messageId: 'noReturnValue', node: returnStmt });
@@ -55,11 +57,13 @@ export default createRule({
5557
const testCallExpressions = getTestCallExpressionsFromDeclaredVariables(
5658
declaredVariables,
5759
);
60+
5861
if (testCallExpressions.length === 0) return;
5962

6063
const returnStmt = node.body.body.find(
6164
t => t.type === AST_NODE_TYPES.ReturnStatement,
6265
);
66+
6367
if (!returnStmt) return;
6468

6569
context.report({ messageId: 'noReturnValue', node: returnStmt });

src/rules/no-truthy-falsy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default createRule({
2626
}
2727

2828
const { matcher } = parseExpectCall(node);
29+
2930
if (!matcher || !['toBeTruthy', 'toBeFalsy'].includes(matcher.name)) {
3031
return;
3132
}

src/rules/prefer-expect-assertions.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ const isExpectAssertionsOrHasAssertionsCall = (expression: TSESTree.Node) => {
3535
);
3636
};
3737

38-
const getFunctionFirstLine = (functionBody: [TSESTree.ExpressionStatement]) =>
39-
functionBody[0] && functionBody[0].expression;
40-
4138
const isFirstLineExprStmt = (
4239
functionBody: TSESTree.Statement[],
4340
): functionBody is [TSESTree.ExpressionStatement] =>
@@ -81,7 +78,8 @@ export default createRule({
8178
return;
8279
}
8380

84-
const testFuncFirstLine = getFunctionFirstLine(testFuncBody);
81+
const testFuncFirstLine = testFuncBody[0].expression;
82+
8583
if (!isExpectAssertionsOrHasAssertionsCall(testFuncFirstLine)) {
8684
context.report({ messageId: 'haveExpectAssertions', node });
8785
}

src/rules/prefer-hooks-on-top.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default createRule({
1717
defaultOptions: [],
1818
create(context) {
1919
const hooksContext = [false];
20+
2021
return {
2122
CallExpression(node) {
2223
if (!isHook(node) && isTestCase(node)) {

src/rules/prefer-to-contain.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ const getCommonFixes = (
153153
openParenthesis,
154154
];
155155
};
156+
156157
// expect(array.includes(<value>)[not.]{toBe,toEqual}(<boolean>)
157158
export default createRule({
158159
name: __filename,
@@ -206,7 +207,7 @@ export default createRule({
206207
fileName,
207208
).map(target => fixer.remove(target));
208209

209-
if (modifier && modifier.name === ModifierName.not) {
210+
if (modifier) {
210211
return getNegationFixes(
211212
includesCall,
212213
modifier,
@@ -232,6 +233,7 @@ export default createRule({
232233
sourceCode.getText(containArg),
233234
),
234235
);
236+
235237
return fixArr;
236238
},
237239
messageId: 'useToContain',

src/rules/prefer-todo.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ function createTodoFixer(
4040
const testName = getNodeName(node.callee)
4141
.split('.')
4242
.shift();
43+
4344
return fixer.replaceText(node.callee, `${testName}.todo`);
4445
}
4546

0 commit comments

Comments
 (0)