UNPKG

4.14 kBJavaScriptView Raw
1'use strict';
2
3/*
4 * This implementation is ported from from eslint-plugin-jasmine.
5 * MIT license, Tom Vincent.
6 */
7
8const { getDocsUrl } = require('./util');
9
10const expectProperties = ['not', 'resolves', 'rejects'];
11
12module.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 // checking "expect()" arguments
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 // something was called on `expect()`
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 // a property is accessed, get the next node
71 if (grandParent.type === 'MemberExpression') {
72 // a modifier is used, just get the next one
73 if (expectProperties.indexOf(propertyName) > -1) {
74 grandParent = grandParent.parent;
75 } else {
76 // only a few properties are allowed
77 context.report({
78 // For some reason `endColumn` isn't set in tests if `loc` is
79 // not added
80 loc: parentProperty.loc,
81 message: `"${propertyName}" is not a valid property of expect.`,
82 node: parentProperty,
83 });
84 }
85
86 // this next one should be the matcher
87 parentNode = parentNode.parent;
88 parentProperty = parentNode.property;
89 propertyName = parentProperty.name;
90 }
91
92 // matcher was not called
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 // For some reason `endColumn` isn't set in tests if `loc` is not
103 // added
104 loc: parentProperty.loc,
105 message,
106 node: parentProperty,
107 });
108 }
109 }
110 }
111 },
112
113 // nothing called on "expect()"
114 'CallExpression:exit'(node) {
115 if (
116 node.callee.name === 'expect' &&
117 node.parent.type === 'ExpressionStatement'
118 ) {
119 context.report({
120 // For some reason `endColumn` isn't set in tests if `loc` is not
121 // added
122 loc: node.loc,
123 message: 'No assertion was called on expect().',
124 node,
125 });
126 }
127 },
128 };
129 },
130};