UNPKG

7.71 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = function (d, b) {
4 extendStatics = Object.setPrototypeOf ||
5 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7 return extendStatics(d, b);
8 }
9 return function (d, b) {
10 extendStatics(d, b);
11 function __() { this.constructor = d; }
12 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13 };
14})();
15Object.defineProperty(exports, "__esModule", { value: true });
16var ts = require("typescript");
17var Lint = require("tslint");
18var tsutils = require("tsutils");
19var AstUtils_1 = require("./utils/AstUtils");
20var MochaUtils_1 = require("./utils/MochaUtils");
21var Utils_1 = require("./utils/Utils");
22var TypeGuard_1 = require("./utils/TypeGuard");
23var FAILURE_STRING = 'Mocha test contains dangerous variable initialization. Move to before()/beforeEach(): ';
24var Rule = (function (_super) {
25 __extends(Rule, _super);
26 function Rule() {
27 return _super !== null && _super.apply(this, arguments) || this;
28 }
29 Rule.prototype.apply = function (sourceFile) {
30 return this.applyWithFunction(sourceFile, walk, this.parseOptions(this.getOptions()));
31 };
32 Rule.prototype.parseOptions = function (options) {
33 var parsed = {
34 ignoreRegex: undefined
35 };
36 options.ruleArguments.forEach(function (opt) {
37 if (TypeGuard_1.isObject(opt)) {
38 if (opt.ignore !== undefined && (typeof opt.ignore === 'string' || opt.ignore instanceof RegExp)) {
39 parsed.ignoreRegex = new RegExp(opt.ignore);
40 }
41 }
42 });
43 return parsed;
44 };
45 Rule.metadata = {
46 ruleName: 'mocha-no-side-effect-code',
47 type: 'maintainability',
48 description: 'All test logic in a Mocha test case should be within Mocha lifecycle method.',
49 options: null,
50 optionsDescription: '',
51 typescriptOnly: true,
52 issueClass: 'Ignored',
53 issueType: 'Warning',
54 severity: 'Moderate',
55 level: 'Opportunity for Excellence',
56 group: 'Correctness'
57 };
58 return Rule;
59}(Lint.Rules.AbstractRule));
60exports.Rule = Rule;
61function walk(ctx) {
62 var isInDescribe = false;
63 function validateExpression(initializer, parentNode) {
64 if (initializer === undefined) {
65 return;
66 }
67 if (AstUtils_1.AstUtils.isConstant(initializer)) {
68 return;
69 }
70 if (initializer.kind === ts.SyntaxKind.FunctionExpression || initializer.kind === ts.SyntaxKind.ArrowFunction) {
71 return;
72 }
73 if (initializer.kind === ts.SyntaxKind.ArrayLiteralExpression) {
74 var arrayLiteral = initializer;
75 arrayLiteral.elements.forEach(function (expression) {
76 validateExpression(expression, parentNode);
77 });
78 return;
79 }
80 if (initializer.kind === ts.SyntaxKind.FirstTemplateToken) {
81 return;
82 }
83 if (initializer.kind === ts.SyntaxKind.TypeAssertionExpression) {
84 var assertion = initializer;
85 validateExpression(assertion.expression, parentNode);
86 return;
87 }
88 if (initializer.kind === ts.SyntaxKind.PropertyAccessExpression) {
89 return;
90 }
91 if (initializer.kind === ts.SyntaxKind.Identifier) {
92 return;
93 }
94 if (initializer.kind === ts.SyntaxKind.ObjectLiteralExpression) {
95 var literal = initializer;
96 literal.properties.forEach(function (element) {
97 if (element.kind === ts.SyntaxKind.PropertyAssignment) {
98 var assignment = element;
99 validateExpression(assignment.initializer, parentNode);
100 }
101 });
102 return;
103 }
104 if (/^this\.(retries|slow|timeout)\(.+\)$/.test(initializer.getText())) {
105 return;
106 }
107 if (initializer.getText() === 'moment()') {
108 return;
109 }
110 if (initializer.kind === ts.SyntaxKind.CallExpression &&
111 AstUtils_1.AstUtils.getFunctionTarget(initializer) === 'moment()') {
112 return;
113 }
114 if (initializer.kind === ts.SyntaxKind.NewExpression) {
115 if (AstUtils_1.AstUtils.getFunctionName(initializer) === 'Date') {
116 return;
117 }
118 }
119 if (initializer.kind === ts.SyntaxKind.CallExpression) {
120 var callExp = initializer;
121 if (callExp.expression.kind === ts.SyntaxKind.PropertyAccessExpression) {
122 var propExp = callExp.expression;
123 if (propExp.expression.kind === ts.SyntaxKind.ArrayLiteralExpression) {
124 if (propExp.name.getText() === 'forEach') {
125 validateExpression(propExp.expression, parentNode);
126 callExp.arguments.forEach(function (arg) {
127 cb(arg);
128 });
129 return;
130 }
131 }
132 }
133 }
134 if (ctx.options.ignoreRegex !== undefined && ctx.options.ignoreRegex.test(initializer.getText())) {
135 return;
136 }
137 if (AstUtils_1.AstUtils.isConstantExpression(initializer)) {
138 return;
139 }
140 var message = FAILURE_STRING + Utils_1.Utils.trimTo(parentNode.getText(), 30);
141 ctx.addFailureAt(parentNode.getStart(), parentNode.getWidth(), message);
142 }
143 function cb(node) {
144 if (tsutils.isFunctionDeclaration(node) || tsutils.isClassDeclaration(node)) {
145 return;
146 }
147 if (tsutils.isVariableDeclaration(node)) {
148 if (isInDescribe === true && node.initializer !== undefined) {
149 validateExpression(node.initializer, node);
150 }
151 }
152 else if (tsutils.isCallExpression(node)) {
153 if (MochaUtils_1.MochaUtils.isDescribe(node)) {
154 var nestedSubscribe = isInDescribe;
155 isInDescribe = true;
156 ts.forEachChild(node, cb);
157 if (nestedSubscribe === false) {
158 isInDescribe = false;
159 }
160 }
161 else if (MochaUtils_1.MochaUtils.isLifecycleMethod(node)) {
162 return;
163 }
164 else if (isInDescribe) {
165 validateExpression(node, node);
166 }
167 }
168 else {
169 ts.forEachChild(node, cb);
170 }
171 }
172 if (MochaUtils_1.MochaUtils.isMochaTest(ctx.sourceFile)) {
173 ctx.sourceFile.statements.forEach(function (statement) {
174 if (statement.kind === ts.SyntaxKind.VariableStatement) {
175 var declarationList = statement.declarationList;
176 declarationList.declarations.forEach(function (declaration) {
177 if (declaration.initializer !== undefined) {
178 validateExpression(declaration.initializer, declaration);
179 }
180 });
181 }
182 if (MochaUtils_1.MochaUtils.isStatementDescribeCall(statement)) {
183 var expression = statement.expression;
184 var call = expression;
185 cb(call);
186 }
187 });
188 }
189}
190//# sourceMappingURL=mochaNoSideEffectCodeRule.js.map
\No newline at end of file