diff --git a/src/rules/__tests__/valid-title.test.ts b/src/rules/__tests__/valid-title.test.ts index abbf81ee7..dfa9b5b95 100644 --- a/src/rules/__tests__/valid-title.test.ts +++ b/src/rules/__tests__/valid-title.test.ts @@ -12,6 +12,7 @@ const ruleTester = new TSESLint.RuleTester({ ruleTester.run('title-must-be-string', rule, { valid: [ 'it("is a string", () => {});', + 'it("is" + " a " + " string", () => {});', 'test("is a string", () => {});', 'xtest("is a string", () => {});', 'xtest(`${myFunc} is a string`, () => {});', diff --git a/src/rules/valid-title.ts b/src/rules/valid-title.ts index c0cd8ab3b..6ed2f7b56 100644 --- a/src/rules/valid-title.ts +++ b/src/rules/valid-title.ts @@ -16,6 +16,20 @@ import { const trimFXprefix = (word: string) => ['f', 'x'].includes(word.charAt(0)) ? word.substr(1) : word; +const doesBinaryExpressionContainStringNode = ( + binaryExp: TSESTree.BinaryExpression, +): boolean => { + if (isStringNode(binaryExp.right)) { + return true; + } + + if (binaryExp.left.type === AST_NODE_TYPES.BinaryExpression) { + return doesBinaryExpressionContainStringNode(binaryExp.left); + } + + return isStringNode(binaryExp.left); +}; + export default createRule({ name: __filename, meta: { @@ -56,6 +70,13 @@ export default createRule({ const [argument] = node.arguments; if (!isStringNode(argument)) { + if ( + argument.type === AST_NODE_TYPES.BinaryExpression && + doesBinaryExpressionContainStringNode(argument) + ) { + return; + } + if ( argument.type !== AST_NODE_TYPES.TemplateLiteral && !(ignoreTypeOfDescribeName && isDescribe(node))