Repository: francoismassart/eslint-plugin-tailwindcss
Pull request #138 (2022-04-22 11:11:08)

Fix `parseNodeRecursive`: Correctly recurse into TemplateLiteral expressions
# Fix `parseNodeRecursive`: Correctly recurse into TemplateLiteral expressions

## Description

In the fuction `parseNodeRecursive` of `lib/util/ast.js`, the case for TemplateListeral nodes would always recurse over `exp.right` for all expressions in the template. However, these expressions are not necessarily binary expressions. Removing the `.right` will make sure that e.g. ConditionalExpressions are also checked.

## Type of change

Please delete options that are not relevant.

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

I've added a test to `tests/lib/rules/no-custom-classname.js` and `tests/lib/rules/no-contradicting-classname.js`.

**Test Configuration**:
* OS + version: Arch Linux (last upgraded today)
* NPM version: 8.5.5
* Node version: 16.14.2

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [ ] ~~I have commented my code, particularly in hard-to-understand areas~~
- [ ] ~~I have made corresponding changes to the documentation~~
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] ~~Any dependent changes have been merged and published in downstream modules~~
- [x] I have checked my code and corrected any misspellings



Patch:
diff --git a/lib/util/ast.js b/lib/util/ast.js
index 49c4a32..225f2ba 100644
--- a/lib/util/ast.js
+++ b/lib/util/ast.js
@@ -189,7 +189,7 @@ function parseNodeRecursive(node, arg, cb, skipConditional = false, isolate = fa
     switch (arg.type) {
       case 'TemplateLiteral':
         arg.expressions.forEach((exp) => {
-          parseNodeRecursive(node, exp.right, cb, skipConditional, forceIsolation);
+          parseNodeRecursive(node, exp, cb, skipConditional, forceIsolation);
         });
         arg.quasis.forEach((quasis) => {
           parseNodeRecursive(node, quasis, cb, skipConditional, isolate);


Test patch:
diff --git a/tests/lib/rules/no-contradicting-classname.js b/tests/lib/rules/no-contradicting-classname.js
index 1d47921..b019d56 100644
--- a/tests/lib/rules/no-contradicting-classname.js
+++ b/tests/lib/rules/no-contradicting-classname.js
@@ -403,6 +403,11 @@ ruleTester.run("no-contradicting-classname", rule, {
       options: [{ tags: ["myTag"] }],
       errors: generateErrors("px-2 px-0"),
     },
+    {
+      code: `myTag\`\${enabled ? "px-2 px-0" : ""}\``,
+      options: [{ tags: ["myTag"] }],
+      errors: generateErrors("px-2 px-0"),
+    },
     {
       code: `
       <div class="shrink shrink-0 shrink-[inherit] shrink-[initial] shrink-[unset] shrink-[var(--some)] shrink-[0.5] shrink-[5]">
diff --git a/tests/lib/rules/no-custom-classname.js b/tests/lib/rules/no-custom-classname.js
index 1095367..edf0c63 100644
--- a/tests/lib/rules/no-custom-classname.js
+++ b/tests/lib/rules/no-custom-classname.js
@@ -985,6 +985,11 @@ ruleTester.run("no-custom-classname", rule, {
       options: [{ tags: ["myTag"] }],
       errors: generateErrors("custom-2 custom-3 custom-1"),
     },
+    {
+      code: `myTag\`custom-1 \${isDisabled ? "custom-2" : "m-4"}\``,
+      options: [{ tags: ["myTag"] }],
+      errors: generateErrors("custom-2 custom-1"),
+    },
     {
       code: `
       <div class="bg-red-600 p-10">