Repository: i18next/i18next-parser
Pull request #1008 (2024-05-29 14:00:03)

custom contextSeparator fix
### Why am I submitting this PR

Unused keys where words separated with underscore (for example "some_key", "some_key_just_started_like_previous") not removed because _ hardcoded in helpers.js contextRegex and both "some_key" and "some_key_just_started_like_previous" treats like context forms of one key.

### Does it fix an existing ticket?

No

### 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))



Patch:
diff --git a/src/helpers.js b/src/helpers.js
index 7bbd58f..1fd91aa 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -131,6 +131,7 @@ function mergeHashes(source, target, options = {}, resetValues = {}) {
   const fullKeyPrefix = options.fullKeyPrefix || ''
   const keySeparator = options.keySeparator || '.'
   const pluralSeparator = options.pluralSeparator || '_'
+  const contextSeparator = options.contextSeparator || '_'
 
   for (const key in source) {
     const hasNestedEntries =
@@ -180,7 +181,9 @@ function mergeHashes(source, target, options = {}, resetValues = {}) {
       const pluralMatch = key !== singularKey
 
       // support for context in keys
-      const contextRegex = /_([^_]+)?$/
+      const contextRegex = new RegExp(
+        `\\${contextSeparator}([^\\${contextSeparator}]+)?$`
+      )
       const contextMatch = contextRegex.test(singularKey)
       const rawKey = singularKey.replace(contextRegex, '')
 


Test patch:
diff --git a/test/helpers/mergeHashes.test.js b/test/helpers/mergeHashes.test.js
index 7725a84..079356d 100644
--- a/test/helpers/mergeHashes.test.js
+++ b/test/helpers/mergeHashes.test.js
@@ -137,6 +137,19 @@ describe('mergeHashes helper function', () => {
     done()
   })
 
+  it('restores context keys when the singular one exists (custom contextSeparator)', (done) => {
+    const source = { key1: '', 'key1|context': 'value1' }
+    const target = { key1: '' }
+    const res = mergeHashes(source, target, { contextSeparator: '|' })
+
+    assert.deepEqual(res.new, { key1: '', 'key1|context': 'value1' })
+    assert.deepEqual(res.old, {})
+    assert.strictEqual(res.mergeCount, 1)
+    assert.strictEqual(res.pullCount, 1)
+    assert.strictEqual(res.oldCount, 0)
+    done()
+  })
+
   it('does not restore context keys when the singular one does not', (done) => {
     const source = { key1: '', key1_context: 'value1' }
     const target = { key2: '' }
@@ -150,6 +163,19 @@ describe('mergeHashes helper function', () => {
     done()
   })
 
+  it('does not restore context keys when the singular one does not (custom contextSeparator)', (done) => {
+    const source = { key1: '', 'key1|context': 'value1' }
+    const target = { key2: '' }
+    const res = mergeHashes(source, target, { contextSeparator: '|' })
+
+    assert.deepEqual(res.new, { key2: '' })
+    assert.deepEqual(res.old, { key1: '', 'key1|context': 'value1' })
+    assert.strictEqual(res.mergeCount, 0)
+    assert.strictEqual(res.pullCount, 0)
+    assert.strictEqual(res.oldCount, 2)
+    done()
+  })
+
   it('works with deep objects', (done) => {
     const source = {
       key1: 'value1',