Skip to content

Commit 1840a53

Browse files
authored
Fix: Improve detection of static description strings and ignore non-static descriptions in require-meta-docs-description rule (#113)
Two changes: * Drastically improves detection of the `description` string value when it can be determined statically, including handling when the description is stored in a constant or created through string concatenation * If we cannot determine the string value of the `description` statically, then bail out and report no violations, so that users can dynamically generate the description if they'd like to
1 parent 98e893b commit 1840a53

File tree

2 files changed

+68
-18
lines changed

2 files changed

+68
-18
lines changed

lib/rules/require-meta-docs-description.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

3+
const { getStaticValue } = require('eslint-utils');
34
const utils = require('../utils');
45

56
// ------------------------------------------------------------------------------
@@ -8,16 +9,6 @@ const utils = require('../utils');
89

910
const DEFAULT_PATTERN = new RegExp('^(enforce|require|disallow)');
1011

11-
/**
12-
* Whether or not the node is a string literal
13-
*
14-
* @param {object} node
15-
* @returns {boolean} whether or not the node is a string literal
16-
*/
17-
function isStringLiteral (node) {
18-
return node.type === 'Literal' && typeof node.value === 'string';
19-
}
20-
2112
module.exports = {
2213
meta: {
2314
docs: {
@@ -70,11 +61,20 @@ module.exports = {
7061

7162
if (!descriptionNode) {
7263
context.report({ node: docsNode ? docsNode : metaNode, messageId: 'missing' });
73-
} else if (!isStringLiteral(descriptionNode.value) || descriptionNode.value.value === '') {
64+
return;
65+
}
66+
67+
const staticValue = getStaticValue(descriptionNode.value, context.getScope());
68+
if (!staticValue) {
69+
// Ignore non-static values since we can't determine what they look like.
70+
return;
71+
}
72+
73+
if (typeof staticValue.value !== 'string' || staticValue.value === '') {
7474
context.report({ node: descriptionNode.value, messageId: 'wrongType' });
75-
} else if (descriptionNode.value.value !== descriptionNode.value.value.trim()) {
75+
} else if (staticValue.value !== staticValue.value.trim()) {
7676
context.report({ node: descriptionNode.value, messageId: 'extraWhitespace' });
77-
} else if (!pattern.test(descriptionNode.value.value)) {
77+
} else if (!pattern.test(staticValue.value)) {
7878
context.report({
7979
node: descriptionNode.value,
8080
message: '`meta.docs.description` must match the regexp {{pattern}}.',

tests/lib/rules/require-meta-docs-description.js

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,44 @@ ruleTester.run('require-meta-docs-description', rule, {
3232
create(context) {}
3333
};
3434
`,
35+
`
36+
module.exports = {
37+
meta: { docs: { description: generateRestOfDescription() } },
38+
create(context) {}
39+
};
40+
`,
41+
`
42+
module.exports = {
43+
meta: { docs: { description: \`enforce with template literal\` } },
44+
create(context) {}
45+
};
46+
`,
47+
`
48+
module.exports = {
49+
meta: { docs: { description: "enforce" + " " + "something" } },
50+
create(context) {}
51+
};
52+
`,
53+
`
54+
module.exports = {
55+
meta: { docs: { description: "enforce " + generateSomething() } },
56+
create(context) {}
57+
};
58+
`,
59+
`
60+
const DESCRIPTION = 'require foo';
61+
module.exports = {
62+
meta: { docs: { description: DESCRIPTION } },
63+
create(context) {}
64+
};
65+
`,
66+
`
67+
const DESCRIPTION = generateDescription();
68+
module.exports = {
69+
meta: { docs: { description: DESCRIPTION } },
70+
create(context) {}
71+
};
72+
`,
3573
{
3674
code:
3775
`
@@ -88,17 +126,18 @@ ruleTester.run('require-meta-docs-description', rule, {
88126
{
89127
code: `
90128
module.exports = {
91-
meta: { docs: { description: \`enforce with template literal\` } },
129+
meta: { docs: { description: '' } },
92130
create(context) {}
93131
};
94132
`,
95133
output: null,
96-
errors: [{ messageId: 'wrongType', type: 'TemplateLiteral' }],
134+
errors: [{ messageId: 'wrongType', type: 'Literal' }],
97135
},
98136
{
99137
code: `
138+
const DESCRIPTION = true;
100139
module.exports = {
101-
meta: { docs: { description: SOME_DESCRIPTION } },
140+
meta: { docs: { description: DESCRIPTION } },
102141
create(context) {}
103142
};
104143
`,
@@ -107,13 +146,14 @@ ruleTester.run('require-meta-docs-description', rule, {
107146
},
108147
{
109148
code: `
149+
const DESCRIPTION = 123;
110150
module.exports = {
111-
meta: { docs: { description: '' } },
151+
meta: { docs: { description: DESCRIPTION } },
112152
create(context) {}
113153
};
114154
`,
115155
output: null,
116-
errors: [{ messageId: 'wrongType', type: 'Literal' }],
156+
errors: [{ messageId: 'wrongType', type: 'Identifier' }],
117157
},
118158
{
119159
code: `
@@ -135,6 +175,16 @@ ruleTester.run('require-meta-docs-description', rule, {
135175
output: null,
136176
errors: [{ message: '`meta.docs.description` must match the regexp /^(enforce|require|disallow)/.', type: 'Literal' }],
137177
},
178+
{
179+
code: `
180+
module.exports = {
181+
meta: { docs: { description: 'foo' + ' ' + 'bar' } },
182+
create(context) {}
183+
};
184+
`,
185+
output: null,
186+
errors: [{ message: '`meta.docs.description` must match the regexp /^(enforce|require|disallow)/.', type: 'BinaryExpression' }],
187+
},
138188
{
139189
code: `
140190
module.exports = {

0 commit comments

Comments
 (0)