1 | 'use strict';
|
2 |
|
3 | const isNil = require('ramda/src/isNil');
|
4 | const find = require('ramda/src/find');
|
5 | const astUtil = require('../util/ast');
|
6 |
|
7 | const asyncMethods = [ 'async', 'callback', 'promise' ];
|
8 |
|
9 | function hasAsyncCallback(functionExpression) {
|
10 | return functionExpression.params.length === 1;
|
11 | }
|
12 |
|
13 | function isAsyncFunction(functionExpression) {
|
14 | return functionExpression.async === true;
|
15 | }
|
16 |
|
17 | function findPromiseReturnStatement(nodes) {
|
18 | return find(function (node) {
|
19 | return node.type === 'ReturnStatement' && node.argument && node.argument.type !== 'Literal';
|
20 | }, nodes);
|
21 | }
|
22 |
|
23 | function doesReturnPromise(functionExpression) {
|
24 | const bodyStatement = functionExpression.body;
|
25 | let returnStatement = null;
|
26 |
|
27 | if (bodyStatement.type === 'BlockStatement') {
|
28 | returnStatement = findPromiseReturnStatement(functionExpression.body.body);
|
29 | } else if (bodyStatement.type !== 'Literal') {
|
30 |
|
31 | returnStatement = bodyStatement;
|
32 | }
|
33 |
|
34 | return returnStatement !== null &&
|
35 | typeof returnStatement !== 'undefined';
|
36 | }
|
37 |
|
38 | module.exports = function (context) {
|
39 | const options = context.options[0] || {};
|
40 | const allowedAsyncMethods = isNil(options.allowed) ? asyncMethods : options.allowed;
|
41 |
|
42 | function check(node) {
|
43 | if (astUtil.hasParentMochaFunctionCall(node)) {
|
44 |
|
45 | const testAsyncMethods = allowedAsyncMethods.map(function (method) {
|
46 | switch (method) {
|
47 | case 'async':
|
48 | return isAsyncFunction(node);
|
49 |
|
50 | case 'callback':
|
51 | return hasAsyncCallback(node);
|
52 |
|
53 | default:
|
54 | return doesReturnPromise(node);
|
55 | }
|
56 | });
|
57 |
|
58 |
|
59 | const isAsyncTest = testAsyncMethods.some(function (value) {
|
60 | return value === true;
|
61 | });
|
62 |
|
63 | if (!isAsyncTest) {
|
64 | context.report(node, 'Unexpected synchronous test.');
|
65 | }
|
66 | }
|
67 | }
|
68 |
|
69 | return {
|
70 | FunctionExpression: check,
|
71 | ArrowFunctionExpression: check
|
72 | };
|
73 | };
|
74 |
|
75 | module.exports.schema = [
|
76 | {
|
77 | type: 'object',
|
78 | properties: {
|
79 | allowed: {
|
80 | type: 'array',
|
81 | items: {
|
82 | type: 'string',
|
83 | enum: asyncMethods
|
84 | },
|
85 | minItems: 1,
|
86 | uniqueItems: true
|
87 | }
|
88 | }
|
89 | }
|
90 | ];
|