Skip to content

Commit 314557c

Browse files
brettz9chiawendt
authored andcommitted
feat(match-description): allow main description: string|boolean to override or disable main description separate from default
feat(match-description): add `contexts` and `noDefaults` options for control on which contexts the rules apply feat(match-description): report line number with `match-description` feat(match-description): allow reporting multiple errors when main description validation fails docs(match-description): indicate default uses 'u' flag and is not case-insensitive testing(match-description): better Cyrillic checks (insist upper-case followed by lower-case and period)
1 parent d7a9632 commit 314557c

File tree

4 files changed

+319
-16
lines changed

4 files changed

+319
-16
lines changed

.README/rules/match-description.md

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,39 @@ tag should be linted with the `matchDescription` value (or the default).
5050
}
5151
```
5252

53+
If you wish to override the main function description without changing the
54+
default `mainDescription`, you may use `tags` with `main description`:
5355

54-
By default, only the main function description is linted.
56+
```js
57+
{
58+
'jsdoc/match-description': ['error', {tags: {
59+
'main description': '[A-Z].*\\.',
60+
param: true,
61+
returns: true
62+
}}]
63+
}
64+
```
65+
66+
There is no need to add `"main description": true`, as by default, the main
67+
function (and only the main function) is linted, though you may disable checking
68+
it by setting it to `false`.
69+
70+
##### `contexts`
71+
72+
Set this to a string or array of strings representing the AST context
73+
where you wish the rule to be applied (e.g., `ClassDeclaration` for ES6 classes).
74+
75+
##### `noDefaults`
76+
77+
By default, `contexts` will permit `ArrowFunctionExpression`,
78+
`FunctionDeclaration`, and `FunctionExpression`. Set this instead to `true` to
79+
have `contexts` override these.
5580

5681
|||
5782
|---|---|
58-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
83+
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`; others when `contexts` option enabled|
5984
|Tags|N/A by default but see `tags` options|
6085
|Settings||
61-
|Options|`tags` (allows for 'param', 'arg', 'argument', 'returns', 'return'), `matchDescription`|
86+
|Options|`contexts`, `noDefaults`, `tags` (allows for 'param', 'arg', 'argument', 'returns', 'return'), `matchDescription`|
6287

6388
<!-- assertions matchDescription -->

README.md

Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,15 +2299,42 @@ tag should be linted with the `matchDescription` value (or the default).
22992299
}
23002300
```
23012301

2302+
If you wish to override the main function description without changing the
2303+
default `mainDescription`, you may use `tags` with `main description`:
23022304

2303-
By default, only the main function description is linted.
2305+
```js
2306+
{
2307+
'jsdoc/match-description': ['error', {tags: {
2308+
'main description': '[A-Z].*\\.',
2309+
param: true,
2310+
returns: true
2311+
}}]
2312+
}
2313+
```
2314+
2315+
There is no need to add `"main description": true`, as by default, the main
2316+
function (and only the main function) is linted, though you may disable checking
2317+
it by setting it to `false`.
2318+
2319+
<a name="eslint-plugin-jsdoc-rules-match-description-options-1-contexts"></a>
2320+
##### <code>contexts</code>
2321+
2322+
Set this to a string or array of strings representing the AST context
2323+
where you wish the rule to be applied (e.g., `ClassDeclaration` for ES6 classes).
2324+
2325+
<a name="eslint-plugin-jsdoc-rules-match-description-options-1-nodefaults"></a>
2326+
##### <code>noDefaults</code>
2327+
2328+
By default, `contexts` will permit `ArrowFunctionExpression`,
2329+
`FunctionDeclaration`, and `FunctionExpression`. Set this instead to `true` to
2330+
have `contexts` override these.
23042331

23052332
|||
23062333
|---|---|
2307-
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
2334+
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`; others when `contexts` option enabled|
23082335
|Tags|N/A by default but see `tags` options|
23092336
|Settings||
2310-
|Options|`tags` (allows for 'param', 'arg', 'argument', 'returns', 'return'), `matchDescription`|
2337+
|Options|`contexts`, `noDefaults`, `tags` (allows for 'param', 'arg', 'argument', 'returns', 'return'), `matchDescription`|
23112338

23122339
The following patterns are considered problems:
23132340

@@ -2335,6 +2362,18 @@ function quux () {
23352362

23362363
}
23372364
// Options: [{"matchDescription":"[А-Я][А-я]+\\."}]
2365+
<<<<<<< HEAD
2366+
=======
2367+
// Message: JSDoc description does not satisfy the regex pattern.
2368+
2369+
/**
2370+
* тест.
2371+
*/
2372+
function quux () {
2373+
2374+
}
2375+
// Options: [{"tags":{"main description":"[А-Я][А-я]+\\.","param":true}}]
2376+
>>>>>>> feat(match-description): allow `main description: string|boolean` to override or disable main description separate from default
23382377
// Message: JSDoc description does not satisfy the regex pattern.
23392378

