Repository: i18next/i18next-parser
Pull request #900 (2023-08-31 13:00:40)

fix: suppress warning about non-literal child when key/defaults are specified
### Why am I submitting this PR

Suppress warnings about non-literal children when both the key and defaults are specified

### Does it fix an existing ticket?

Yes #899

### Checklist

- [x] only relevant code is changed (make a diff before you submit the PR)
- [x] tests are included and pass: `yarn test` (see [details here](https://github.com/i18next/i18next-parser/blob/master/docs/development.md#tests))
- [ ] documentation is changed or added



Patch:
diff --git a/src/lexers/jsx-lexer.js b/src/lexers/jsx-lexer.js
index da9a380..f70a801 100644
--- a/src/lexers/jsx-lexer.js
+++ b/src/lexers/jsx-lexer.js
@@ -81,6 +81,7 @@ export default class JsxLexer extends JavascriptLexer {
           'warning',
           `"${attributeName}" prop is not a string literal: ${attribute.initializer.expression.text}`
         )
+
         return undefined
       }
 
@@ -175,7 +176,12 @@ export default class JsxLexer extends JavascriptLexer {
   }
 
   nodeToString(node, sourceText) {
-    const children = this.parseChildren.call(this, node.children, sourceText)
+    const children = this.parseChildren.call(
+      this,
+      node,
+      node.children,
+      sourceText
+    )
 
     const elemsToString = (children) =>
       children
@@ -209,7 +215,7 @@ export default class JsxLexer extends JavascriptLexer {
       .replace(/(\n|\r)\s*/g, ' ')
   }
 
-  parseChildren(children = [], sourceText) {
+  parseChildren(node, children = [], sourceText) {
     return children
       .map((child) => {
         if (child.kind === ts.SyntaxKind.JsxText) {
@@ -231,7 +237,7 @@ export default class JsxLexer extends JavascriptLexer {
             type: 'tag',
             children: hasDynamicChildren
               ? []
-              : this.parseChildren(child.children, sourceText),
+              : this.parseChildren(child, child.children, sourceText),
             name,
             isBasic,
             selfClosing: child.kind === ts.SyntaxKind.JsxSelfClosingElement,
@@ -327,7 +333,17 @@ export default class JsxLexer extends JavascriptLexer {
             child.expression.end
           )
 
-          this.emit('warning', `Child is not literal: ${slicedExpression}`)
+          const tagNode = node.openingElement || node
+          const attrValues = tagNode.attributes.properties
+            .filter((attr) => [this.attr, 'defaults'].includes(attr.name?.text))
+            .map(
+              (attr) =>
+                attr.initializer.expression?.text ?? attr.initializer.text
+            )
+
+          if (attrValues.some((attr) => !attr)) {
+            this.emit('warning', `Child is not literal: ${slicedExpression}`)
+          }
 
           return {
             type: 'js',


Test patch:
diff --git a/test/lexers/jsx-lexer.test.js b/test/lexers/jsx-lexer.test.js
index e1745d9..28aa651 100644
--- a/test/lexers/jsx-lexer.test.js
+++ b/test/lexers/jsx-lexer.test.js
@@ -1,4 +1,5 @@
 import { assert } from 'chai'
+import sinon from 'sinon'
 import JsxLexer from '../../src/lexers/jsx-lexer.js'
 
 describe('JsxLexer', () => {
@@ -535,6 +536,19 @@ describe('JsxLexer', () => {
         )
         done()
       })
+
+      it('does not emit a warning about non-literal child when defaults and i18nKey are specified', (done) => {
+        const Lexer = new JsxLexer({
+          transIdentityFunctionsToIgnore: ['funcCall'],
+        })
+        const content =
+          '<Trans i18nKey="testkey" defaults="test">{anotherFuncCall({ name: "John" })}</Trans>'
+        const spy = sinon.spy()
+        Lexer.on('warning', spy)
+        assert.equal(Lexer.extract(content)[0].defaultValue, 'test')
+        assert.isFalse(spy.called)
+        done()
+      })
     })
   })
 })