Skip to content

Commit

Permalink
feat(match-description): allow arbitrary tags; also fixes returns
Browse files Browse the repository at this point in the history
…/`return` to avoid skipping matching of an initial "name" and space
  • Loading branch information
brettz9 authored and golopot committed Jul 8, 2019
1 parent eab2813 commit 9263fba
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 6 deletions.
10 changes: 9 additions & 1 deletion .README/rules/match-description.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ tag should be linted with the `matchDescription` value (or the default).
}
```

The tags `@param`/`@arg`/`@argument` will be properly parsed to ensure that
the matched "description" text includes only the text after the name.
All other tags will treat the text following the tag name, a space, and
an optional curly-bracketed type expression (and another space) as part of
its "description" (e.g., for `@returns {someType} some description`, the
description is `some description` while for `@some-tag xyz`, the description
is `xyz`).

##### `mainDescription`

If you wish to override the main function description without changing the
Expand Down Expand Up @@ -82,6 +90,6 @@ Overrides the default contexts (see below).
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`; others when `contexts` option enabled|
|Tags|N/A by default but see `tags` options|
|Settings||
|Options|`contexts`, `tags` (allows for 'param', 'arg', 'argument', 'returns', 'return', 'description', 'desc'), `mainDescription`, `matchDescription`|
|Options|`contexts`, `tags` (allows for 'param', 'arg', 'argument', 'description', 'desc', and any added to `tags` option, e.g., 'returns', 'return'), `mainDescription`, `matchDescription`|

<!-- assertions matchDescription -->
81 changes: 80 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2428,6 +2428,14 @@ tag should be linted with the `matchDescription` value (or the default).
}
```

The tags `@param`/`@arg`/`@argument` will be properly parsed to ensure that
the matched "description" text includes only the text after the name.
All other tags will treat the text following the tag name, a space, and
an optional curly-bracketed type expression (and another space) as part of
its "description" (e.g., for `@returns {someType} some description`, the
description is `some description` while for `@some-tag xyz`, the description
is `xyz`).

<a name="eslint-plugin-jsdoc-rules-match-description-options-3-maindescription"></a>
##### <code>mainDescription</code>

Expand Down Expand Up @@ -2462,7 +2470,7 @@ Overrides the default contexts (see below).
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`; others when `contexts` option enabled|
|Tags|N/A by default but see `tags` options|
|Settings||
|Options|`contexts`, `tags` (allows for 'param', 'arg', 'argument', 'returns', 'return', 'description', 'desc'), `mainDescription`, `matchDescription`|
|Options|`contexts`, `tags` (allows for 'param', 'arg', 'argument', 'description', 'desc', and any added to `tags` option, e.g., 'returns', 'return'), `mainDescription`, `matchDescription`|

The following patterns are considered problems:

