Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(check-param-names): Add disableMissingParamChecks option #1206

Merged
merged 9 commits into from Feb 22, 2024
6 changes: 5 additions & 1 deletion .README/rules/check-param-names.md
Expand Up @@ -81,12 +81,16 @@ item at the same level is destructured as destructuring will prevent other
access and this option is only intended to permit documenting extra properties
that are available and actually used in the function.

### `disableMissingParamChecks`

Whether to check for missing `@param` definitions. Defaults to `false`. Change to `true` if you want to be able to omit properties.
seanpoulter marked this conversation as resolved.
Show resolved Hide resolved

## Context and settings

|||
|---|---|
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
|Options|`allowExtraTrailingParamDocs`, `checkDestructured`, `checkRestProperty`, `checkTypesPattern`, `disableExtraPropertyReporting`, `enableFixer`, `useDefaultObjectProperties`|
|Options|`allowExtraTrailingParamDocs`, `checkDestructured`, `checkRestProperty`, `checkTypesPattern`, `disableExtraPropertyReporting`, `disableMissingParamChecks`, `enableFixer`, `useDefaultObjectProperties`|
|Tags|`param`|
|Aliases|`arg`, `argument`|
|Recommended|true|
Expand Down
8 changes: 7 additions & 1 deletion docs/rules/check-param-names.md
Expand Up @@ -116,14 +116,20 @@ item at the same level is destructured as destructuring will prevent other
access and this option is only intended to permit documenting extra properties
that are available and actually used in the function.

<a name="user-content-check-param-names-options-disableMissingParamChecks"></a>
<a name="check-param-names-options-disableMissingParamChecks"></a>
### <code>disableMissingParamChecks</code>

Whether to check for missing `@param` definitions. Defaults to `false`. Change to `true` if you want to be able to omit properties.

<a name="user-content-check-param-names-context-and-settings"></a>
<a name="check-param-names-context-and-settings"></a>
## Context and settings

|||
|---|---|
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
|Options|`allowExtraTrailingParamDocs`, `checkDestructured`, `checkRestProperty`, `checkTypesPattern`, `disableExtraPropertyReporting`, `enableFixer`, `useDefaultObjectProperties`|
|Options|`allowExtraTrailingParamDocs`, `checkDestructured`, `checkRestProperty`, `checkTypesPattern`, `disableExtraPropertyReporting`, `disableMissingParamChecks`, `enableFixer`, `useDefaultObjectProperties`|
|Tags|`param`|
|Aliases|`arg`, `argument`|
|Recommended|true|
Expand Down
21 changes: 19 additions & 2 deletions src/rules/checkParamNames.js
Expand Up @@ -7,6 +7,7 @@ import iterateJsdoc from '../iterateJsdoc.js';
* @param {boolean} checkRestProperty
* @param {RegExp} checkTypesRegex
* @param {boolean} disableExtraPropertyReporting
* @param {boolean} disableMissingParamChecks
* @param {boolean} enableFixer
* @param {import('../jsdocUtils.js').ParamNameInfo[]} functionParameterNames
* @param {import('comment-parser').Block} jsdoc
Expand All @@ -21,6 +22,7 @@ const validateParameterNames = (
checkRestProperty,
checkTypesRegex,
disableExtraPropertyReporting,
disableMissingParamChecks,
enableFixer,
functionParameterNames, jsdoc, utils, report,
) => {
Expand Down Expand Up @@ -245,10 +247,20 @@ const validateParameterNames = (
return item;
}).filter((item) => {
return item !== 'this';
}).join(', ');
});

// When disableMissingParamChecks is true tag names can be omitted.
// Report when the tag names do not match the expected names or they are used out of order.
if (disableMissingParamChecks) {
const usedExpectedNames = expectedNames.map(a => a?.toString()).filter(expectedName => !!expectedName && actualNames.includes(expectedName));
seanpoulter marked this conversation as resolved.
Show resolved Hide resolved
const usedInOrder = actualNames.every((actualName, idx) => actualName === usedExpectedNames[idx]);
if (usedInOrder) {
return false;
}
}

report(
`Expected @${targetTagName} names to be "${expectedNames}". Got "${actualNames.join(', ')}".`,
`Expected @${targetTagName} names to be "${expectedNames.join(', ')}". Got "${actualNames.join(', ')}".`,
null,
tag,
);
Expand Down Expand Up @@ -329,6 +341,7 @@ export default iterateJsdoc(({
enableFixer = false,
useDefaultObjectProperties = false,
disableExtraPropertyReporting = false,
disableMissingParamChecks = false,
} = context.options[0] || {};

const checkTypesRegex = utils.getRegexFromString(checkTypesPattern);
Expand All @@ -349,6 +362,7 @@ export default iterateJsdoc(({
checkRestProperty,
checkTypesRegex,
disableExtraPropertyReporting,
disableMissingParamChecks,
enableFixer,
functionParameterNames,
jsdoc,
Expand Down Expand Up @@ -389,6 +403,9 @@ export default iterateJsdoc(({
disableExtraPropertyReporting: {
type: 'boolean',
},
disableMissingParamChecks: {
type: 'boolean',
},
enableFixer: {
type: 'boolean',
},
Expand Down
126 changes: 126 additions & 0 deletions test/rules/assertions/checkParamNames.js
Expand Up @@ -1183,6 +1183,89 @@ export default {
parser: typescriptEslintParser
},
},
{
code: `
/**
* @param foo
* @param foo.bar
*/
function quux (bar, foo) {
}
`,
options: [
{
disableMissingParamChecks: false,
},
],
errors: [
{
line: 3,
message: 'Expected @param names to be "bar, foo". Got "foo".',
},
],
},
{
code: `
/**
* @param foo
*/
function quux (bar, baz) {
}
`,
options: [
{
disableMissingParamChecks: true,
},
],
errors: [
{
line: 3,
message: 'Expected @param names to be "bar, baz". Got "foo".',
},
],
},
{
code: `
/**
* @param bar
* @param foo
*/
function quux (foo, bar) {
}
`,
options: [
{
disableMissingParamChecks: true,
},
],
errors: [
{
line: 3,
message: 'Expected @param names to be "foo, bar". Got "bar, foo".',
},
],
},
{
code: `
/**
* @param foo
* @param bar
*/
function quux (foo) {
}
`,
options: [
{
disableMissingParamChecks: true,
},
brettz9 marked this conversation as resolved.
Show resolved Hide resolved
],
errors: [
{
line: 4,
message: '@param "bar" does not match an existing function parameter.',
},
],
},
],
valid: [
{
Expand Down Expand Up @@ -1835,5 +1918,48 @@ export default {
parser: typescriptEslintParser
},
},
{
code: `
/**
* Documentation
*/
function quux (foo, bar) {
}
`,
options: [
{
disableMissingParamChecks: true,
},
],
},
{
code: `
/**
* @param bar
* @param bar.baz
*/
function quux (foo, bar) {
}
`,
options: [
{
disableMissingParamChecks: true,
},
],
},
{
code: `
/**
* @param foo
*/
function quux (foo, bar) {
}
`,
options: [
{
disableMissingParamChecks: true,
brettz9 marked this conversation as resolved.
Show resolved Hide resolved
},
],
},
],
};