1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | const { getDocsUrl } = require('./util');
|
9 |
|
10 | const expectProperties = ['not', 'resolves', 'rejects'];
|
11 |
|
12 | module.exports = {
|
13 | meta: {
|
14 | docs: {
|
15 | url: getDocsUrl(__filename),
|
16 | },
|
17 | },
|
18 | create(context) {
|
19 | return {
|
20 | CallExpression(node) {
|
21 | const calleeName = node.callee.name;
|
22 |
|
23 | if (calleeName === 'expect') {
|
24 |
|
25 | if (node.arguments.length > 1) {
|
26 | const secondArgumentLocStart = node.arguments[1].loc.start;
|
27 | const lastArgumentLocEnd =
|
28 | node.arguments[node.arguments.length - 1].loc.end;
|
29 |
|
30 | context.report({
|
31 | loc: {
|
32 | end: {
|
33 | column: lastArgumentLocEnd.column - 1,
|
34 | line: lastArgumentLocEnd.line,
|
35 | },
|
36 | start: secondArgumentLocStart,
|
37 | },
|
38 | message: 'More than one argument was passed to expect().',
|
39 | node,
|
40 | });
|
41 | } else if (node.arguments.length === 0) {
|
42 | const expectLength = calleeName.length;
|
43 | context.report({
|
44 | loc: {
|
45 | end: {
|
46 | column: node.loc.start.column + expectLength + 1,
|
47 | line: node.loc.start.line,
|
48 | },
|
49 | start: {
|
50 | column: node.loc.start.column + expectLength,
|
51 | line: node.loc.start.line,
|
52 | },
|
53 | },
|
54 | message: 'No arguments were passed to expect().',
|
55 | node,
|
56 | });
|
57 | }
|
58 |
|
59 |
|
60 | if (
|
61 | node.parent &&
|
62 | node.parent.type === 'MemberExpression' &&
|
63 | node.parent.parent
|
64 | ) {
|
65 | let parentNode = node.parent;
|
66 | let parentProperty = parentNode.property;
|
67 | let propertyName = parentProperty.name;
|
68 | let grandParent = parentNode.parent;
|
69 |
|
70 |
|
71 | if (grandParent.type === 'MemberExpression') {
|
72 |
|
73 | if (expectProperties.indexOf(propertyName) > -1) {
|
74 | grandParent = grandParent.parent;
|
75 | } else {
|
76 |
|
77 | context.report({
|
78 |
|
79 |
|
80 | loc: parentProperty.loc,
|
81 | message: `"${propertyName}" is not a valid property of expect.`,
|
82 | node: parentProperty,
|
83 | });
|
84 | }
|
85 |
|
86 |
|
87 | parentNode = parentNode.parent;
|
88 | parentProperty = parentNode.property;
|
89 | propertyName = parentProperty.name;
|
90 | }
|
91 |
|
92 |
|
93 | if (grandParent.type === 'ExpressionStatement') {
|
94 | let message;
|
95 | if (expectProperties.indexOf(propertyName) > -1) {
|
96 | message = `"${propertyName}" needs to call a matcher.`;
|
97 | } else {
|
98 | message = `"${propertyName}" was not called.`;
|
99 | }
|
100 |
|
101 | context.report({
|
102 |
|
103 |
|
104 | loc: parentProperty.loc,
|
105 | message,
|
106 | node: parentProperty,
|
107 | });
|
108 | }
|
109 | }
|
110 | }
|
111 | },
|
112 |
|
113 |
|
114 | 'CallExpression:exit'(node) {
|
115 | if (
|
116 | node.callee.name === 'expect' &&
|
117 | node.parent.type === 'ExpressionStatement'
|
118 | ) {
|
119 | context.report({
|
120 |
|
121 |
|
122 | loc: node.loc,
|
123 | message: 'No assertion was called on expect().',
|
124 | node,
|
125 | });
|
126 | }
|
127 | },
|
128 | };
|
129 | },
|
130 | };
|