Skip to content

Commit

Permalink
checkAnnotations: add tag checking by presets
Browse files Browse the repository at this point in the history
Fixes #18
  • Loading branch information
Alexej Yaroshevich committed Nov 26, 2014
1 parent f454c98 commit 41f1dbb
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 1 deletion.
4 changes: 4 additions & 0 deletions lib/rules/validate-jsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ module.exports.prototype = {
if (v.options) {
validators.checkOptions(v, options);
}
// configure
if (v.configure) {
v.configure(options);
}
// index rules by tags and scopes
(v.scopes || ['']).forEach(function(scope) {
if (!v.tags) {
Expand Down
77 changes: 77 additions & 0 deletions lib/rules/validate-jsdoc/check-annotations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
var assert = require('assert');

var availablePresets = require('../../tags');
var jsdoc = require('../../jsdoc');

module.exports = validateAnnotations;
module.exports.scopes = ['file'];
module.exports.options = {
checkAnnotations: true
};

var tags;

validateAnnotations.configure = function(options) {
var o = options.checkAnnotations;

assert(o === true || typeof o === 'string' || typeof o === 'object',
'jsDoc.checkAnnotation rule was not configured properly');

if (typeof o === 'string') {
o = {preset: o};
}

tags = {};

if (o === true) {
Object.keys(availablePresets).forEach(function(preset) {
var presetTags = availablePresets[preset];
Object.keys(presetTags).forEach(function(tag) {
tags[tag] = tags[tag] || presetTags[tag];
});
});

} else if (typeof o === 'object') {
if (o.preset) {
assert(typeof o.preset === 'string', 'jsDoc.checkAnnotation.preset should be preset name');
assert(availablePresets[o.preset], 'Unknown tag preset ' + o.preset);
Object.keys(availablePresets[o.preset]).forEach(function(tag) {
tags[tag] = tags[tag] || availablePresets[o.preset][tag];
});
}
if (o.extra) {
Object.keys(o.extra).forEach(function(tag) {
tags[tag] = o.extra[tag];
});
}
}
};

/**
* validator for annotations
* @param {JSCS.JSFile} file
* @param {JSCS.Errors} errors
*/
function validateAnnotations(file, errors) {
var comments = file.getComments();
comments.forEach(function(commentNode) {
if (commentNode.type !== 'Block' || commentNode.value[0] !== '*') {
return;
}

// trying to create DocComment object
var node = jsdoc.createDocCommentByCommentNode(commentNode);
if (!node.valid) {
return;
}

node.iterate(function(tag) {
if (!tags.hasOwnProperty[tag.id]) {
errors.add('unavailable tag ' + tag.id, tag.loc);
}
else if (tags[tag.id] && (!tag.name || !tag.type)) {
errors.add('incomplete tag ' + tag.id + ' data', tag.loc);
}
});
});
}
3 changes: 2 additions & 1 deletion lib/rules/validate-jsdoc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ var validatorsByName = module.exports = {
requireReturnTypes: require('./require-return-types'),
checkRedundantReturns: require('./check-redundant-returns'),

//returns: require('./returns'),
checkAnnotations: require('./check-annotations'),

checkRedundantAccess: require('./check-redundant-access'),
enforceExistence: require('./enforce-existence'),
leadingUnderscoreAccess: require('./leading-underscore-access')
Expand Down
5 changes: 5 additions & 0 deletions lib/tags/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
jsdoc3: require('./jsdoc3'),
jsduck5: require('./jsduck5'),
closurecompiler: require('./closurecompiler')
};
25 changes: 25 additions & 0 deletions test/lib/rules/validate-jsdoc/check-annotations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
describe('lib/rules/validate-jsdoc/check-annotations', function () {
var checker = global.checker({
additionalRules: ['lib/rules/validate-jsdoc.js']
});

describe('with true', function () {
checker.rules({checkAnnotations: true});

checker.cases([
/* jshint ignore:start */
{
it: 'should throw unavailable tag',
errors: {message: 'unavailable tag ppublic'},
code: function() {
/**
* @ppublic
*/
}
}
/* jshint ignore:end */
]);

});

});

0 comments on commit 41f1dbb

Please sign in to comment.