Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 102 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

[![NPM version](https://img.shields.io/npm/v/jscs-jsdoc.svg)](https://www.npmjs.com/package/jscs-jsdoc)
[![NPM downloads](https://img.shields.io/npm/dm/jscs-jsdoc.svg)](https://www.npmjs.com/package/jscs-jsdoc)
[![MIT License](https://img.shields.io/npm/l/jscs-jsdoc.svg)](https://github.com/jscs-dev/jscs-jsdoc/blob/master/LICENSExc)
[![MIT License](https://img.shields.io/npm/l/jscs-jsdoc.svg)](https://github.com/jscs-dev/jscs-jsdoc/blob/master/LICENSE)

`jsdoc` plugin for [jscs](https://github.com/jscs-dev/node-jscs/). [Twitter](https://twitter.com/jscs_dev) | [Mailing List](https://groups.google.com/group/jscs-dev)

Expand Down Expand Up @@ -616,6 +616,107 @@ function method() {}
function method() {}
```


### requireNewlineAfterDescription

Ensures a doc comment description has padding newline

Type: `Boolean`

Values: `true`

Context: `functions`

Tags: `*`

#### Example

```js
"requireNewlineAfterDescription": true
```

##### Valid

```js
/**
* @param {String} - message
*/
function method() {}

/**
* Description
*/
function method() {}

/**
* Description
*
* @param {String} - message
*/
function method() {}
```

##### Invalid

```js
/**
* Description
* @param {String} message
*/
function method() {}
```


### disallowNewlineAfterDescription

Ensures a doc comment description has no padding newlines

Type: `Boolean`

Values: `true`

Context: `functions`

Tags: `*`

#### Example

```js
"disallowNewlineAfterDescription": true
```

##### Valid

```js
/**
* @param {String} - message
*/
function method() {}

/**
* Description
*/
function method() {}

/**
* Description
* @param {String} - message
*/
function method() {}
```

##### Invalid

```js
/**
* Description
*
* @param {String} message
*/
function method() {}
```


## Browser Usage

NOT SUPPORTED ATM. SORRY.
Expand Down
4 changes: 3 additions & 1 deletion lib/jsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ function DocComment(value, loc) {
this.valid = _parsed.hasOwnProperty('line');

// doc parsed data
this.description = _parsed.description || null;
this.description = _parsed.source && _parsed.description ?
_parsed.source.substr(0, _parsed.source.indexOf('\n@')) : null;

this.tags = (_parsed.tags || []).map(function(tag) {
return new DocTag(tag, new DocLocation(tag.line, 3, loc.start));
});
Expand Down
32 changes: 32 additions & 0 deletions lib/rules/validate-jsdoc/disallow-newline-after-description.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module.exports = disallowNewlineAfterDescription;
module.exports.scopes = ['function'];
module.exports.options = {
disallowNewlineAfterDescription: {allowedValues: [true]}
};

var RE_NEWLINE_AT_THE_END = /\n$/;
var RE_NEWLINES = /\n/g;

/**
* Disallows newline after description in jsdoc comment
*
* @param {(FunctionDeclaration|FunctionExpression)} node
* @param {Function} err
*/
function disallowNewlineAfterDescription(node, err) {
var doc = node.jsdoc;
if (!doc || !doc.tags.length || !doc.description || !doc.description.length) {
return;
}

if (!RE_NEWLINE_AT_THE_END.test(doc.description)) {
return;
}

var loc = node.jsdoc.loc.start;
var lines = doc.description.split(RE_NEWLINES);
err('Newline required after description', {
line: loc.line + lines.length,
column: loc.column + 3 + lines[lines.length - 1].length
});
}
3 changes: 3 additions & 0 deletions lib/rules/validate-jsdoc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ var validatorsByName = module.exports = {

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

requireNewlineAfterDescription: require('./require-newline-after-description'),
disallowNewlineAfterDescription: require('./disallow-newline-after-description'),

checkRedundantAccess: require('./check-redundant-access'),
enforceExistence: require('./enforce-existence'),
leadingUnderscoreAccess: require('./leading-underscore-access')
Expand Down
30 changes: 30 additions & 0 deletions lib/rules/validate-jsdoc/require-newline-after-description.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = requireNewlineAfterDescription;
module.exports.scopes = ['function'];
module.exports.options = {
requireNewlineAfterDescription: {allowedValues: [true]}
};

var RE_NEWLINE_AT_THE_END = /\n$/;
var RE_NEWLINES = /\n/g;

/**
* Requires newline after description in jsdoc comment
*
* @param {(FunctionDeclaration|FunctionExpression)} node
* @param {Function} err
*/
function requireNewlineAfterDescription(node, err) {
var doc = node.jsdoc;
if (!doc || !doc.tags.length || !doc.description || !doc.description.length) {
return;
}

if (!RE_NEWLINE_AT_THE_END.test(doc.description)) {
var loc = node.jsdoc.loc.start;
var lines = doc.description.split(RE_NEWLINES);
err('Newline required after description', {
line: loc.line + lines.length,
column: loc.column + 3 + lines[lines.length - 1].length
});
}
}
14 changes: 8 additions & 6 deletions test/lib/jsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ describe('jsdoc', function() {
'/**\n' +
' * Description\n' +
' * with a new line\n' +
' *\n' +
' * @tag1 value\n' +
' * @param {Type} some long\n' +
' * description of param\n' +
Expand All @@ -138,25 +139,26 @@ describe('jsdoc', function() {
});

it('should parses comment and create all tags and types', function() {
expect(c1.description).to.eq('Description\n with a new line\n');
expect(c1.tags.length).to.eq(4);

var tag1 = c1.tags[0];
expect(tag1.id).to.eq('tag1');
expect(tag1.loc).to.eql(new Location(8, 5));
expect(tag1.loc).to.eql(new Location(9, 5));
expect(tag1.name.value).to.eq('value');
expect(tag1.name.loc).to.eql(new Location(8, 11));
expect(tag1.name.loc).to.eql(new Location(9, 11));

var param = c1.tags[1];
expect(param.id).to.eq('param');
expect(param.loc).to.eql(new Location(9, 5));
expect(param.loc).to.eql(new Location(10, 5));
expect(param.type.value).to.eq('Type');
expect(param.type.loc).to.eql(new Location(9, 13));
expect(param.type.loc).to.eql(new Location(10, 13));
expect(param.name.value).to.eq('some');
expect(param.name.loc).to.eql(new Location(9, 19));
expect(param.name.loc).to.eql(new Location(10, 19));

var abs = c1.tags[2];
expect(abs.id).to.eq('abstract');
expect(abs.loc).to.eql(new Location(11, 5));
expect(abs.loc).to.eql(new Location(12, 5));

var example = c1.tags[3];
expect(example.id).to.eq('example');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
describe('lib/rules/validate-jsdoc/disallow-newline-after-description', function () {
var checker = global.checker({
additionalRules: ['lib/rules/validate-jsdoc.js']
});

describe('not configured', function() {

it('should report with undefined', function() {
global.expect(function() {
checker.configure({disallowNewlineAfterDescription: undefined});
}).to.throws(/accepted value/i);
});

it('should report with an object', function() {
global.expect(function() {
checker.configure({disallowNewlineAfterDescription: {}});
}).to.throws(/accepted value/i);
});

});

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

checker.cases([
/* jshint ignore:start */
{
it: 'should not report common cases',
code: function() {
function fun(p) {
}

/**
* Description
*/
function fun(p) {
}

/**
* @param p
*/
function fun(p) {
}
}
}, {
it: 'should node report newline absence after description',
code: function () {
/**
* Some description
* @param {number} p description without hyphen
*/
function fun(p) {
}
},
}, {
it: 'should report newline after description',
code: function () {
/**
* Some description.
* Get me higher and higher!
*
* @param {number} p description without hyphen
*/
function fun(p) {}
},
errors: {
line: 4,
column: 3
},
}
/* jshint ignore:end */
]);

});

});
76 changes: 76 additions & 0 deletions test/lib/rules/validate-jsdoc/require-newline-after-description.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
describe('lib/rules/validate-jsdoc/require-newline-after-description', function () {
var checker = global.checker({
additionalRules: ['lib/rules/validate-jsdoc.js']
});

describe('not configured', function() {

it('should report with undefined', function() {
global.expect(function() {
checker.configure({requireNewlineAfterDescription: undefined});
}).to.throws(/accepted value/i);
});

it('should report with an object', function() {
global.expect(function() {
checker.configure({requireNewlineAfterDescription: {}});
}).to.throws(/accepted value/i);
});

});

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

checker.cases([
/* jshint ignore:start */
{
it: 'should not report common cases',
code: function() {
function fun(p) {
}

/**
* Description
*/
function fun(p) {
}

/**
* @param p
*/
function fun(p) {
}
}
}, {
it: 'should report newline absence after description',
code: function () {
/**
* Some description
* @param {number} p description without hyphen
*/
function fun(p) {
}
},
errors: {
line: 2,
column: 19
},
}, {
it: 'should not report newline after description',
code: function () {
/**
* Some description.
* Get me higher and higher!
*
* @param {number} p description without hyphen
*/
function fun(p) {}
}
}
/* jshint ignore:end */
]);

});

});