Skip to content

Commit 379e9ff

Browse files
Sergey ZarouskiAlexej Yaroshevich
authored andcommitted
enforceExistence: add paramless-procedures exception
Fixes #139 Closes gh-141
1 parent c768497 commit 379e9ff

File tree

4 files changed

+113
-11
lines changed

4 files changed

+113
-11
lines changed

.jscsrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"plugins": ["jscs-jsdoc"],
2+
"plugins": ["../jscs-jsdoc"],
33
"preset": "google",
44

55
"fileExtensions": [ ".js", ".jscs" ],

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,9 +552,16 @@ function _e() {}
552552

553553
Ensures jsdoc block exist
554554

555-
Type: `Boolean` or `String`
556-
557-
Values: `true` or `"exceptExports"` (skip `module.exports = function () {};`)
555+
Type: `Boolean`, `String` or `Object`
556+
557+
Values:
558+
- `true`
559+
- `"exceptExports"` (*deprecated* use `"allExcept": ["exports"]`)
560+
- `Object`:
561+
- `"allExcept"` array of exceptions:
562+
- `"expressions"` skip expression functions
563+
- `"exports"` skip `module.exports = function () {};`
564+
- `"paramless-procedures"` functions without parameters and with empty return statements will be skipped
558565

559566
Context: `functions`
560567

lib/rules/validate-jsdoc/enforce-existence.js

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var assert = require('assert');
2+
var esprimaHelpers = require('../../esprima-helpers');
23

34
module.exports = enforceExistence;
45
module.exports.scopes = ['function'];
@@ -16,7 +17,8 @@ enforceExistence.configure = function(options) {
1617
all: true,
1718
anonymous: false,
1819
exports: true,
19-
expressions: true
20+
expressions: true,
21+
'paramless-procedures': true,
2022
};
2123

2224
// check options are valid
@@ -26,18 +28,23 @@ enforceExistence.configure = function(options) {
2628
'jsDoc.enforceExistence rule was not configured properly'
2729
);
2830

31+
var optionsToPolicyMap = Object.keys(policy);
32+
/**
33+
* @param {string} option
34+
*/
35+
function updatePolicyRules(option) {
36+
if (o.allExcept.indexOf(option) > -1) {
37+
policy[option] = !policy[option];
38+
}
39+
}
40+
2941
// parse options for policies
3042
if (o === false) {
3143
policy.all = false;
3244
} else if (typeof o === 'string' && o === 'exceptExports') { // backward compatible string option
3345
policy.exports = false;
3446
} else if (typeof o === 'object' && Array.isArray(o.allExcept)) {
35-
if (o.allExcept.indexOf('exports') > -1) {
36-
policy.exports = false;
37-
}
38-
if (o.allExcept.indexOf('expressions') > -1) {
39-
policy.expressions = false;
40-
}
47+
optionsToPolicyMap.forEach(updatePolicyRules);
4148
}
4249

4350
};
@@ -80,6 +87,21 @@ function enforceExistence(node, err) {
8087
return;
8188
}
8289
}
90+
if (policy['paramless-procedures'] === false) {
91+
var hasReturnsWhichRequireJsdoc = false;
92+
this._iterate(function(n) {
93+
if (hasReturnsWhichRequireJsdoc) {
94+
return;
95+
}
96+
var isReturnWithValue = n && n.type === 'ReturnStatement' && n.argument;
97+
var isInCurrentScope = node === esprimaHelpers.closestScopeNode(n);
98+
hasReturnsWhichRequireJsdoc = isReturnWithValue && isInCurrentScope;
99+
}, node);
100+
if (!node.params.length && !hasReturnsWhichRequireJsdoc) {
101+
// don't check functions without params
102+
return;
103+
}
104+
}
83105

84106
// now clear to check for documentation
85107
if (node.jsdoc) {

test/lib/rules/validate-jsdoc/enforce-existence.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,77 @@ describe('lib/rules/validate-jsdoc/enforce-existence', function () {
218218
]);
219219
});
220220

221+
describe('with allExcept paramless-procedures', function() {
222+
checker.rules({enforceExistence: {allExcept: ['paramless-procedures']}});
223+
224+
checker.cases([
225+
/* jshint ignore:start */
226+
{
227+
it: 'should not report jsdocs absence for function expressions without parameters',
228+
code: function () {
229+
var functionalExpression = function () {
230+
};
231+
}
232+
}, {
233+
it: 'should not report jsdocs absence for function declarations without parameters',
234+
code: function () {
235+
function func() {
236+
}
237+
}
238+
}, {
239+
it: 'should not report jsdocs absence for function expressions with undefined returns',
240+
code: function () {
241+
var functionalExpression = function () {
242+
return;
243+
};
244+
var functionalExpressionNoReturn = function () {
245+
/** @returns {number}*/
246+
var nestedHasReturn = function () {
247+
return 1;
248+
};
249+
};
250+
}
251+
}, {
252+
it: 'should report jsdocs absence for function expressions with defined returns',
253+
code: function () {
254+
var functionalExpression = function () {
255+
return false;
256+
};
257+
var functionalExpressionNoReturn = function () {
258+
var nestedHasReturn = function () {
259+
return 1;
260+
};
261+
};
262+
},
263+
errors: 2
264+
}, {
265+
it: 'should not report jsdocs absence for function declarations with undefined returns',
266+
code: function () {
267+
function func() {
268+
return;
269+
}
270+
function noReturn() {
271+
/** @returns {number}*/
272+
function nestedHasReturn() {
273+
return 1;
274+
}
275+
}
276+
}
277+
}, {
278+
it: 'should report jsdocs absence for function declarations with defined returns',
279+
code: function () {
280+
function func() {
281+
return false;
282+
}
283+
function noReturn() {
284+
function nestedHasReturn() {
285+
return 1;
286+
}
287+
}
288+
},
289+
errors: 2
290+
}
291+
/* jshint ignore:end */
292+
]);
293+
});
221294
});

0 commit comments

Comments
 (0)