Expand Down Expand Up @@ -2538,6 +2546,39 @@ function quux (foo) {
// Options: [{"tags":{"param":true}}]
// Message: JSDoc description does not satisfy the regex pattern.

/**
* Foo.
*
* @summary foo.
*/
function quux () {

}
// Options: [{"tags":{"summary":true}}]
// Message: JSDoc description does not satisfy the regex pattern.

/**
* Foo.
*
* @author
*/
function quux () {

}
// Options: [{"tags":{"author":".+"}}]
// Message: JSDoc description does not satisfy the regex pattern.

/**
* Foo.
*
* @x-tag
*/
function quux () {

}
// Options: [{"tags":{"x-tag":".+"}}]
// Message: JSDoc description does not satisfy the regex pattern.

/**
* Foo.
*
Expand Down Expand Up @@ -2797,6 +2838,14 @@ function quux () {
}
// Options: [{"tags":{"returns":true}}]

/**
* @returns {type1} Foo bar.
*/
function quux () {

}
// Options: [{"tags":{"returns":true}}]

/**
* @description Foo bar.
*/
Expand Down Expand Up @@ -2934,6 +2983,36 @@ function quux () {

}
// Options: [{"tags":{"param":true}}]

/**
* Foo.
*
* @summary Foo.
*/
function quux () {

}
// Options: [{"tags":{"summary":true}}]

/**
* Foo.
*
* @author Somebody
*/
function quux () {

}
// Options: [{"tags":{"author":".+"}}]

/**
* Foo.
*
* @x-tag something
*/
function quux () {

}
// Options: [{"tags":{"x-tag":".+"}}]
````


Expand Down
26 changes: 22 additions & 4 deletions src/rules/matchDescription.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'lodash';
import iterateJsdoc from '../iterateJsdoc';

const tagsWithDescriptions = ['param', 'arg', 'argument', 'returns', 'return'];
const tagsWithNamesAndDescriptions = ['param', 'arg', 'argument'];

// If supporting Node >= 10, we could loosen the default to this for the
// initial letter: \\p{Upper}
Expand Down Expand Up @@ -57,22 +57,40 @@ export default iterateJsdoc(({
return Boolean(options.tags[tagName]);
};

let descName;
utils.forEachPreferredTag('description', (matchingJsdocTag, targetTagName) => {
descName = targetTagName;
const description = (matchingJsdocTag.name + ' ' + matchingJsdocTag.description).trim();
if (hasOptionTag(targetTagName)) {
validateDescription(description, matchingJsdocTag);
}
});

const tags = utils.filterTags(({tag}) => {
return tagsWithDescriptions.includes(tag) && hasOptionTag(tag);
const tagsWithoutNames = [];
const tagsWithNames = utils.filterTags((tag) => {
const {tag: tagName} = tag;
if (!hasOptionTag(tagName)) {
return false;
}
const tagWithName = tagsWithNamesAndDescriptions.includes(tagName);
if (!tagWithName && tagName !== descName) {
tagsWithoutNames.push(tag);
}

return tagWithName;
});

tags.some((tag) => {
tagsWithNames.some((tag) => {
const description = _.trimStart(tag.description, '- ');

return validateDescription(description, tag);
});

tagsWithoutNames.some((tag) => {
const description = (tag.name + ' ' + tag.description).trim();

return validateDescription(description, tag);
});
}, {
contextDefaults: true,
meta: {
Expand Down
149 changes: 149 additions & 0 deletions test/rules/assertions/matchDescription.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,81 @@ export default {
}
]
},
{
code: `
/**
* Foo.
*
* @summary foo.
*/
function quux () {
}
`,
errors: [
{
line: 5,
message: 'JSDoc description does not satisfy the regex pattern.'
}
],
options: [
{
tags: {
summary: true
}
}
]
},
{
code: `
/**
* Foo.
*
* @author
*/
function quux () {
}
`,
errors: [
{
line: 5,
message: 'JSDoc description does not satisfy the regex pattern.'
}
],
options: [
{
tags: {
author: '.+'
}
}
]
},
{
code: `
/**
* Foo.
*
* @x-tag
*/
function quux () {
}
`,
errors: [
{
line: 5,
message: 'JSDoc description does not satisfy the regex pattern.'
}
],
options: [
{
tags: {
'x-tag': '.+'
}
}
]
},
{
code: `
/**
Expand Down Expand Up @@ -706,6 +781,23 @@ export default {
}
]
},
{
code: `
/**
* @returns {type1} Foo bar.
*/
function quux () {
}
`,
options: [
{
tags: {
returns: true
}
}
]
},
{
code: `
/**
Expand Down Expand Up @@ -937,6 +1029,63 @@ export default {
param: true
}}
]
},
{
code: `
/**
* Foo.
*
* @summary Foo.
*/
function quux () {
}
`,
options: [
{
tags: {
summary: true
}
}
]
},
{
code: `
/**
* Foo.
*
* @author Somebody
*/
function quux () {
}
`,
options: [
{
tags: {
author: '.+'
}
}
]
},
{
code: `
/**
* Foo.
*
* @x-tag something
*/
function quux () {
}
`,
options: [
{
tags: {
'x-tag': '.+'
}
}
]
}
]
};

0 comments on commit 9263fba

Please sign in to comment.