23402379
/**
@@ -2356,6 +2395,28 @@ function quux (foo) {
23562395
// Options: [{"tags":{"param":true}}]
23572396
// Message: JSDoc description does not satisfy the regex pattern.
23582397

2398+
/**
2399+
* Foo
2400+
*
2401+
* @param foo foo.
2402+
*/
2403+
function quux (foo) {
2404+
2405+
}
2406+
// Options: [{"tags":{"main description":"^[a-zA-Z]*$","param":true}}]
2407+
// Message: JSDoc description does not satisfy the regex pattern.
2408+
2409+
/**
2410+
* Foo
2411+
*
2412+
* @param foo foo.
2413+
*/
2414+
function quux (foo) {
2415+
2416+
}
2417+
// Options: [{"tags":{"main description":false,"param":true}}]
2418+
// Message: JSDoc description does not satisfy the regex pattern.
2419+
23592420
/**
23602421
* Foo.
23612422
*
@@ -2456,6 +2517,18 @@ function quux () {
24562517

24572518
}
24582519
// Options: [{"tags":{"param":"[А-Я][А-я]+\\."}}]
2520+
<<<<<<< HEAD
2521+
=======
2522+
// Message: JSDoc description does not satisfy the regex pattern.
2523+
2524+
/**
2525+
* foo.
2526+
*/
2527+
class quux {
2528+
2529+
}
2530+
// Options: [{"contexts":["ClassDeclaration"],"noDefaults":true}]
2531+
>>>>>>> feat(match-description): allow `main description: string|boolean` to override or disable main description separate from default
24592532
// Message: JSDoc description does not satisfy the regex pattern.
24602533
````
24612534

@@ -2585,6 +2658,30 @@ function quux () {
25852658
function quux () {
25862659

25872660
}
2661+
2662+
/**
2663+
* foo.
2664+
*/
2665+
function quux () {
2666+
2667+
}
2668+
// Options: [{"tags":{"main description":false}}]
2669+
2670+
/**
2671+
* foo.
2672+
*/
2673+
class quux {
2674+
2675+
}
2676+
// Message: JSDoc description does not satisfy the regex pattern.
2677+
2678+
/**
2679+
* foo.
2680+
*/
2681+
class quux {
2682+
2683+
}
2684+
// Options: [{"tags":{"main description":true}}]
25882685
````
25892686

25902687

src/rules/matchDescription.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,13 @@ export default iterateJsdoc(({
1212
const options = context.options[0] || {};
1313

1414
const validateDescription = (description, tag) => {
15+
const tagName = tag.tag;
16+
const tagOptions = options.tags || {};
17+
if (tagOptions[tagName] === false) {
18+
return;
19+
}
1520
const regex = new RegExp(
16-
(tag && typeof options.tags[tag] === 'string' ? options.tags[tag] :
21+
(typeof tagOptions[tagName] === 'string' ? tagOptions[tagName] :
1722
options.matchDescription
1823

1924
// If supporting Node >= 10, we could loosen to this for the
@@ -23,16 +28,16 @@ export default iterateJsdoc(({
2328
);
2429

2530
if (!regex.test(description)) {
26-
report('JSDoc description does not satisfy the regex pattern.');
27-
28-
return true;
31+
report('JSDoc description does not satisfy the regex pattern.', null, tag);
2932
}
30-
31-
return false;
3233
};
3334

34-
if (jsdoc.description && validateDescription(jsdoc.description)) {
35-
return;
35+
if (jsdoc.description) {
36+
validateDescription(jsdoc.description, {
37+
// Add one as description would typically be into block
38+
line: jsdoc.line + 1,
39+
tag: 'main description'
40+
});
3641
}
3742

3843
if (!options.tags || !Object.keys(options.tags).length) {
@@ -47,18 +52,36 @@ export default iterateJsdoc(({
4752
tags.some((tag) => {
4853
const description = _.trimStart(tag.description, '- ');
4954

50-
return validateDescription(description, tag.tag);
55+
return validateDescription(description, tag);
5156
});
5257
}, {
58+
contextDefaults: true,
5359
meta: {
5460
schema: [
5561
{
5662
additionalProperties: false,
5763
properties: {
64+
contexts: {
65+
oneOf: [
66+
{
67+
items: {
68+
type: 'string'
69+
},
70+
type: 'array'
71+
},
72+
{
73+
type: 'string'
74+
}
75+
]
76+
},
5877
matchDescription: {
5978
format: 'regex',
6079
type: 'string'
6180
},
81+
noDefaults: {
82+
default: false,
83+
type: 'boolean'
84+
},
6285
tags: {
6386
patternProperties: {
6487
'.*': {
@@ -68,7 +91,6 @@ export default iterateJsdoc(({
6891
type: 'string'
6992
},
7093
{
71-
enum: [true],
7294
type: 'boolean'
7395
}
7496
]

0 commit comments

Comments
 (0)