diff --git a/.README/rules/match-description.md b/.README/rules/match-description.md
index a88cdc90d..0b434276d 100644
--- a/.README/rules/match-description.md
+++ b/.README/rules/match-description.md
@@ -37,6 +37,21 @@ You can supply your own expression to override the default, passing a
}
```
+##### `message`
+
+You may provide a custom default message by using the following format:
+
+```js
+{
+ 'jsdoc/match-description': ['error', {
+ message: 'The default dscription should begin with a capital letter.'
+ }]
+}
+```
+
+This can be overridden per tag or for the main block description by setting
+`message` within `tags` or `mainDescription`, respectively.
+
##### `tags`
If you want different regular expressions to apply to tags, you may use
@@ -63,6 +78,18 @@ tag should be linted with the `matchDescription` value (or the default).
}
```
+Alternatively, you may supply an object with a `message` property to indicate
+the error message for that tag.
+
+```js
+{
+ 'jsdoc/match-description': ['error', {tags: {
+ param: {message: 'Begin with a hyphen', match: '\\- [A-Z].*\\.'},
+ returns: {message: 'Capitalize for returns (the default)', match: true}
+ }}]
+}
+```
+
The tags `@param`/`@arg`/`@argument` and `@property`/`@prop` will be properly
parsed to ensure that the matched "description" text includes only the text
after the name.
@@ -75,8 +102,9 @@ is `xyz`).
##### `mainDescription`
-If you wish to override the main function description without changing the
-default `match-description`, you may use `mainDescription`:
+If you wish to override the main block description without changing the
+default `match-description` (which can cascade to the `tags` with `true`),
+you may use `mainDescription`:
```js
{
@@ -91,8 +119,25 @@ default `match-description`, you may use `mainDescription`:
```
There is no need to add `mainDescription: true`, as by default, the main
-function (and only the main function) is linted, though you may disable
-checking it by setting it to `false`.
+block description (and only the main block description) is linted, though you
+may disable checking it by setting it to `false`.
+
+You may also provide an object with `message`:
+
+```js
+{
+ 'jsdoc/match-description': ['error', {
+ mainDescription: {
+ message: 'Capitalize first word of JSDoc block descriptions',
+ match: '[A-Z].*\\.'
+ },
+ tags: {
+ param: true,
+ returns: true
+ }
+ }]
+}
+```
##### `contexts`
diff --git a/README.md b/README.md
index 9e228f980..22df65943 100644
--- a/README.md
+++ b/README.md
@@ -6390,6 +6390,22 @@ You can supply your own expression to override the default, passing a
}
```
+
+##### message
+
+You may provide a custom default message by using the following format:
+
+```js
+{
+ 'jsdoc/match-description': ['error', {
+ message: 'The default dscription should begin with a capital letter.'
+ }]
+}
+```
+
+This can be overridden per tag or for the main block description by setting
+`message` within `tags` or `mainDescription`, respectively.
+
##### tags
@@ -6417,6 +6433,18 @@ tag should be linted with the `matchDescription` value (or the default).
}
```
+Alternatively, you may supply an object with a `message` property to indicate
+the error message for that tag.
+
+```js
+{
+ 'jsdoc/match-description': ['error', {tags: {
+ param: {message: 'Begin with a hyphen', match: '\\- [A-Z].*\\.'},
+ returns: {message: 'Capitalize for returns (the default)', match: true}
+ }}]
+}
+```
+
The tags `@param`/`@arg`/`@argument` and `@property`/`@prop` will be properly
parsed to ensure that the matched "description" text includes only the text
after the name.
@@ -6430,8 +6458,9 @@ is `xyz`).
##### mainDescription
-If you wish to override the main function description without changing the
-default `match-description`, you may use `mainDescription`:
+If you wish to override the main block description without changing the
+default `match-description` (which can cascade to the `tags` with `true`),
+you may use `mainDescription`:
```js
{
@@ -6446,8 +6475,25 @@ default `match-description`, you may use `mainDescription`:
```
There is no need to add `mainDescription: true`, as by default, the main
-function (and only the main function) is linted, though you may disable
-checking it by setting it to `false`.
+block description (and only the main block description) is linted, though you
+may disable checking it by setting it to `false`.
+
+You may also provide an object with `message`:
+
+```js
+{
+ 'jsdoc/match-description': ['error', {
+ mainDescription: {
+ message: 'Capitalize first word of JSDoc block descriptions',
+ match: '[A-Z].*\\.'
+ },
+ tags: {
+ param: true,
+ returns: true
+ }
+ }]
+}
+```
##### contexts
@@ -6482,6 +6528,15 @@ const q = class {
// "jsdoc/match-description": ["error"|"warn", {"contexts":["ClassExpression"]}]
// Message: JSDoc description does not satisfy the regex pattern.
+/**
+ * foo.
+ */
+const q = class {
+
+}
+// "jsdoc/match-description": ["error"|"warn", {"contexts":["ClassExpression"],"message":"Needs to begin with a capital letter and end with an end mark."}]
+// Message: Needs to begin with a capital letter and end with an end mark.
+
/**
* foo.
*/
@@ -6528,6 +6583,15 @@ function quux () {
// "jsdoc/match-description": ["error"|"warn", {"matchDescription":"[А-Я][А-я]+\\."}]
// Message: JSDoc description does not satisfy the regex pattern.
+/**
+ * тест.
+ */
+function quux () {
+
+}
+// "jsdoc/match-description": ["error"|"warn", {"matchDescription":"[А-Я][А-я]+\\.","message":"Needs to begin with a capital letter and end with an end mark."}]
+// Message: Needs to begin with a capital letter and end with an end mark.
+
/**
* Abc.
*/
@@ -6537,6 +6601,15 @@ function quux () {
// "jsdoc/match-description": ["error"|"warn", {"mainDescription":"[А-Я][А-я]+\\.","tags":{"param":true}}]
// Message: JSDoc description does not satisfy the regex pattern.
+/**
+ * Abc.
+ */
+function quux () {
+
+}
+// "jsdoc/match-description": ["error"|"warn", {"mainDescription":{"match":"[А-Я][А-я]+\\.","message":"Needs to begin with a Cyrillic capital letter and end with a period."},"tags":{"param":true}}]
+// Message: Needs to begin with a Cyrillic capital letter and end with a period.
+
/**
* Foo
*/
@@ -6640,6 +6713,17 @@ function quux (foo) {
*/
function quux (foo) {
+}
+// "jsdoc/match-description": ["error"|"warn", {"mainDescription":{"match":"^[a-zA-Z]*$","message":"Letters only"},"tags":{"param":{"match":true,"message":"Needs to begin with a capital letter and end with a period."}}}]
+// Message: Needs to begin with a capital letter and end with a period.
+
+/**
+ * Foo
+ *
+ * @param foo foo.
+ */
+function quux (foo) {
+
}
// "jsdoc/match-description": ["error"|"warn", {"mainDescription":false,"tags":{"param":true}}]
// Message: JSDoc description does not satisfy the regex pattern.
@@ -6858,6 +6942,16 @@ function quux () {
}
+/**
+ * Foo.
+ *
+ * Bar.
+ */
+function quux () {
+
+}
+// "jsdoc/match-description": ["error"|"warn", {"message":"This won't be shown"}]
+
/**
* Тест.
*/
diff --git a/src/rules/matchDescription.js b/src/rules/matchDescription.js
index 595e5cc82..96df6b717 100644
--- a/src/rules/matchDescription.js
+++ b/src/rules/matchDescription.js
@@ -16,28 +16,48 @@ export default iterateJsdoc(({
context,
utils,
}) => {
- const options = context.options[0] || {};
+ const {
+ mainDescription,
+ matchDescription,
+ message,
+ tags,
+ } = context.options[0] || {};
const validateDescription = (description, tag) => {
- if (!tag && options.mainDescription === false) {
+ let mainDescriptionMatch = mainDescription;
+ let errorMessage = message;
+ if (typeof mainDescription === 'object') {
+ mainDescriptionMatch = mainDescription.match;
+ errorMessage = mainDescription.message;
+ }
+ if (!tag && mainDescriptionMatch === false) {
return;
}
- let tagValue = options.mainDescription;
+ let tagValue = mainDescriptionMatch;
if (tag) {
const tagName = tag.tag;
- tagValue = options.tags[tagName];
+ if (typeof tags[tagName] === 'object') {
+ tagValue = tags[tagName].match;
+ errorMessage = tags[tagName].message;
+ } else {
+ tagValue = tags[tagName];
+ }
}
const regex = utils.getRegexFromString(
- stringOrDefault(tagValue, options.matchDescription),
+ stringOrDefault(tagValue, matchDescription),
);
if (!regex.test(description)) {
- report('JSDoc description does not satisfy the regex pattern.', null, tag || {
- // Add one as description would typically be into block
- line: jsdoc.source[0].number + 1,
- });
+ report(
+ errorMessage || 'JSDoc description does not satisfy the regex pattern.',
+ null,
+ tag || {
+ // Add one as description would typically be into block
+ line: jsdoc.source[0].number + 1,
+ },
+ );
}
};
@@ -48,12 +68,12 @@ export default iterateJsdoc(({
);
}
- if (!options.tags || !Object.keys(options.tags).length) {
+ if (!tags || !Object.keys(tags).length) {
return;
}
const hasOptionTag = (tagName) => {
- return Boolean(options.tags[tagName]);
+ return Boolean(tags[tagName]);
};
utils.forEachPreferredTag('description', (matchingJsdocTag, targetTagName) => {
@@ -121,12 +141,35 @@ export default iterateJsdoc(({
{
type: 'boolean',
},
+ {
+ additionalProperties: false,
+ properties: {
+ match: {
+ oneOf: [
+ {
+ format: 'regex',
+ type: 'string',
+ },
+ {
+ type: 'boolean',
+ },
+ ],
+ },
+ message: {
+ type: 'string',
+ },
+ },
+ type: 'object',
+ },
],
},
matchDescription: {
format: 'regex',
type: 'string',
},
+ message: {
+ type: 'string',
+ },
tags: {
patternProperties: {
'.*': {
@@ -139,6 +182,27 @@ export default iterateJsdoc(({
enum: [true],
type: 'boolean',
},
+ {
+ additionalProperties: false,
+ properties: {
+ match: {
+ oneOf: [
+ {
+ format: 'regex',
+ type: 'string',
+ },
+ {
+ enum: [true],
+ type: 'boolean',
+ },
+ ],
+ },
+ message: {
+ type: 'string',
+ },
+ },
+ type: 'object',
+ },
],
},
},
diff --git a/test/rules/assertions/matchDescription.js b/test/rules/assertions/matchDescription.js
index 85ac34012..c2c2973a1 100644
--- a/test/rules/assertions/matchDescription.js
+++ b/test/rules/assertions/matchDescription.js
@@ -23,6 +23,30 @@ export default {
},
],
},
+ {
+ code: `
+ /**
+ * foo.
+ */
+ const q = class {
+
+ }
+ `,
+ errors: [
+ {
+ line: 3,
+ message: 'Needs to begin with a capital letter and end with an end mark.',
+ },
+ ],
+ options: [
+ {
+ contexts: [
+ 'ClassExpression',
+ ],
+ message: 'Needs to begin with a capital letter and end with an end mark.',
+ },
+ ],
+ },
{
code: `
/**
@@ -137,6 +161,26 @@ export default {
matchDescription: '[\u0410-\u042F][\u0410-\u044F]+\\.',
}],
},
+ {
+ code: `
+ /**
+ * тест.
+ */
+ function quux () {
+
+ }
+ `,
+ errors: [
+ {
+ line: 3,
+ message: 'Needs to begin with a capital letter and end with an end mark.',
+ },
+ ],
+ options: [{
+ matchDescription: '[\u0410-\u042F][\u0410-\u044F]+\\.',
+ message: 'Needs to begin with a capital letter and end with an end mark.',
+ }],
+ },
{
code: `
/**
@@ -159,6 +203,31 @@ export default {
},
}],
},
+ {
+ code: `
+ /**
+ * Abc.
+ */
+ function quux () {
+
+ }
+ `,
+ errors: [
+ {
+ line: 3,
+ message: 'Needs to begin with a Cyrillic capital letter and end with a period.',
+ },
+ ],
+ options: [{
+ mainDescription: {
+ match: '[\u0410-\u042F][\u0410-\u044F]+\\.',
+ message: 'Needs to begin with a Cyrillic capital letter and end with a period.',
+ },
+ tags: {
+ param: true,
+ },
+ }],
+ },
{
code: `
/**
@@ -387,6 +456,38 @@ export default {
}
`,
+ errors: [
+ {
+ line: 5,
+ message: 'Needs to begin with a capital letter and end with a period.',
+ },
+ ],
+ options: [
+ {
+ mainDescription: {
+ match: '^[a-zA-Z]*$',
+ message: 'Letters only',
+ },
+ tags: {
+ param: {
+ match: true,
+ message: 'Needs to begin with a capital letter and end with a period.',
+ },
+ },
+ },
+ ],
+ },
+ {
+ code: `
+ /**
+ * Foo
+ *
+ * @param foo foo.
+ */
+ function quux (foo) {
+
+ }
+ `,
errors: [
{
line: 5,
@@ -866,6 +967,21 @@ export default {
}
`,
},
+ {
+ code: `
+ /**
+ * Foo.
+ *
+ * Bar.
+ */
+ function quux () {
+
+ }
+ `,
+ options: [{
+ message: 'This won\'t be shown',
+ }],
+ },
{
code: `
/**