forked from avajs/eslint-plugin-ava
-
Notifications
You must be signed in to change notification settings - Fork 0
/
create-ava-rule.js
108 lines (99 loc) · 2.29 KB
/
create-ava-rule.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
'use strict';
const espurify = require('espurify');
const enhance = require('enhance-visitors');
const deepStrictEqual = require('deep-strict-equal');
const util = require('./util');
const avaImportDeclarationAst = {
type: 'ImportDeclaration',
specifiers: [
{
type: 'ImportDefaultSpecifier',
local: {
type: 'Identifier',
name: 'test'
}
}
],
source: {
type: 'Literal',
value: 'ava'
}
};
const avaVariableDeclaratorAst = {
type: 'VariableDeclarator',
id: {
type: 'Identifier',
name: 'test'
},
init: {
type: 'CallExpression',
callee: {
type: 'Identifier',
name: 'require'
},
arguments: [
{
type: 'Literal',
value: 'ava'
}
]
}
};
function isTestFunctionCall(node) {
if (node.type === 'Identifier') {
return node.name === 'test';
}
if (node.type === 'MemberExpression') {
return isTestFunctionCall(node.object);
}
return false;
}
function getTestModifierNames(node) {
return util.getTestModifiers(node).map(property => property.name);
}
module.exports = () => {
let isTestFile = false;
let currentTestNode;
/* eslint quote-props: [2, "as-needed"] */
const predefinedRules = {
ImportDeclaration: node => {
if (!isTestFile && deepStrictEqual(espurify(node), avaImportDeclarationAst)) {
isTestFile = true;
}
},
VariableDeclarator: node => {
if (!isTestFile && deepStrictEqual(espurify(node), avaVariableDeclaratorAst)) {
isTestFile = true;
}
},
CallExpression: node => {
if (isTestFunctionCall(node.callee)) {
// Entering test function
currentTestNode = node;
}
},
'CallExpression:exit': node => {
if (currentTestNode === node) {
// Leaving test function
currentTestNode = undefined;
}
},
'Program:exit': () => {
isTestFile = false;
}
};
return {
hasTestModifier: mod => getTestModifierNames(currentTestNode).includes(mod),
hasNoHookModifier: () => {
const modifiers = getTestModifierNames(currentTestNode);
return !modifiers.includes('before') &&
!modifiers.includes('beforeEach') &&
!modifiers.includes('after') &&
!modifiers.includes('afterEach');
},
isInTestFile: () => isTestFile,
isInTestNode: () => currentTestNode,
isTestNode: node => currentTestNode === node,
merge: customHandlers => enhance.mergeVisitors([predefinedRules, customHandlers])
};
};