Repository: lo1tuma/eslint-plugin-mocha (ts)

Issue:
`no-empty-description` incorrectly flags non-empty descriptions.
The following seem like reasonable test descriptions, but they get flagged by `no-empty-description`:

```js
describe('eslint-plugin-mocha', function() {
  const description = 'description';
  it(description, function() {});

  ['test1', 'test2'].forEach(testname => {
    it(testname, function() {});
  });

  const removePrefix = 'testcase.prefix';
  it(removePrefix.replace('.prefix'), function() {});
});
```

```
   3:3  error  Unexpected empty test description  mocha/no-empty-description
   6:5  error  Unexpected empty test description  mocha/no-empty-description
  10:3  error  Unexpected empty test description  mocha/no-empty-description
```

Was this intended with #304?

Pull request description:
Fix no-empty-description rule to not report on dynamic values
Fixes #313 

Patch:
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


Test patch:
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 } ]
         }
     ]