From bffa6bf9bd4ed3bc18792a7af1b8badda154f919 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Wed, 1 Feb 2023 14:30:58 -0700 Subject: [PATCH] docs(`no-restricted-syntax`): demo erring without returns on contexts with non-void return-type type annotations; closes #517 --- README.md | 56 ++++++ test/rules/assertions/noRestrictedSyntax.js | 188 ++++++++++++++++++++ 2 files changed, 244 insertions(+) diff --git a/README.md b/README.md index d8e32c438..5cc9d2091 100644 --- a/README.md +++ b/README.md @@ -9692,6 +9692,36 @@ const MyComponent = ({ children }) => { */ // "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:has(JsdocTag[tag=type][parsedType.type!=JsdocTypeStringValue][parsedType.type!=JsdocTypeNumber][parsedType.type!=JsdocTypeName])","context":"any","message":"@type should be limited to numeric or string literals and names"},{"comment":"JsdocBlock:has(JsdocTag[tag=type][parsedType.type=JsdocTypeName]:not(*[parsedType.value=/^(true|false|null|undefined|boolean|number|string)$/]))","context":"any","message":"@type names should only be recognized primitive types or literals"}]}] // Message: @type names should only be recognized primitive types or literals + +/** + * + */ +function test(): string { } +// "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))","context":"FunctionDeclaration[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]","message":"Functions with non-void return types must have a @returns tag"}]}] +// Message: Functions with non-void return types must have a @returns tag + +/** + * + */ +let test = (): string => { }; +// "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))","context":"ArrowFunctionExpression[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]","message":"Functions with non-void return types must have a @returns tag"}]}] +// Message: Functions with non-void return types must have a @returns tag + +/** + * @returns + */ +let test: () => string; +// "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:not(*:has(JsdocTag[tag=/returns/]:has(JsdocDescriptionLine)))","context":"VariableDeclaration:has(*[typeAnnotation.typeAnnotation.type=/TSFunctionType/][typeAnnotation.typeAnnotation.returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/])","message":"FunctionType's with non-void return types must have a @returns tag with a description"}]}] +// Message: FunctionType's with non-void return types must have a @returns tag with a description + +/** + * + */ +class Test { + abstract Test(): string; +} +// "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))","context":"TSEmptyBodyFunctionExpression[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]","message":"methods with non-void return types must have a @returns tag"}]}] +// Message: methods with non-void return types must have a @returns tag ```` The following patterns are not considered problems: @@ -9772,6 +9802,32 @@ function foo(): string; * @type {boolean} */ // "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:has(JsdocTag[tag=type][parsedType.type!=JsdocTypeStringValue][parsedType.type!=JsdocTypeNumber][parsedType.type!=JsdocTypeName])","context":"any","message":"@type should be limited to numeric or string literals and names"},{"comment":"JsdocBlock:has(JsdocTag[tag=type][parsedType.type=JsdocTypeName]:not(*[parsedType.value=/^(true|false|null|undefined|boolean|number|string)$/]))","context":"any","message":"@type names should only be recognized primitive types or literals"}]}] + +/** + * + */ +function test(): void { } +// "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))","context":"FunctionDeclaration[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]","message":"Functions with return types must have a @returns tag"}]}] + +/** + * + */ +let test = (): undefined => { }; +// "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))","context":"ArrowFunctionExpression[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]","message":"Functions with non-void return types must have a @returns tag"}]}] + +/** + * @returns A description + */ +let test: () => string; +// "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:not(*:has(JsdocTag[tag=/returns/]:has(JsdocDescriptionLine)))","context":"VariableDeclaration:has(*[typeAnnotation.typeAnnotation.type=/TSFunctionType/])","message":"FunctionType's with non-void return types must have a @returns tag"}]}] + +/** + * + */ +class Test { + abstract Test(): void; +} +// "jsdoc/no-restricted-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))","context":"TSEmptyBodyFunctionExpression[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]","message":"methods with non-void return types must have a @returns tag"}]}] ```` diff --git a/test/rules/assertions/noRestrictedSyntax.js b/test/rules/assertions/noRestrictedSyntax.js index 14ad0f873..70e8c45f4 100644 --- a/test/rules/assertions/noRestrictedSyntax.js +++ b/test/rules/assertions/noRestrictedSyntax.js @@ -523,6 +523,112 @@ export default { }, ], }, + { + code: ` + /** + * + */ + function test(): string { } + `, + errors: [ + { + line: 2, + message: 'Functions with non-void return types must have a @returns tag', + }, + ], + options: [ + { + contexts: [ + { + comment: 'JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))', + context: 'FunctionDeclaration[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]', + message: 'Functions with non-void return types must have a @returns tag', + }, + ], + }, + ], + parser: require.resolve('@typescript-eslint/parser'), + }, + { + code: ` + /** + * + */ + let test = (): string => { }; + `, + errors: [ + { + line: 2, + message: 'Functions with non-void return types must have a @returns tag', + }, + ], + options: [ + { + contexts: [ + { + comment: 'JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))', + context: 'ArrowFunctionExpression[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]', + message: 'Functions with non-void return types must have a @returns tag', + }, + ], + }, + ], + parser: require.resolve('@typescript-eslint/parser'), + }, + { + code: ` + /** + * @returns + */ + let test: () => string; + `, + errors: [ + { + line: 2, + message: 'FunctionType\'s with non-void return types must have a @returns tag with a description', + }, + ], + options: [ + { + contexts: [ + { + comment: 'JsdocBlock:not(*:has(JsdocTag[tag=/returns/]:has(JsdocDescriptionLine)))', + context: 'VariableDeclaration:has(*[typeAnnotation.typeAnnotation.type=/TSFunctionType/][typeAnnotation.typeAnnotation.returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/])', + message: 'FunctionType\'s with non-void return types must have a @returns tag with a description', + }, + ], + }, + ], + parser: require.resolve('@typescript-eslint/parser'), + }, + { + code: ` + /** + * + */ + class Test { + abstract Test(): string; + } + `, + errors: [ + { + line: 2, + message: 'methods with non-void return types must have a @returns tag', + }, + ], + options: [ + { + contexts: [ + { + comment: 'JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))', + context: 'TSEmptyBodyFunctionExpression[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]', + message: 'methods with non-void return types must have a @returns tag', + }, + ], + }, + ], + parser: require.resolve('@typescript-eslint/parser'), + }, ], valid: [ { @@ -779,5 +885,87 @@ export default { }, ], }, + { + code: ` + /** + * + */ + function test(): void { } + `, + options: [ + { + contexts: [ + { + comment: 'JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))', + context: 'FunctionDeclaration[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]', + message: 'Functions with return types must have a @returns tag', + }, + ], + }, + ], + parser: require.resolve('@typescript-eslint/parser'), + }, + { + code: ` + /** + * + */ + let test = (): undefined => { }; + `, + options: [ + { + contexts: [ + { + comment: 'JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))', + context: 'ArrowFunctionExpression[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]', + message: 'Functions with non-void return types must have a @returns tag', + }, + ], + }, + ], + parser: require.resolve('@typescript-eslint/parser'), + }, + { + code: ` + /** + * @returns A description + */ + let test: () => string; + `, + options: [ + { + contexts: [ + { + comment: 'JsdocBlock:not(*:has(JsdocTag[tag=/returns/]:has(JsdocDescriptionLine)))', + context: 'VariableDeclaration:has(*[typeAnnotation.typeAnnotation.type=/TSFunctionType/])', + message: 'FunctionType\'s with non-void return types must have a @returns tag', + }, + ], + }, + ], + parser: require.resolve('@typescript-eslint/parser'), + }, + { + code: ` + /** + * + */ + class Test { + abstract Test(): void; + } + `, + options: [ + { + contexts: [ + { + comment: 'JsdocBlock:not(*:has(JsdocTag[tag=/returns/]))', + context: 'TSEmptyBodyFunctionExpression[returnType.typeAnnotation.type!=/TSVoidKeyword|TSUndefinedKeyword/]', + message: 'methods with non-void return types must have a @returns tag', + }, + ], + }, + ], + parser: require.resolve('@typescript-eslint/parser'), + }, ], };