eslint-plugin-chai-friendly 0.3.6 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.editorconfig ADDED
@@ -0,0 +1,15 @@
1
+ ; EditorConfig file: https://EditorConfig.org
2
+ ; Install the "EditorConfig" plugin into your editor to use
3
+
4
+ root = true
5
+
6
+ [*]
7
+ charset = utf-8
8
+ end_of_line = lf
9
+ insert_final_newline = true
10
+ indent_style = space
11
+ indent_size = 4
12
+ trim_trailing_whitespace = true
13
+
14
+ [*.json]
15
+ indent_size = 2
package/.eslintignore ADDED
@@ -0,0 +1,2 @@
1
+ node_modules
2
+ !.eslintrc.js
package/.eslintrc.js ADDED
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ extends: ['eslint:recommended'],
5
+ env: {
6
+ node: true
7
+ },
8
+ rules: {
9
+ strict: ['error'],
10
+ indent: ['error', 4]
11
+ }
12
+ };
@@ -0,0 +1 @@
1
+ {"/Users/user/repos/eslint-plugin-chai-friendly/lib/rules/no-unused-expressions.js":{"path":"/Users/user/repos/eslint-plugin-chai-friendly/lib/rules/no-unused-expressions.js","statementMap":{"0":{"start":{"line":12,"column":0},"end":{"line":212,"column":2}},"1":{"start":{"line":41,"column":21},"end":{"line":41,"column":45}},"2":{"start":{"line":42,"column":32},"end":{"line":42,"column":65}},"3":{"start":{"line":43,"column":27},"end":{"line":43,"column":55}},"4":{"start":{"line":44,"column":35},"end":{"line":44,"column":71}},"5":{"start":{"line":52,"column":12},"end":{"line":53,"column":96}},"6":{"start":{"line":62,"column":12},"end":{"line":66,"column":13}},"7":{"start":{"line":62,"column":25},"end":{"line":62,"column":26}},"8":{"start":{"line":63,"column":16},"end":{"line":65,"column":17}},"9":{"start":{"line":64,"column":20},"end":{"line":64,"column":44}},"10":{"start":{"line":67,"column":12},"end":{"line":67,"column":32}},"11":{"start":{"line":75,"column":12},"end":{"line":75,"column":60}},"12":{"start":{"line":84,"column":25},"end":{"line":84,"column":56}},"13":{"start":{"line":85,"column":30},"end":{"line":85,"column":61}},"14":{"start":{"line":87,"column":12},"end":{"line":89,"column":58}},"15":{"start":{"line":98,"column":12},"end":{"line":104,"column":13}},"16":{"start":{"line":101,"column":16},"end":{"line":103,"column":17}},"17":{"start":{"line":102,"column":20},"end":{"line":102,"column":99}},"18":{"start":{"line":105,"column":12},"end":{"line":109,"column":13}},"19":{"start":{"line":106,"column":16},"end":{"line":108,"column":17}},"20":{"start":{"line":107,"column":20},"end":{"line":107,"column":57}},"21":{"start":{"line":111,"column":12},"end":{"line":113,"column":13}},"22":{"start":{"line":112,"column":16},"end":{"line":112,"column":28}},"23":{"start":{"line":115,"column":12},"end":{"line":116,"column":100}},"24":{"start":{"line":126,"column":29},"end":{"line":126,"column":44}},"25":{"start":{"line":127,"column":12},"end":{"line":129,"column":13}},"26":{"start":{"line":128,"column":16},"end":{"line":128,"column":29}},"27":{"start":{"line":131,"column":33},"end":{"line":131,"column":75}},"28":{"start":{"line":133,"column":12},"end":{"line":133,"column":33}},"29":{"start":{"line":143,"column":12},"end":{"line":145,"column":13}},"30":{"start":{"line":144,"column":16},"end":{"line":144,"column":28}},"31":{"start":{"line":148,"column":12},"end":{"line":150,"column":13}},"32":{"start":{"line":149,"column":16},"end":{"line":149,"column":51}},"33":{"start":{"line":151,"column":12},"end":{"line":153,"column":13}},"34":{"start":{"line":152,"column":16},"end":{"line":152,"column":51}},"35":{"start":{"line":156,"column":12},"end":{"line":156,"column":24}},"36":{"start":{"line":166,"column":29},"end":{"line":166,"column":44}},"37":{"start":{"line":167,"column":12},"end":{"line":169,"column":13}},"38":{"start":{"line":168,"column":16},"end":{"line":168,"column":29}},"39":{"start":{"line":171,"column":32},"end":{"line":171,"column":74}},"40":{"start":{"line":173,"column":12},"end":{"line":173,"column":33}},"41":{"start":{"line":183,"column":12},"end":{"line":185,"column":13}},"42":{"start":{"line":184,"column":16},"end":{"line":184,"column":28}},"43":{"start":{"line":188,"column":12},"end":{"line":190,"column":13}},"44":{"start":{"line":189,"column":16},"end":{"line":189,"column":51}},"45":{"start":{"line":191,"column":12},"end":{"line":193,"column":13}},"46":{"start":{"line":192,"column":16},"end":{"line":192,"column":51}},"47":{"start":{"line":196,"column":12},"end":{"line":196,"column":24}},"48":{"start":{"line":200,"column":8},"end":{"line":210,"column":10}},"49":{"start":{"line":202,"column":28},"end":{"line":205,"column":45}},"50":{"start":{"line":206,"column":16},"end":{"line":208,"column":17}},"51":{"start":{"line":207,"column":20},"end":{"line":207,"column":115}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":40,"column":12},"end":{"line":40,"column":13}},"loc":{"start":{"line":40,"column":31},"end":{"line":211,"column":5}},"line":40},"1":{"name":"looksLikeDirective","decl":{"start":{"line":51,"column":17},"end":{"line":51,"column":35}},"loc":{"start":{"line":51,"column":42},"end":{"line":54,"column":9}},"line":51},"2":{"name":"takeWhile","decl":{"start":{"line":61,"column":17},"end":{"line":61,"column":26}},"loc":{"start":{"line":61,"column":44},"end":{"line":68,"column":9}},"line":61},"3":{"name":"directives","decl":{"start":{"line":74,"column":17},"end":{"line":74,"column":27}},"loc":{"start":{"line":74,"column":34},"end":{"line":76,"column":9}},"line":74},"4":{"name":"isDirective","decl":{"start":{"line":83,"column":17},"end":{"line":83,"column":28}},"loc":{"start":{"line":83,"column":46},"end":{"line":90,"column":9}},"line":83},"5":{"name":"isValidExpression","decl":{"start":{"line":97,"column":17},"end":{"line":97,"column":34}},"loc":{"start":{"line":97,"column":41},"end":{"line":117,"column":9}},"line":97},"6":{"name":"isChaiExpectCall","decl":{"start":{"line":125,"column":17},"end":{"line":125,"column":33}},"loc":{"start":{"line":125,"column":40},"end":{"line":134,"column":9}},"line":125},"7":{"name":"findExpectCall","decl":{"start":{"line":141,"column":17},"end":{"line":141,"column":31}},"loc":{"start":{"line":141,"column":38},"end":{"line":157,"column":9}},"line":141},"8":{"name":"isChaiShouldCall","decl":{"start":{"line":165,"column":17},"end":{"line":165,"column":33}},"loc":{"start":{"line":165,"column":40},"end":{"line":174,"column":9}},"line":165},"9":{"name":"findShouldCall","decl":{"start":{"line":181,"column":17},"end":{"line":181,"column":31}},"loc":{"start":{"line":181,"column":38},"end":{"line":197,"column":9}},"line":181},"10":{"name":"(anonymous_10)","decl":{"start":{"line":201,"column":33},"end":{"line":201,"column":34}},"loc":{"start":{"line":201,"column":48},"end":{"line":209,"column":13}},"line":201}},"branchMap":{"0":{"loc":{"start":{"line":41,"column":21},"end":{"line":41,"column":45}},"type":"binary-expr","locations":[{"start":{"line":41,"column":21},"end":{"line":41,"column":39}},{"start":{"line":41,"column":43},"end":{"line":41,"column":45}}],"line":41},"1":{"loc":{"start":{"line":42,"column":32},"end":{"line":42,"column":65}},"type":"binary-expr","locations":[{"start":{"line":42,"column":32},"end":{"line":42,"column":56}},{"start":{"line":42,"column":60},"end":{"line":42,"column":65}}],"line":42},"2":{"loc":{"start":{"line":43,"column":27},"end":{"line":43,"column":55}},"type":"binary-expr","locations":[{"start":{"line":43,"column":27},"end":{"line":43,"column":46}},{"start":{"line":43,"column":50},"end":{"line":43,"column":55}}],"line":43},"3":{"loc":{"start":{"line":44,"column":35},"end":{"line":44,"column":71}},"type":"binary-expr","locations":[{"start":{"line":44,"column":35},"end":{"line":44,"column":62}},{"start":{"line":44,"column":66},"end":{"line":44,"column":71}}],"line":44},"4":{"loc":{"start":{"line":52,"column":19},"end":{"line":53,"column":95}},"type":"binary-expr","locations":[{"start":{"line":52,"column":19},"end":{"line":52,"column":54}},{"start":{"line":53,"column":16},"end":{"line":53,"column":50}},{"start":{"line":53,"column":54},"end":{"line":53,"column":95}}],"line":52},"5":{"loc":{"start":{"line":63,"column":16},"end":{"line":65,"column":17}},"type":"if","locations":[{"start":{"line":63,"column":16},"end":{"line":65,"column":17}},{"start":{"line":63,"column":16},"end":{"line":65,"column":17}}],"line":63},"6":{"loc":{"start":{"line":87,"column":19},"end":{"line":89,"column":57}},"type":"binary-expr","locations":[{"start":{"line":87,"column":20},"end":{"line":87,"column":45}},{"start":{"line":87,"column":49},"end":{"line":87,"column":81}},{"start":{"line":88,"column":21},"end":{"line":88,"column":54}},{"start":{"line":89,"column":20},"end":{"line":89,"column":57}}],"line":87},"7":{"loc":{"start":{"line":98,"column":12},"end":{"line":104,"column":13}},"type":"if","locations":[{"start":{"line":98,"column":12},"end":{"line":104,"column":13}},{"start":{"line":98,"column":12},"end":{"line":104,"column":13}}],"line":98},"8":{"loc":{"start":{"line":101,"column":16},"end":{"line":103,"column":17}},"type":"if","locations":[{"start":{"line":101,"column":16},"end":{"line":103,"column":17}},{"start":{"line":101,"column":16},"end":{"line":103,"column":17}}],"line":101},"9":{"loc":{"start":{"line":102,"column":27},"end":{"line":102,"column":98}},"type":"binary-expr","locations":[{"start":{"line":102,"column":27},"end":{"line":102,"column":61}},{"start":{"line":102,"column":65},"end":{"line":102,"column":98}}],"line":102},"10":{"loc":{"start":{"line":105,"column":12},"end":{"line":109,"column":13}},"type":"if","locations":[{"start":{"line":105,"column":12},"end":{"line":109,"column":13}},{"start":{"line":105,"column":12},"end":{"line":109,"column":13}}],"line":105},"11":{"loc":{"start":{"line":106,"column":16},"end":{"line":108,"column":17}},"type":"if","locations":[{"start":{"line":106,"column":16},"end":{"line":108,"column":17}},{"start":{"line":106,"column":16},"end":{"line":108,"column":17}}],"line":106},"12":{"loc":{"start":{"line":111,"column":12},"end":{"line":113,"column":13}},"type":"if","locations":[{"start":{"line":111,"column":12},"end":{"line":113,"column":13}},{"start":{"line":111,"column":12},"end":{"line":113,"column":13}}],"line":111},"13":{"loc":{"start":{"line":111,"column":16},"end":{"line":111,"column":80}},"type":"binary-expr","locations":[{"start":{"line":111,"column":16},"end":{"line":111,"column":36}},{"start":{"line":111,"column":40},"end":{"line":111,"column":80}}],"line":111},"14":{"loc":{"start":{"line":115,"column":19},"end":{"line":116,"column":99}},"type":"binary-expr","locations":[{"start":{"line":115,"column":19},"end":{"line":115,"column":98}},{"start":{"line":116,"column":17},"end":{"line":116,"column":48}},{"start":{"line":116,"column":52},"end":{"line":116,"column":98}}],"line":115},"15":{"loc":{"start":{"line":127,"column":12},"end":{"line":129,"column":13}},"type":"if","locations":[{"start":{"line":127,"column":12},"end":{"line":129,"column":13}},{"start":{"line":127,"column":12},"end":{"line":129,"column":13}}],"line":127},"16":{"loc":{"start":{"line":143,"column":12},"end":{"line":145,"column":13}},"type":"if","locations":[{"start":{"line":143,"column":12},"end":{"line":145,"column":13}},{"start":{"line":143,"column":12},"end":{"line":145,"column":13}}],"line":143},"17":{"loc":{"start":{"line":143,"column":16},"end":{"line":143,"column":116}},"type":"binary-expr","locations":[{"start":{"line":143,"column":16},"end":{"line":143,"column":46}},{"start":{"line":143,"column":50},"end":{"line":143,"column":83}},{"start":{"line":143,"column":87},"end":{"line":143,"column":116}}],"line":143},"18":{"loc":{"start":{"line":148,"column":12},"end":{"line":150,"column":13}},"type":"if","locations":[{"start":{"line":148,"column":12},"end":{"line":150,"column":13}},{"start":{"line":148,"column":12},"end":{"line":150,"column":13}}],"line":148},"19":{"loc":{"start":{"line":151,"column":12},"end":{"line":153,"column":13}},"type":"if","locations":[{"start":{"line":151,"column":12},"end":{"line":153,"column":13}},{"start":{"line":151,"column":12},"end":{"line":153,"column":13}}],"line":151},"20":{"loc":{"start":{"line":167,"column":12},"end":{"line":169,"column":13}},"type":"if","locations":[{"start":{"line":167,"column":12},"end":{"line":169,"column":13}},{"start":{"line":167,"column":12},"end":{"line":169,"column":13}}],"line":167},"21":{"loc":{"start":{"line":183,"column":12},"end":{"line":185,"column":13}},"type":"if","locations":[{"start":{"line":183,"column":12},"end":{"line":185,"column":13}},{"start":{"line":183,"column":12},"end":{"line":185,"column":13}}],"line":183},"22":{"loc":{"start":{"line":183,"column":16},"end":{"line":183,"column":100}},"type":"binary-expr","locations":[{"start":{"line":183,"column":16},"end":{"line":183,"column":48}},{"start":{"line":183,"column":52},"end":{"line":183,"column":65}},{"start":{"line":183,"column":69},"end":{"line":183,"column":100}}],"line":183},"23":{"loc":{"start":{"line":188,"column":12},"end":{"line":190,"column":13}},"type":"if","locations":[{"start":{"line":188,"column":12},"end":{"line":190,"column":13}},{"start":{"line":188,"column":12},"end":{"line":190,"column":13}}],"line":188},"24":{"loc":{"start":{"line":191,"column":12},"end":{"line":193,"column":13}},"type":"if","locations":[{"start":{"line":191,"column":12},"end":{"line":193,"column":13}},{"start":{"line":191,"column":12},"end":{"line":193,"column":13}}],"line":191},"25":{"loc":{"start":{"line":202,"column":28},"end":{"line":205,"column":45}},"type":"binary-expr","locations":[{"start":{"line":202,"column":28},"end":{"line":202,"column":62}},{"start":{"line":203,"column":23},"end":{"line":203,"column":64}},{"start":{"line":204,"column":23},"end":{"line":204,"column":45}},{"start":{"line":205,"column":23},"end":{"line":205,"column":45}}],"line":202},"26":{"loc":{"start":{"line":206,"column":16},"end":{"line":208,"column":17}},"type":"if","locations":[{"start":{"line":206,"column":16},"end":{"line":208,"column":17}},{"start":{"line":206,"column":16},"end":{"line":208,"column":17}}],"line":206}},"s":{"0":1,"1":62,"2":62,"3":62,"4":62,"5":56,"6":42,"7":42,"8":56,"9":41,"10":1,"11":42,"12":44,"13":44,"14":44,"15":83,"16":15,"17":5,"18":78,"19":14,"20":6,"21":72,"22":1,"23":71,"24":35,"25":35,"26":27,"27":8,"28":8,"29":35,"30":2,"31":33,"32":24,"33":9,"34":3,"35":6,"36":33,"37":33,"38":27,"39":6,"40":6,"41":19,"42":3,"43":16,"44":11,"45":5,"46":2,"47":3,"48":62,"49":69,"50":69,"51":30},"f":{"0":62,"1":56,"2":42,"3":42,"4":44,"5":83,"6":35,"7":35,"8":33,"9":19,"10":69},"b":{"0":[62,45],"1":[62,55],"2":[62,56],"3":[62,59],"4":[56,52,16],"5":[41,15],"6":[44,10,10,42],"7":[15,68],"8":[5,10],"9":[5,3],"10":[14,64],"11":[6,8],"12":[1,71],"13":[72,3],"14":[71,46,4],"15":[27,8],"16":[2,33],"17":[35,5,2],"18":[24,9],"19":[3,6],"20":[27,6],"21":[3,16],"22":[19,14,14],"23":[11,5],"24":[2,3],"25":[69,44,35,33],"26":[30,39]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"05973dc07792da4b010cbf63b0206f454d6787a3","contentHash":"d41ee3dc8a8706e57c6465dd74c3a83be88f133f2d09a982d81644df7fffac22"}}
@@ -0,0 +1 @@
1
+ {"parent":null,"pid":73645,"argv":["/usr/local/bin/node","/Users/user/repos/eslint-plugin-chai-friendly/node_modules/.bin/mocha","tests","--recursive"],"execArgv":[],"cwd":"/Users/user/repos/eslint-plugin-chai-friendly","time":1587732197220,"ppid":73644,"coverageFilename":"/Users/user/repos/eslint-plugin-chai-friendly/.nyc_output/fd38766d-533f-46d0-9f65-df594829ca11.json","externalId":"","uuid":"fd38766d-533f-46d0-9f65-df594829ca11","files":["/Users/user/repos/eslint-plugin-chai-friendly/lib/rules/no-unused-expressions.js"]}
@@ -0,0 +1 @@
1
+ {"processes":{"fd38766d-533f-46d0-9f65-df594829ca11":{"parent":null,"children":[]}},"files":{"/Users/user/repos/eslint-plugin-chai-friendly/lib/rules/no-unused-expressions.js":["fd38766d-533f-46d0-9f65-df594829ca11"]},"externalIds":{}}
package/README.md CHANGED
@@ -1,13 +1,17 @@
1
1
  # eslint-plugin-chai-friendly
2
2
 
3
- This plugin overrides `no-unused-expressions` to make it friendly towards chai expect statements.
3
+ [![npm](https://img.shields.io/npm/v/eslint-plugin-chai-friendly.svg)](https://www.npmjs.com/package/eslint-plugin-chai-friendly) [![npm](https://img.shields.io/npm/dm/eslint-plugin-chai-friendly)](https://www.npmjs.com/package/eslint-plugin-chai-friendly)
4
+
5
+ This plugin overrides `no-unused-expressions` to make it friendly towards chai `expect` and `should` statements.
4
6
 
5
7
  ```javascript
6
8
  // this
7
9
  expect(foo).to.be.true;
10
+ foo.should.be.true;
8
11
 
9
12
  // instead of this
10
13
  expect(foo).to.be.true; // eslint-disable-line no-unused-expressions
14
+ foo.should.be.true; // eslint-disable-line no-unused-expressions
11
15
  ```
12
16
 
13
17
  ## Installation
@@ -28,7 +32,7 @@ npm install eslint-plugin-chai-friendly --save-dev
28
32
 
29
33
  ## Usage
30
34
 
31
- Add `chai-friendly` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
35
+ Add `chai-friendly` to the plugins section of your `.eslintrc.*` configuration file. You can omit the `eslint-plugin-` prefix:
32
36
 
33
37
  ```json
34
38
  {
@@ -50,6 +54,16 @@ Then disable original `no-unused-expressions` rule and configure chai-friendly r
50
54
  }
51
55
  ```
52
56
 
57
+ If you don't need to tweak the above rule settings, you can instead
58
+ just add the following to your config file's `extends` and the above
59
+ will be applied automatically:
60
+
61
+ ```json
62
+ {
63
+ "extends": ["plugin:chai-friendly/recommended"]
64
+ }
65
+ ```
66
+
53
67
  ## Options
54
68
 
55
69
  This rule, in its default state, does not require any arguments. If you would like to enable one or more of the following you may pass an object with the options set as follows:
@@ -64,9 +78,4 @@ More info in the original rule's [docs](http://eslint.org/docs/rules/no-unused-e
64
78
 
65
79
  ## Supported Rules
66
80
 
67
- - chai-friendly/no-unused-expressions
68
-
69
-
70
-
71
-
72
-
81
+ - `chai-friendly/no-unused-expressions`
package/lib/index.js CHANGED
@@ -5,10 +5,16 @@
5
5
  "use strict";
6
6
 
7
7
  module.exports = {
8
- rules: {
9
- 'no-unused-expressions': require('./rules/no-unused-expressions')
10
- }
8
+ configs: {
9
+ recommended: {
10
+ plugins: ['chai-friendly'],
11
+ rules: {
12
+ 'chai-friendly/no-unused-expressions': 'error',
13
+ 'no-unused-expressions': 'off'
14
+ }
15
+ }
16
+ },
17
+ rules: {
18
+ 'no-unused-expressions': require('./rules/no-unused-expressions')
19
+ }
11
20
  };
12
-
13
-
14
-
@@ -11,6 +11,8 @@
11
11
 
12
12
  module.exports = {
13
13
  meta: {
14
+ type: "suggestion",
15
+
14
16
  docs: {
15
17
  description: "disallow unused expressions",
16
18
  category: "Best Practices",
@@ -26,6 +28,9 @@ module.exports = {
26
28
  },
27
29
  allowTernary: {
28
30
  type: "boolean"
31
+ },
32
+ allowTaggedTemplates: {
33
+ type: "boolean"
29
34
  }
30
35
  },
31
36
  additionalProperties: false
@@ -35,7 +40,9 @@ module.exports = {
35
40
  create: function (context) {
36
41
  var config = context.options[0] || {},
37
42
  allowShortCircuit = config.allowShortCircuit || false,
38
- allowTernary = config.allowTernary || false;
43
+ allowTernary = config.allowTernary || false,
44
+ allowTaggedTemplates = config.allowTaggedTemplates || false;
45
+
39
46
 
40
47
  /**
41
48
  * @param {ASTNode} node - any node
@@ -101,7 +108,11 @@ module.exports = {
101
108
  }
102
109
  }
103
110
 
104
- return /^(?:Assignment|Call|New|Update|Yield|Await)Expression$/.test(node.type) ||
111
+ if (allowTaggedTemplates && node.type === "TaggedTemplateExpression") {
112
+ return true;
113
+ }
114
+
115
+ return /^(?:Assignment|Call|New|Update|Yield|Await|Import)Expression$/.test(node.type) ||
105
116
  (node.type === "UnaryExpression" && ["delete", "void"].indexOf(node.operator) >= 0);
106
117
  }
107
118
 
@@ -111,7 +122,7 @@ module.exports = {
111
122
  * @param {ASTNode} node - any node
112
123
  * @returns {boolean} whether the given node is a chai expectation
113
124
  */
114
- function isChaiExpectation(node) {
125
+ function isChaiExpectCall(node) {
115
126
  var expression = node.expression;
116
127
  if (expression.type !== 'MemberExpression') {
117
128
  return false;
@@ -143,15 +154,59 @@ module.exports = {
143
154
 
144
155
  // Stop search, expect(...) not found
145
156
  return null;
146
- };
157
+ }
158
+
159
+ /**
160
+ * Determines whether or not a given node is a chai's should statement.
161
+ * e.g. foo.should.eventually.be.true;
162
+ * @param {ASTNode} node - any node
163
+ * @returns {boolean} whether the given node is a chai should statement
164
+ */
165
+ function isChaiShouldCall(node) {
166
+ var expression = node.expression;
167
+ if (expression.type !== 'MemberExpression') {
168
+ return false;
169
+ }
170
+
171
+ var hasShouldCall = Boolean(findShouldCall(expression.object));
172
+
173
+ return hasShouldCall;
174
+ }
175
+
176
+ /**
177
+ * Searches for the chai obj.should call down the AST.
178
+ * @param {ASTNode} node - any node
179
+ * @returns {ASTNode} obj.should call expression or null
180
+ */
181
+ function findShouldCall(node) {
182
+ // Found obj.should call, return the node
183
+ if (node.type === 'MemberExpression' && node.property && node.property.name === 'should') {
184
+ return node;
185
+ }
186
+
187
+ // Continue search up the AST if it's a member call
188
+ if (node.type === 'MemberExpression') {
189
+ return findShouldCall(node.object);
190
+ }
191
+ if (node.type === 'CallExpression') {
192
+ return findShouldCall(node.callee);
193
+ }
194
+
195
+ // Stop search, obj.should not found
196
+ return null;
197
+ }
147
198
 
148
199
 
149
200
  return {
150
201
  ExpressionStatement: function(node) {
151
- if (!isValidExpression(node.expression) && !isDirective(node, context.getAncestors()) && !isChaiExpectation(node)) {
202
+ var valid = isValidExpression(node.expression)
203
+ || isDirective(node, context.getAncestors())
204
+ || isChaiExpectCall(node)
205
+ || isChaiShouldCall(node);
206
+ if (!valid) {
152
207
  context.report(node, "Expected an assignment or function call and instead saw an expression.");
153
208
  }
154
209
  }
155
210
  };
156
211
  }
157
- };
212
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-chai-friendly",
3
- "version": "0.3.6",
3
+ "version": "0.6.0",
4
4
  "description": "This plugin makes 'no-unused-expressions' rule friendly towards chai expect statements.",
5
5
  "keywords": [
6
6
  "eslint",
@@ -18,17 +18,23 @@
18
18
  "url": "https://github.com/ihordiachenko/eslint-plugin-chai-friendly/issues"
19
19
  },
20
20
  "author": "Ihor Diachenko",
21
+ "contributors": [
22
+ "Brett Zamir"
23
+ ],
21
24
  "main": "lib/index.js",
22
25
  "scripts": {
23
- "test": "mocha tests --recursive"
26
+ "lint": "eslint .",
27
+ "test": "nyc mocha tests --recursive"
24
28
  },
25
29
  "dependencies": {},
26
30
  "peerDependencies": {
27
31
  "eslint": ">=3.0.0"
28
32
  },
29
33
  "devDependencies": {
30
- "eslint": "~3.11.0",
31
- "mocha": "^3.0.2"
34
+ "babel-eslint": "^10.1.0",
35
+ "eslint": "~6.6.0",
36
+ "mocha": "^7.1.1",
37
+ "nyc": "^15.0.1"
32
38
  },
33
39
  "engines": {
34
40
  "node": ">=0.10.0"
@@ -20,6 +20,10 @@ var ruleTester = new RuleTester();
20
20
 
21
21
  ruleTester.run("no-unused-expressions", rule, {
22
22
  valid: [
23
+ {
24
+ code: "import('./some-file.js');",
25
+ parser: require.resolve("babel-eslint")
26
+ },
23
27
  "function f(){}",
24
28
  "a = b",
25
29
  "new a",
@@ -27,16 +31,16 @@ ruleTester.run("no-unused-expressions", rule, {
27
31
  "f(); g()",
28
32
  "i++",
29
33
  "a()",
30
- { code: "a && a()", options: [{ allowShortCircuit: true }] },
31
- { code: "a() || (b = c)", options: [{ allowShortCircuit: true }] },
32
- { code: "a ? b() : c()", options: [{ allowTernary: true }] },
33
- { code: "a ? b() || (c = d) : e()", options: [{ allowShortCircuit: true, allowTernary: true }] },
34
+ { code: "a && a()", options: [{ allowShortCircuit: true }]},
35
+ { code: "a() || (b = c)", options: [{ allowShortCircuit: true }]},
36
+ { code: "a ? b() : c()", options: [{ allowTernary: true }]},
37
+ { code: "a ? b() || (c = d) : e()", options: [{ allowShortCircuit: true, allowTernary: true }]},
34
38
  "delete foo.bar",
35
39
  "void new C",
36
40
  "\"use strict\";",
37
41
  "\"directive one\"; \"directive two\"; f();",
38
42
  "function foo() {\"use strict\"; return true; }",
39
- { code: "var foo = () => {\"use strict\"; return true; }", parserOptions: { ecmaVersion: 6 } },
43
+ { code: "var foo = () => {\"use strict\"; return true; }", parserOptions: { ecmaVersion: 6 }},
40
44
  "function foo() {\"directive one\"; \"directive two\"; f(); }",
41
45
  "function foo() { var foo = \"use strict\"; return true; }",
42
46
  {
@@ -61,33 +65,77 @@ ruleTester.run("no-unused-expressions", rule, {
61
65
  options: [{ allowTernary: true }],
62
66
  parserOptions: { ecmaVersion: 8 }
63
67
  },
64
- "expect(foo).to.be.ok",
65
- "expect(foo).be.ok",
66
- "expect(foo).to.eventually().be.ok"
68
+ {
69
+ code: "tag`tagged template literal`",
70
+ options: [{ allowTaggedTemplates: true }],
71
+ parserOptions: { ecmaVersion: 6 }
72
+ },
73
+ {
74
+ code: "shouldNotBeAffectedByAllowTemplateTagsOption()",
75
+ options: [{ allowTaggedTemplates: true }],
76
+ parserOptions: { ecmaVersion: 6 }
77
+ },
78
+ // Chai statements
79
+ "expect(foo).to.be.true;",
80
+ "expect(foo).to.have.a.property('bar').which.is.true",
81
+ "foo.should.be.true;",
82
+ "foo.inner.nested.should.be.true",
83
+ "foo.should.have.a.property('bar').which.is.true;"
67
84
  ],
68
85
  invalid: [
69
- { code: "0", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
70
- { code: "a", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
71
- { code: "f(), 0", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
72
- { code: "{0}", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
73
- { code: "[]", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
74
- { code: "a && b();", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
75
- { code: "a() || false", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }] },
76
- { code: "a || (b = c)", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }] },
77
- { code: "a ? b() || (c = d) : e", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }] },
86
+ { code: "0", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
87
+ { code: "a", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
88
+ { code: "f(), 0", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
89
+ { code: "{0}", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
90
+ { code: "[]", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
91
+ { code: "a && b();", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
92
+ { code: "a() || false", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }]},
93
+ { code: "a || (b = c)", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }]},
94
+ { code: "a ? b() || (c = d) : e", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }]},
78
95
  { code: "a && b()", options: [{ allowTernary: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }]},
79
96
  { code: "a ? b() : c()", options: [{ allowShortCircuit: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }]},
80
- { code: "a || b", options: [{ allowShortCircuit: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
81
- { code: "a() && b", options: [{ allowShortCircuit: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
82
- { code: "a ? b : 0", options: [{ allowTernary: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
83
- { code: "a ? b : c()", options: [{ allowTernary: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
84
- { code: "foo.bar;", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
85
- { code: "!a", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
86
- { code: "+a", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
87
- { code: "\"directive one\"; f(); \"directive two\";", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
88
- { code: "function foo() {\"directive one\"; f(); \"directive two\"; }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
89
- { code: "if (0) { \"not a directive\"; f(); }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
90
- { code: "function foo() { var foo = true; \"use strict\"; }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] },
91
- { code: "var foo = () => { var foo = true; \"use strict\"; }", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}] }
97
+ { code: "a || b", options: [{ allowShortCircuit: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
98
+ { code: "a() && b", options: [{ allowShortCircuit: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
99
+ { code: "a ? b : 0", options: [{ allowTernary: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
100
+ { code: "a ? b : c()", options: [{ allowTernary: true }], errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
101
+ { code: "foo.bar;", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
102
+ { code: "!a", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
103
+ { code: "+a", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
104
+ { code: "\"directive one\"; f(); \"directive two\";", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
105
+ { code: "function foo() {\"directive one\"; f(); \"directive two\"; }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
106
+ { code: "if (0) { \"not a directive\"; f(); }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
107
+ { code: "function foo() { var foo = true; \"use strict\"; }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
108
+ { code: "var foo = () => { var foo = true; \"use strict\"; }", parserOptions: { ecmaVersion: 6}, errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement"}]},
109
+ {
110
+ code: "`untagged template literal`",
111
+ options: [{ allowTaggedTemplates: true }],
112
+ parserOptions: { ecmaVersion: 6},
113
+ errors: ["Expected an assignment or function call and instead saw an expression."]
114
+ },
115
+ {
116
+ code: "`untagged template literal`",
117
+ options: [{ allowTaggedTemplates: false }],
118
+ parserOptions: { ecmaVersion: 6},
119
+ errors: ["Expected an assignment or function call and instead saw an expression."]
120
+ },
121
+ {
122
+ code: "tag`tagged template literal`",
123
+ options: [{ allowTaggedTemplates: false }],
124
+ parserOptions: { ecmaVersion: 6},
125
+ errors: ["Expected an assignment or function call and instead saw an expression."]
126
+ },
127
+ {
128
+ code: "`untagged template literal`",
129
+ parserOptions: { ecmaVersion: 6 },
130
+ errors: ["Expected an assignment or function call and instead saw an expression."]
131
+ },
132
+ {
133
+ code: "tag`tagged template literal`",
134
+ parserOptions: { ecmaVersion: 6 },
135
+ errors: ["Expected an assignment or function call and instead saw an expression."]
136
+ },
137
+ // Chai statements
138
+ { code: "foo.expect('bar').not.to.pass;", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }]},
139
+ { code: "should.not.pass;", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }] },
92
140
  ]
93
- });
141
+ });
package/.npmignore DELETED
@@ -1 +0,0 @@
1
- ./tests