diff --git a/lib/rules/no-empty-description.js b/lib/rules/no-empty-description.js index d40932b..d02e880 100644 --- a/lib/rules/no-empty-description.js +++ b/lib/rules/no-empty-description.js @@ -14,6 +14,22 @@ function objectOptions(options = {}) { return { testNames, message }; } +function isTemplateString(node) { + return [ 'TaggedTemplateExpression', 'TemplateLiteral' ].includes(node && node.type); +} + +function isIdentifier(node) { + return node && node.type === 'Identifier'; +} + +function isStaticallyAnalyzableDescription(node, extractedText) { + if (extractedText === null) { + return !(isTemplateString(node) || isIdentifier(node)); + } + + return true; +} + module.exports = { meta: { type: 'suggestion', @@ -51,15 +67,11 @@ module.exports = { return node.callee && node.callee.name && testNames.includes(node.callee.name); } - function isTemplateString(node) { - return [ 'TaggedTemplateExpression', 'TemplateLiteral' ].includes(node && node.type); - } - - function checkDescription(mochaCallExpression) { + function isNonEmptyDescription(mochaCallExpression) { const description = mochaCallExpression.arguments[0]; - const text = getStringIfConstant(description); + const text = getStringIfConstant(description, context.getScope()); - if (isTemplateString(description) && text === null) { + if (!isStaticallyAnalyzableDescription(description, text)) { return true; } @@ -69,7 +81,7 @@ module.exports = { return { CallExpression(node) { if (isTest(node)) { - if (!checkDescription(node)) { + if (!isNonEmptyDescription(node)) { context.report({ node, message: message || ERROR_MESSAGE diff --git a/test/rules/no-empty-description.js b/test/rules/no-empty-description.js index 3faa7b1..a6d979a 100644 --- a/test/rules/no-empty-description.js +++ b/test/rules/no-empty-description.js @@ -29,6 +29,9 @@ ruleTester.run('no-empty-description', rules['no-empty-description'], { 'test.only("some text")', 'test("some text", function() { })', + 'var dynamicTitle = "foo"; it(dynamicTitle, function() {});', + 'it(dynamicTitle, function() {});', + 'notTest()', { @@ -46,6 +49,10 @@ ruleTester.run('no-empty-description', rules['no-empty-description'], { { options: [ { testNames: [ 'someFunction' ] } ], code: 'someFunction("this is a test", function () { });' + }, + { + parserOptions: { ecmaVersion: 2019 }, + code: 'const dynamicTitle = "foo"; it(dynamicTitle, function() {});' } ], @@ -76,6 +83,11 @@ ruleTester.run('no-empty-description', rules['no-empty-description'], { parserOptions: { ecmaVersion: 2019 }, code: 'it(` `, function () { });', errors: [ { message: defaultErrorMessage, ...firstLine } ] + }, + { + parserOptions: { ecmaVersion: 2019 }, + code: 'const foo = ""; it(foo);', + errors: [ { message: defaultErrorMessage, line: 1, column: 17 } ] } ]