Skip to content

Commit 9458735

Browse files
authored
docs: fix malformed eslint config comments in rule examples (#18078)
* fix: fix malformed `eslint` config comments in rule examples * extend rule example validation * fix test for runtime-specific error message
1 parent 07a1ada commit 9458735

File tree

4 files changed

+46
-21
lines changed

4 files changed

+46
-21
lines changed

docs/src/rules/lines-around-comment.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ class C {
233233
switch (foo) {
234234
/* what a great and wonderful day */
235235

236-
case 1:
236+
case 1:
237237
bar();
238238
break;
239239
}
@@ -317,7 +317,7 @@ class C {
317317
}
318318

319319
switch (foo) {
320-
case 1:
320+
case 1:
321321
bar();
322322
break;
323323

@@ -663,7 +663,7 @@ Examples of **correct** code for the `ignorePattern` option:
663663
/*eslint lines-around-comment: ["error"]*/
664664

665665
foo();
666-
/* eslint mentioned in this comment */
666+
/* jshint mentioned in this comment */
667667
bar();
668668

669669
/*eslint lines-around-comment: ["error", { "ignorePattern": "pragma" }] */
@@ -712,7 +712,7 @@ Examples of **incorrect** code for the `{ "applyDefaultIgnorePatterns": false }`
712712
/*eslint lines-around-comment: ["error", { "applyDefaultIgnorePatterns": false }] */
713713

714714
foo();
715-
/* eslint mentioned in comment */
715+
/* jshint mentioned in comment */
716716

717717
```
718718

tests/fixtures/bad-examples.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: no-restricted-syntax
33
---
44

5-
This file contains rule example code with syntax errors.
5+
This file contains rule example code with syntax errors and other problems.
66

77
<!-- markdownlint-capture -->
88
<!-- markdownlint-disable MD040 -->
@@ -32,3 +32,13 @@ const foo = "baz";
3232
```
3333

3434
:::
35+
36+
:::correct
37+
38+
```js
39+
/* eslint no-restricted-syntax: "error" */
40+
41+
/* eslint doesn't allow this comment */
42+
```
43+
44+
:::

tests/tools/check-rule-examples.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,18 @@ describe("check-rule-examples", () => {
5555
assert.strictEqual(code, 1);
5656
assert.strictEqual(stdout, "");
5757

58-
// Remove OS-dependent path except base name.
58+
/* eslint-disable no-control-regex -- escaping control characters */
59+
5960
const normalizedStderr =
60-
// eslint-disable-next-line no-control-regex -- escaping control character
61-
stderr.replace(/(?<=\x1B\[4m).*(?=bad-examples\.md)/u, "");
61+
stderr
62+
63+
// Remove OS-dependent path except base name.
64+
.replace(/(?<=\x1B\[4m).*(?=bad-examples\.md)/u, "")
65+
66+
// Remove runtime-specific error message part (different in Node.js 18, 20 and 21).
67+
.replace(/(?<=' doesn't allow this comment'):.*(?=\x1B\[0m)/u, "");
68+
69+
/* eslint-enable no-control-regex -- re-enable rule */
6270

6371
const expectedStderr =
6472
"\x1B[0m\x1B[0m\n" +
@@ -68,8 +76,9 @@ describe("check-rule-examples", () => {
6876
"\x1B[0m \x1B[2m20:5\x1B[22m \x1B[31merror\x1B[39m Nonstandard language tag 'ts': use one of 'javascript', 'js' or 'jsx'\x1B[0m\n" +
6977
"\x1B[0m \x1B[2m23:7\x1B[22m \x1B[31merror\x1B[39m Syntax error: Identifier 'foo' has already been declared\x1B[0m\n" +
7078
"\x1B[0m \x1B[2m31:1\x1B[22m \x1B[31merror\x1B[39m Example code should contain a configuration comment like /* eslint no-restricted-syntax: \"error\" */\x1B[0m\n" +
79+
"\x1B[0m \x1B[2m41:1\x1B[22m \x1B[31merror\x1B[39m Failed to parse JSON from ' doesn't allow this comment'\x1B[0m\n" +
7180
"\x1B[0m\x1B[0m\n" +
72-
"\x1B[0m\x1B[31m\x1B[1m✖ 5 problems (5 errors, 0 warnings)\x1B[22m\x1B[39m\x1B[0m\n" +
81+
"\x1B[0m\x1B[31m\x1B[1m✖ 6 problems (6 errors, 0 warnings)\x1B[22m\x1B[39m\x1B[0m\n" +
7382
"\x1B[0m\x1B[31m\x1B[1m\x1B[22m\x1B[39m\x1B[0m\n";
7483

7584
assert.strictEqual(normalizedStderr, expectedStderr);

tools/check-rule-examples.js

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const commentParser = new ConfigCommentParser();
3838
*/
3939
function tryParseForPlayground(code, parserOptions) {
4040
try {
41-
const ast = parse(code, { ecmaVersion: "latest", ...parserOptions, comment: true });
41+
const ast = parse(code, { ecmaVersion: "latest", ...parserOptions, comment: true, loc: true });
4242

4343
return { ast };
4444
} catch (error) {
@@ -81,20 +81,26 @@ async function findProblems(filename) {
8181

8282
const { ast, error } = tryParseForPlayground(code, parserOptions);
8383

84-
if (ast && !isRuleRemoved) {
85-
const hasRuleConfigComment = ast.comments.some(
86-
comment => {
87-
if (comment.type !== "Block" || !/^\s*eslint(?!\S)/u.test(comment.value)) {
88-
return false;
89-
}
90-
const { directiveValue } = commentParser.parseDirective(comment);
91-
const parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc);
84+
if (ast) {
85+
let hasRuleConfigComment = false;
9286

93-
return parseResult.success && Object.hasOwn(parseResult.config, title);
87+
for (const comment of ast.comments) {
88+
if (comment.type !== "Block" || !/^\s*eslint(?!\S)/u.test(comment.value)) {
89+
continue;
9490
}
95-
);
91+
const { directiveValue } = commentParser.parseDirective(comment);
92+
const parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc);
93+
const parseError = parseResult.error;
94+
95+
if (parseError) {
96+
parseError.line += codeBlockToken.map[0] + 1;
97+
problems.push(parseError);
98+
} else if (Object.hasOwn(parseResult.config, title)) {
99+
hasRuleConfigComment = true;
100+
}
101+
}
96102

97-
if (!hasRuleConfigComment) {
103+
if (!isRuleRemoved && !hasRuleConfigComment) {
98104
const message = `Example code should contain a configuration comment like /* eslint ${title}: "error" */`;
99105

100106
problems.push({

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy