1 | 'use strict';
|
2 |
|
3 | const astUtils = require('../util/ast');
|
4 | const { additionalSuiteNames } = require('../util/settings');
|
5 |
|
6 | const FUNCTION = 1;
|
7 | const DESCRIBE = 2;
|
8 |
|
9 | const PURE = 3;
|
10 |
|
11 | module.exports = function noSetupInDescribe(context) {
|
12 | const nesting = [];
|
13 | const settings = context.settings;
|
14 |
|
15 | function isPureNode(node) {
|
16 | return astUtils.isHookCall(node) ||
|
17 | astUtils.isTestCase(node) ||
|
18 | astUtils.isSuiteConfigCall(node);
|
19 | }
|
20 |
|
21 | function reportCallExpression(callExpression) {
|
22 | const message = 'Unexpected function call in describe block.';
|
23 |
|
24 | context.report({
|
25 | message,
|
26 | node: callExpression.callee
|
27 | });
|
28 | }
|
29 |
|
30 | function reportMemberExpression(memberExpression) {
|
31 | const message = 'Unexpected member expression in describe block. ' +
|
32 | 'Member expressions may call functions via getters.';
|
33 |
|
34 | context.report({
|
35 | message,
|
36 | node: memberExpression
|
37 | });
|
38 | }
|
39 |
|
40 | function isNestedInDescribeBlock() {
|
41 | return nesting.length &&
|
42 | nesting.indexOf(PURE) === -1 &&
|
43 | nesting.lastIndexOf(FUNCTION) < nesting.lastIndexOf(DESCRIBE);
|
44 | }
|
45 |
|
46 | function handleCallExpressionInDescribe(node) {
|
47 | if (isPureNode(node)) {
|
48 | nesting.push(PURE);
|
49 | } else if (isNestedInDescribeBlock()) {
|
50 | reportCallExpression(node);
|
51 | }
|
52 | }
|
53 |
|
54 | function isDescribe(node) {
|
55 | return astUtils.isDescribe(node, additionalSuiteNames(settings));
|
56 | }
|
57 |
|
58 | function isParentDescribe(node) {
|
59 | return isDescribe(node.parent);
|
60 | }
|
61 |
|
62 | return {
|
63 | CallExpression(node) {
|
64 | if (isDescribe(node)) {
|
65 | nesting.push(DESCRIBE);
|
66 | return;
|
67 | }
|
68 |
|
69 | if (!nesting.length) {
|
70 | return;
|
71 | }
|
72 | handleCallExpressionInDescribe(node);
|
73 | },
|
74 |
|
75 | 'CallExpression:exit'(node) {
|
76 | if (isDescribe(node) || nesting.length && isPureNode(node)) {
|
77 | nesting.pop();
|
78 | }
|
79 | },
|
80 |
|
81 | MemberExpression(node) {
|
82 | if (isNestedInDescribeBlock()) {
|
83 | reportMemberExpression(node);
|
84 | }
|
85 | },
|
86 |
|
87 | FunctionDeclaration() {
|
88 | if (nesting.length) {
|
89 | nesting.push(FUNCTION);
|
90 | }
|
91 | },
|
92 | 'FunctionDeclaration:exit'() {
|
93 | if (nesting.length) {
|
94 | nesting.pop();
|
95 | }
|
96 | },
|
97 |
|
98 | ArrowFunctionExpression(node) {
|
99 | if (nesting.length && !isParentDescribe(node)) {
|
100 | nesting.push(FUNCTION);
|
101 | }
|
102 | },
|
103 | 'ArrowFunctionExpression:exit'(node) {
|
104 | if (nesting.length && !isParentDescribe(node)) {
|
105 | nesting.pop();
|
106 | }
|
107 | }
|
108 | };
|
109 | };
|