Skip to content

Commit 37081d2

Browse files
committed
fix(require-description-complete-sentence): report proper line numbers (fixes #160)
1 parent bee3779 commit 37081d2

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

src/rules/requireDescriptionCompleteSentence.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ const capitalize = (str) => {
5151
return str.charAt(0).toUpperCase() + str.slice(1);
5252
};
5353

54-
const validateDescription = (description, report, jsdocNode, sourceCode, tag) => {
54+
const validateDescription = (description, reportOrig, jsdocNode, sourceCode, tag) => {
5555
if (!description) {
5656
return false;
5757
}
5858

5959
const paragraphs = extractParagraphs(description);
6060

61-
return paragraphs.some((paragraph) => {
61+
return paragraphs.some((paragraph, parIdx) => {
6262
const sentences = extractSentences(paragraph);
6363

6464
const fix = (fixer) => {
@@ -75,8 +75,8 @@ const validateDescription = (description, report, jsdocNode, sourceCode, tag) =>
7575
})) {
7676
const beginning = sentence.split('\n')[0];
7777

78-
if (tag) {
79-
const reg = new RegExp(`(@${_.escapeRegExp(tag)}.*)${_.escapeRegExp(beginning)}`);
78+
if (tag.tag) {
79+
const reg = new RegExp(`(@${_.escapeRegExp(tag.tag)}.*)${_.escapeRegExp(beginning)}`);
8080

8181
text = text.replace(reg, ($0, $1) => {
8282
return $1 + capitalize(beginning);
@@ -89,20 +89,28 @@ const validateDescription = (description, report, jsdocNode, sourceCode, tag) =>
8989
return fixer.replaceText(jsdocNode, text);
9090
};
9191

92+
const report = (msg, fixer, tagObj) => {
93+
tagObj.line += parIdx * 2;
94+
95+
// Avoid errors if old column doesn't exist here
96+
tagObj.column = 0;
97+
reportOrig(msg, fixer, tagObj);
98+
};
99+
92100
if (sentences.some((sentence) => {
93101
return !(/^\s*$/).test(sentence) && !isCapitalized(sentence);
94102
})) {
95-
report('Sentence should start with an uppercase character.', fix);
103+
report('Sentence should start with an uppercase character.', fix, tag);
96104
}
97105

98106
if (!/[.!?]$/.test(paragraph)) {
99-
report('Sentence must end with a period.', fix);
107+
report('Sentence must end with a period.', fix, tag);
100108

101109
return true;
102110
}
103111

104112
if (!isNewLinePrecededByAPeriod(paragraph)) {
105-
report('A line of text is started with an uppercase character, but preceding line does not end the sentence.');
113+
report('A line of text is started with an uppercase character, but preceding line does not end the sentence.', null, tag);
106114

107115
return true;
108116
}
@@ -119,14 +127,16 @@ export default iterateJsdoc(({
119127
utils
120128
}) => {
121129
if (!jsdoc.tags ||
122-
validateDescription(jsdoc.description, report, jsdocNode, sourceCode)
130+
validateDescription(jsdoc.description, report, jsdocNode, sourceCode, {
131+
line: jsdoc.line + 1
132+
})
123133
) {
124134
return;
125135
}
126136

127-
utils.forEachPreferredTag('description', (matchingJsdocTag, targetTagName) => {
137+
utils.forEachPreferredTag('description', (matchingJsdocTag) => {
128138
const description = `${matchingJsdocTag.name} ${matchingJsdocTag.description}`.trim();
129-
validateDescription(description, report, jsdocNode, sourceCode, targetTagName);
139+
validateDescription(description, report, jsdocNode, sourceCode, matchingJsdocTag);
130140
});
131141

132142
const tags = jsdoc.tags.filter((tag) => {
@@ -136,7 +146,7 @@ export default iterateJsdoc(({
136146
tags.some((tag) => {
137147
const description = _.trimStart(tag.description, '- ');
138148

139-
return validateDescription(description, report, jsdocNode, sourceCode, tag.tag);
149+
return validateDescription(description, report, jsdocNode, sourceCode, tag);
140150
});
141151
}, {
142152
iterateAllJsdocs: true,

test/rules/assertions/requireDescriptionCompleteSentence.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default {
1111
`,
1212
errors: [
1313
{
14+
line: 3,
1415
message: 'Sentence should start with an uppercase character.'
1516
}
1617
],
@@ -57,6 +58,7 @@ export default {
5758
`,
5859
errors: [
5960
{
61+
line: 3,
6062
message: 'Sentence should start with an uppercase character.'
6163
}
6264
],
@@ -80,6 +82,7 @@ export default {
8082
`,
8183
errors: [
8284
{
85+
line: 3,
8386
message: 'Sentence must end with a period.'
8487
}
8588
],
@@ -128,6 +131,7 @@ export default {
128131
`,
129132
errors: [
130133
{
134+
line: 5,
131135
message: 'Sentence should start with an uppercase character.'
132136
}
133137
],
@@ -153,6 +157,7 @@ export default {
153157
`,
154158
errors: [
155159
{
160+
line: 3,
156161
message: 'Sentence should start with an uppercase character.'
157162
}
158163
],
@@ -176,6 +181,7 @@ export default {
176181
`,
177182
errors: [
178183
{
184+
line: 3,
179185
message: 'Sentence must end with a period.'
180186
}
181187
],
@@ -200,6 +206,7 @@ export default {
200206
`,
201207
errors: [
202208
{
209+
line: 3,
203210
message: 'A line of text is started with an uppercase character, but preceding line does not end the sentence.'
204211
}
205212
]
@@ -217,6 +224,7 @@ export default {
217224
`,
218225
errors: [
219226
{
227+
line: 5,
220228
message: 'Sentence should start with an uppercase character.'
221229
}
222230
],
@@ -244,9 +252,11 @@ export default {
244252
`,
245253
errors: [
246254
{
255+
line: 5,
247256
message: 'Sentence should start with an uppercase character.'
248257
},
249258
{
259+
line: 5,
250260
message: 'Sentence must end with a period.'
251261
}
252262
],
@@ -272,9 +282,11 @@ export default {
272282
`,
273283
errors: [
274284
{
285+
line: 3,
275286
message: 'Sentence should start with an uppercase character.'
276287
},
277288
{
289+
line: 3,
278290
message: 'Sentence must end with a period.'
279291
}
280292
],
@@ -300,9 +312,11 @@ export default {
300312
`,
301313
errors: [
302314
{
315+
line: 5,
303316
message: 'Sentence should start with an uppercase character.'
304317
},
305318
{
319+
line: 5,
306320
message: 'Sentence must end with a period.'
307321
}
308322
],
@@ -330,6 +344,7 @@ export default {
330344
`,
331345
errors: [
332346
{
347+
line: 5,
333348
message: 'Sentence should start with an uppercase character.'
334349
}
335350
],
@@ -360,6 +375,7 @@ export default {
360375
`,
361376
errors: [
362377
{
378+
line: 3,
363379
message: 'Sentence should start with an uppercase character.'
364380
}
365381
],
@@ -388,6 +404,7 @@ export default {
388404
`,
389405
errors: [
390406
{
407+
line: 3,
391408
message: 'Sentence must end with a period.'
392409
}
393410
],
@@ -411,6 +428,7 @@ export default {
411428
`,
412429
errors: [
413430
{
431+
line: 3,
414432
message: 'Sentence must end with a period.'
415433
}
416434
],
@@ -434,9 +452,11 @@ export default {
434452
`,
435453
errors: [
436454
{
455+
line: 3,
437456
message: 'Sentence should start with an uppercase character.'
438457
},
439458
{
459+
line: 3,
440460
message: 'Sentence must end with a period.'
441461
}
442462
],
@@ -462,9 +482,11 @@ export default {
462482
`,
463483
errors: [
464484
{
485+
line: 5,
465486
message: 'Sentence should start with an uppercase character.'
466487
},
467488
{
489+
line: 5,
468490
message: 'Sentence must end with a period.'
469491
}
470492
],

0 commit comments

Comments
 (0)