Skip to content

Commit

Permalink
fix(check-examples): allow multiline captions; fixes #655
Browse files Browse the repository at this point in the history
  • Loading branch information
brettz9 committed Nov 14, 2020
1 parent bcd465f commit 8963394
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 9 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,24 @@ function quux () {
const obj = {};
// Options: [{"checkProperties":true}]
// Message: @property error (quotes): Strings must use doublequote.

/**
* Test function.
*
* @example <caption>functionName (paramOne: string, paramTwo?: any,
* paramThree?: any): boolean</caption> test()
*
* @param {string} paramOne Parameter description.
* @param {any} [paramTwo] Parameter description.
* @param {any} [paramThree] Parameter description.
* @returns {boolean} Return description.
*/
const functionName = function (paramOne, paramTwo,
paramThree) {
return false;
};
// Options: [{"baseConfig":{"parserOptions":{"ecmaVersion":2015,"sourceType":"module"},"rules":{"semi":["error","always"]}},"captionRequired":true,"checkEslintrc":false}]
// Message: @example error (semi): Missing semicolon.
````

The following patterns are not considered problems:
Expand Down Expand Up @@ -1571,6 +1589,23 @@ function quux () {
*/
const obj = {};
// Options: [{"checkProperties":false,"matchingFileNameProperties":"dummy.js"}]

/**
* Test function.
*
* @example <caption>functionName (paramOne: string, paramTwo?: any,
* paramThree?: any): boolean</caption> test();
*
* @param {string} paramOne Parameter description.
* @param {any} [paramTwo] Parameter description.
* @param {any} [paramThree] Parameter description.
* @returns {boolean} Return description.
*/
const functionName = function (paramOne, paramTwo,
paramThree) {
return false;
};
// Options: [{"baseConfig":{"parserOptions":{"ecmaVersion":2015,"sourceType":"module"},"rules":{"semi":["error","always"]}},"captionRequired":true,"checkEslintrc":false}]
````


Expand Down
28 changes: 19 additions & 9 deletions src/rules/checkExamples.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const preTagSpaceLength = 1;
// If a space is present, we should ignore it
const firstLinePrefixLength = preTagSpaceLength;

const hasCaptionRegex = /^\s*<caption>(.*?)<\/caption>/u;
const hasCaptionRegex = /^\s*<caption>([\s\S]*?)<\/caption>/u;

const escapeStringRegexp = (str) => {
return str.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
Expand Down Expand Up @@ -82,6 +82,16 @@ const defaultExpressionRules = {
strict: 'off',
};

const getLinesCols = (text) => {
const matchLines = countChars(text, '\n');

const colDelta = matchLines ?
text.slice(text.lastIndexOf('\n') + 1).length :
text.length;

return [matchLines, colDelta];
};

export default iterateJsdoc(({
report,
utils,
Expand Down Expand Up @@ -133,12 +143,14 @@ export default iterateJsdoc(({
const checkSource = ({
filename, defaultFileName,
rules = expressionRules,
lines = 0,
cols = 0,
skipInit, source, targetTagName, sources = [], tag = {line: 0},
}) => {
if (!skipInit) {
sources.push({
nonJSPrefacingCols: 0,
nonJSPrefacingLines: 0,
nonJSPrefacingCols: cols,
nonJSPrefacingLines: lines,
string: source,
});
}
Expand Down Expand Up @@ -301,8 +313,8 @@ export default iterateJsdoc(({
report('Caption is expected for examples.', null, tag);
}

// If we allow newlines in hasCaptionRegex, we should add to line count
source = source.replace(hasCaptionRegex, '');
const [lines, cols] = match ? getLinesCols(match[0]) : [0, 0];

if (exampleCodeRegex && !exampleCodeRegex.test(source) ||
rejectExampleCodeRegex && rejectExampleCodeRegex.test(source)
Expand All @@ -327,11 +339,7 @@ export default iterateJsdoc(({
// Count anything preceding user regex match (can affect line numbering)
const preMatch = source.slice(startingIndex, index);

const preMatchLines = countChars(preMatch, '\n');

const colDelta = preMatchLines ?
preMatch.slice(preMatch.lastIndexOf('\n') + 1).length :
preMatch.length;
const [preMatchLines, colDelta] = getLinesCols(preMatch);

let nonJSPreface;
let nonJSPrefaceLineCount;
Expand Down Expand Up @@ -371,6 +379,8 @@ export default iterateJsdoc(({
}

checkSource({
cols,
lines,
rules: mdRules,
skipInit,
source,
Expand Down
70 changes: 70 additions & 0 deletions test/rules/assertions/checkExamples.js
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,44 @@ export default {
},
],
},
{
code: `
/**
* Test function.
*
* @example <caption>functionName (paramOne: string, paramTwo?: any,
* paramThree?: any): boolean</caption> test()
*
* @param {string} paramOne Parameter description.
* @param {any} [paramTwo] Parameter description.
* @param {any} [paramThree] Parameter description.
* @returns {boolean} Return description.
*/
const functionName = function (paramOne, paramTwo,
paramThree) {
return false;
};
`,
errors: [
{
line: 6,
message: '@example error (semi): Missing semicolon.',
},
],
options: [{
baseConfig: {
parserOptions: {
ecmaVersion: 2_015,
sourceType: 'module',
},
rules: {
semi: ['error', 'always'],
},
},
captionRequired: true,
checkEslintrc: false,
}],
},
],
valid: [
{
Expand Down Expand Up @@ -1166,5 +1204,37 @@ export default {
},
],
},
{
code: `
/**
* Test function.
*
* @example <caption>functionName (paramOne: string, paramTwo?: any,
* paramThree?: any): boolean</caption> test();
*
* @param {string} paramOne Parameter description.
* @param {any} [paramTwo] Parameter description.
* @param {any} [paramThree] Parameter description.
* @returns {boolean} Return description.
*/
const functionName = function (paramOne, paramTwo,
paramThree) {
return false;
};
`,
options: [{
baseConfig: {
parserOptions: {
ecmaVersion: 2_015,
sourceType: 'module',
},
rules: {
semi: ['error', 'always'],
},
},
captionRequired: true,
checkEslintrc: false,
}],
},
],
};

0 comments on commit 8963394

Please sign in to comment.