From c5921bcaee0ff9bee2eac84b4a2c19005803ad1e Mon Sep 17 00:00:00 2001 From: Francisco Madeira Date: Wed, 3 Jan 2024 09:47:43 +0000 Subject: [PATCH] fix: Not handling empty string translations. (#155) --- src/index.ts | 23 ++++++++++++++++++----- test/fixtures/lang/pt.json | 3 ++- test/translate.test.ts | 8 +++++++- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4c70d1a..25af773 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import {reactive, Plugin, computed, ComputedRef, watchEffect} from 'vue' +import { reactive, Plugin, computed, ComputedRef, watchEffect } from 'vue' import { OptionsInterface } from './interfaces/options' import { PluginOptionsInterface } from './interfaces/plugin-options' import { LanguageInterface } from './interfaces/language' @@ -349,13 +349,13 @@ export class I18n { } for (const [key, value] of Object.entries(this.fallbackMessages)) { - if (!this.activeMessages[key] || this.activeMessages[key] === key) { + if (!this.isValid(messages[key]) || this.activeMessages[key] === key) { this.activeMessages[key] = value } } for (const [key] of Object.entries(this.activeMessages)) { - if (!messages[key] && !this.fallbackMessages[key]) { + if (!this.isValid(messages[key]) && !this.isValid(this.fallbackMessages[key])) { this.activeMessages[key] = null } } @@ -392,7 +392,13 @@ export class I18n { */ wTrans(key: string, replacements: ReplacementsInterface = {}): ComputedRef { watchEffect(() => { - this.activeMessages[key] = this.findTranslation(key) || this.findTranslation(key.replace(/\//g, '.')) || key + let value = this.findTranslation(key) + + if (!this.isValid(value)) { + value = this.findTranslation(key.replace(/\//g, '.')) + } + + this.activeMessages[key] = this.isValid(value) ? value : key }) return computed(() => this.makeReplacements(this.activeMessages[key], replacements)) @@ -420,7 +426,7 @@ export class I18n { * Find translation in memory. */ findTranslation(key) { - if (this.activeMessages[key]) { + if (this.isValid(this.activeMessages[key])) { return this.activeMessages[key] } @@ -457,6 +463,13 @@ export class I18n { return message } + /** + * Checks if the message provided is valid. + */ + isValid(message: string | null | undefined): boolean { + return message !== undefined && message !== null + } + /** * Resets all the data stored in memory. */ diff --git a/test/fixtures/lang/pt.json b/test/fixtures/lang/pt.json index 0dcbd72..dc78b33 100644 --- a/test/fixtures/lang/pt.json +++ b/test/fixtures/lang/pt.json @@ -6,5 +6,6 @@ "foo.bar": "baz", "Start/end": "InĂ­cio/Fim", "Get started.": "Comece.", - "
Welcome
": "
Bem-vindo
" + "
Welcome
": "
Bem-vindo
", + "Empty string": "" } diff --git a/test/translate.test.ts b/test/translate.test.ts index b7a649d..3265f42 100644 --- a/test/translate.test.ts +++ b/test/translate.test.ts @@ -17,6 +17,12 @@ it('translates with "trans" helper', async () => { expect(trans('Welcome!')).toBe('Bem-vindo!'); }) +it('handles empty translations', async () => { + await global.mountPlugin(); + + expect(trans('Empty string')).toBe(''); +}) + it('returns the same message if there is no resolve method provided', async () => { const wrapper = mount({ template: `

{{ $t('Welcome!') }}

` }, { global: { @@ -256,4 +262,4 @@ it('checks if watching wTrans works if key does not exist', async () => { await loadLanguageAsync('en'); expect(translated.value).toBe('Not existing translation'); -}) \ No newline at end of file +})