From 7b63922539304ccbff4fcd589981efda9bf138bb Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Fri, 12 Apr 2024 09:22:48 +0900 Subject: [PATCH 01/10] feat: don't show warning for same language --- packages/core-base/src/context.ts | 12 +++++++++++- packages/core-base/src/translate.ts | 6 ++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/core-base/src/context.ts b/packages/core-base/src/context.ts index 3c673f74c..d4978bfde 100644 --- a/packages/core-base/src/context.ts +++ b/packages/core-base/src/context.ts @@ -647,6 +647,12 @@ export function isTranslateMissingWarn( return missing instanceof RegExp ? missing.test(key) : missing } +export function isSameLanguage(locale: Locale, fallback: Locale): boolean { + const languageCode1 = locale.split('-')[0] + const languageCode2 = fallback.split('-')[0] + return languageCode1 === languageCode2 +} + /** @internal */ export function handleMissing( context: CoreContext, @@ -674,7 +680,11 @@ export function handleMissing( const ret = missing(context as any, locale, key, type) return isString(ret) ? ret : key } else { - if (__DEV__ && isTranslateMissingWarn(missingWarn, key)) { + if ( + __DEV__ && + isTranslateMissingWarn(missingWarn, key) && + !isSameLanguage(locale, context.fallbackLocale as Locale) + ) { onWarn(getWarnMessage(CoreWarnCodes.NOT_FOUND_KEY, { key, locale })) } return key diff --git a/packages/core-base/src/translate.ts b/packages/core-base/src/translate.ts index 465266a5c..2634b017b 100644 --- a/packages/core-base/src/translate.ts +++ b/packages/core-base/src/translate.ts @@ -23,7 +23,8 @@ import { handleMissing, NOT_REOSLVED, getAdditionalMeta, - CoreContext + CoreContext, + isSameLanguage } from './context' import { CoreWarnCodes, getWarnMessage } from './warnings' import { CoreErrorCodes, createCoreError } from './errors' @@ -839,7 +840,8 @@ function resolveMessageFormat( if ( __DEV__ && locale !== targetLocale && - isTranslateFallbackWarn(fallbackWarn, key) + isTranslateFallbackWarn(fallbackWarn, key) && + !isSameLanguage(locale, targetLocale) ) { onWarn( getWarnMessage(CoreWarnCodes.FALLBACK_TO_TRANSLATE, { From e2add23a0520a865a688c924e3c7f6aef65d122e Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Sat, 13 Apr 2024 10:55:49 +0900 Subject: [PATCH 02/10] test: don't show warning for same language --- packages/vue-i18n-core/test/issues.test.ts | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/vue-i18n-core/test/issues.test.ts b/packages/vue-i18n-core/test/issues.test.ts index 550e288cb..04a4571fe 100644 --- a/packages/vue-i18n-core/test/issues.test.ts +++ b/packages/vue-i18n-core/test/issues.test.ts @@ -1358,3 +1358,27 @@ test('issue #1738', async () => { expect(wrapper.find('#te1')?.textContent).toEqual(`true - expected true`) expect(wrapper.find('#te2')?.textContent).toEqual(`true - expected true`) }) + +test('issue #1768', async () => { + const mockWarn = vi.spyOn(shared, 'warn') + // eslint-disable-next-line @typescript-eslint/no-empty-function + mockWarn.mockImplementation(() => {}) + + const i18n = createI18n({ + locale: 'en-US', + fallbackLocale: 'en', + messages: { + en: { + hello: 'Hello, Vue I18n' + } + } + }) + + const App = defineComponent({ + template: `
{{ $t('hello') }}
` + }) + const wrapper = await mount(App, i18n) + + expect(wrapper.html()).toEqual('
Hello, Vue I18n
') + expect(mockWarn).toHaveBeenCalledTimes(0) +}) From 5c8f1c7408be9633a6125c57290bc4d7c9344f70 Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Sat, 13 Apr 2024 10:56:15 +0900 Subject: [PATCH 03/10] fix: case of simply missing key --- packages/core-base/src/context.ts | 24 +++++++++++++++++++----- packages/core-base/src/translate.ts | 5 +++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/packages/core-base/src/context.ts b/packages/core-base/src/context.ts index d4978bfde..57ad2bd3f 100644 --- a/packages/core-base/src/context.ts +++ b/packages/core-base/src/context.ts @@ -647,10 +647,23 @@ export function isTranslateMissingWarn( return missing instanceof RegExp ? missing.test(key) : missing } -export function isSameLanguage(locale: Locale, fallback: Locale): boolean { +/** @internal */ +export function isSameLanguage( + messages: any, + key: Path, + locale: Locale, + fallback: Locale | undefined +): boolean { const languageCode1 = locale.split('-')[0] - const languageCode2 = fallback.split('-')[0] - return languageCode1 === languageCode2 + const languageCode2 = fallback?.split('-')[0] + + if (languageCode1 === languageCode2) { + const hasKey = + messages[languageCode1!] && messages[languageCode1!][key] !== undefined + return hasKey + } else { + return false + } } /** @internal */ @@ -659,7 +672,8 @@ export function handleMissing( key: Path, locale: Locale, missingWarn: boolean | RegExp, - type: CoreMissingType + type: CoreMissingType, + locale2?: Locale ): unknown { const { missing, onWarn } = context @@ -683,7 +697,7 @@ export function handleMissing( if ( __DEV__ && isTranslateMissingWarn(missingWarn, key) && - !isSameLanguage(locale, context.fallbackLocale as Locale) + !isSameLanguage(context.messages, key, locale, locale2) ) { onWarn(getWarnMessage(CoreWarnCodes.NOT_FOUND_KEY, { key, locale })) } diff --git a/packages/core-base/src/translate.ts b/packages/core-base/src/translate.ts index 2634b017b..235f526af 100644 --- a/packages/core-base/src/translate.ts +++ b/packages/core-base/src/translate.ts @@ -841,7 +841,7 @@ function resolveMessageFormat( __DEV__ && locale !== targetLocale && isTranslateFallbackWarn(fallbackWarn, key) && - !isSameLanguage(locale, targetLocale) + !isSameLanguage(messages, key, locale, targetLocale) ) { onWarn( getWarnMessage(CoreWarnCodes.FALLBACK_TO_TRANSLATE, { @@ -912,7 +912,8 @@ function resolveMessageFormat( key, targetLocale, missingWarn, - type + type, + locale ) if (missingRet !== key) { format = missingRet as PathValue From f957b942aaaeb51789551d0871eb5ba31654d0fa Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Sat, 13 Apr 2024 13:57:11 +0900 Subject: [PATCH 04/10] fix: consider nested case --- packages/vue-i18n-core/test/issues.test.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/vue-i18n-core/test/issues.test.ts b/packages/vue-i18n-core/test/issues.test.ts index 04a4571fe..fc6570138 100644 --- a/packages/vue-i18n-core/test/issues.test.ts +++ b/packages/vue-i18n-core/test/issues.test.ts @@ -1369,13 +1369,15 @@ test('issue #1768', async () => { fallbackLocale: 'en', messages: { en: { - hello: 'Hello, Vue I18n' + hello: { + 'vue-i18n': 'Hello, Vue I18n' + } } } }) const App = defineComponent({ - template: `
{{ $t('hello') }}
` + template: `
{{ $t('hello.vue-i18n') }}
` }) const wrapper = await mount(App, i18n) From de801754c8f90a25683e2afd8bbf4989d1dca3ad Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Sat, 13 Apr 2024 13:57:41 +0900 Subject: [PATCH 05/10] fix: nested message case --- packages/core-base/src/context.ts | 29 ++++++++++++++++++++--------- packages/core-base/src/translate.ts | 4 ++-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/packages/core-base/src/context.ts b/packages/core-base/src/context.ts index 57ad2bd3f..5fdb5746f 100644 --- a/packages/core-base/src/context.ts +++ b/packages/core-base/src/context.ts @@ -648,19 +648,30 @@ export function isTranslateMissingWarn( } /** @internal */ -export function isSameLanguage( +export function isImplicitFallback( messages: any, key: Path, locale: Locale, fallback: Locale | undefined ): boolean { - const languageCode1 = locale.split('-')[0] - const languageCode2 = fallback?.split('-')[0] + const localLanguageCode = locale.split('-')[0] + const fallbackLanguageCode = fallback?.split('-')[0] + + if (localLanguageCode === fallbackLanguageCode) { + const hasKeyInMessages = (obj: any, keyPath: string[]): boolean => { + const key = keyPath[0] + if (obj && key in obj) { + if (keyPath.length === 1) { + return true + } + return hasKeyInMessages(obj[key], keyPath.slice(1)) + } + return false + } + + const keyPathArray = key.split('.') - if (languageCode1 === languageCode2) { - const hasKey = - messages[languageCode1!] && messages[languageCode1!][key] !== undefined - return hasKey + return hasKeyInMessages(messages[localLanguageCode], keyPathArray) } else { return false } @@ -673,7 +684,7 @@ export function handleMissing( locale: Locale, missingWarn: boolean | RegExp, type: CoreMissingType, - locale2?: Locale + fallbackLocale?: Locale ): unknown { const { missing, onWarn } = context @@ -697,7 +708,7 @@ export function handleMissing( if ( __DEV__ && isTranslateMissingWarn(missingWarn, key) && - !isSameLanguage(context.messages, key, locale, locale2) + !isImplicitFallback(context.messages, key, locale, fallbackLocale) ) { onWarn(getWarnMessage(CoreWarnCodes.NOT_FOUND_KEY, { key, locale })) } diff --git a/packages/core-base/src/translate.ts b/packages/core-base/src/translate.ts index 235f526af..74d173b7a 100644 --- a/packages/core-base/src/translate.ts +++ b/packages/core-base/src/translate.ts @@ -24,7 +24,7 @@ import { NOT_REOSLVED, getAdditionalMeta, CoreContext, - isSameLanguage + isImplicitFallback } from './context' import { CoreWarnCodes, getWarnMessage } from './warnings' import { CoreErrorCodes, createCoreError } from './errors' @@ -841,7 +841,7 @@ function resolveMessageFormat( __DEV__ && locale !== targetLocale && isTranslateFallbackWarn(fallbackWarn, key) && - !isSameLanguage(messages, key, locale, targetLocale) + !isImplicitFallback(messages, key, locale, targetLocale) ) { onWarn( getWarnMessage(CoreWarnCodes.FALLBACK_TO_TRANSLATE, { From 7cedf0eb67ad44c9f859aba44b0326b69ab4e1d9 Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Sat, 13 Apr 2024 15:45:41 +0900 Subject: [PATCH 06/10] use context message resolver --- packages/core-base/src/context.ts | 23 ++++++----------------- packages/core-base/src/translate.ts | 7 ++++++- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/packages/core-base/src/context.ts b/packages/core-base/src/context.ts index 5fdb5746f..86d951244 100644 --- a/packages/core-base/src/context.ts +++ b/packages/core-base/src/context.ts @@ -648,30 +648,19 @@ export function isTranslateMissingWarn( } /** @internal */ -export function isImplicitFallback( - messages: any, +export function isImplicitFallback( + context: CoreContext, key: Path, locale: Locale, fallback: Locale | undefined ): boolean { const localLanguageCode = locale.split('-')[0] const fallbackLanguageCode = fallback?.split('-')[0] + const messages: Record = context.messages if (localLanguageCode === fallbackLanguageCode) { - const hasKeyInMessages = (obj: any, keyPath: string[]): boolean => { - const key = keyPath[0] - if (obj && key in obj) { - if (keyPath.length === 1) { - return true - } - return hasKeyInMessages(obj[key], keyPath.slice(1)) - } - return false - } - - const keyPathArray = key.split('.') - - return hasKeyInMessages(messages[localLanguageCode], keyPathArray) + const message = context.messageResolver(messages[localLanguageCode], key) + return !!message } else { return false } @@ -708,7 +697,7 @@ export function handleMissing( if ( __DEV__ && isTranslateMissingWarn(missingWarn, key) && - !isImplicitFallback(context.messages, key, locale, fallbackLocale) + !isImplicitFallback(context, key, locale, fallbackLocale) ) { onWarn(getWarnMessage(CoreWarnCodes.NOT_FOUND_KEY, { key, locale })) } diff --git a/packages/core-base/src/translate.ts b/packages/core-base/src/translate.ts index 74d173b7a..311695ffe 100644 --- a/packages/core-base/src/translate.ts +++ b/packages/core-base/src/translate.ts @@ -841,7 +841,12 @@ function resolveMessageFormat( __DEV__ && locale !== targetLocale && isTranslateFallbackWarn(fallbackWarn, key) && - !isImplicitFallback(messages, key, locale, targetLocale) + !isImplicitFallback( + context as CoreContext, + key, + locale, + targetLocale + ) ) { onWarn( getWarnMessage(CoreWarnCodes.FALLBACK_TO_TRANSLATE, { From 348ace16f808f1f2923e19c3383b703fa55f9344 Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Sat, 13 Apr 2024 17:12:05 +0900 Subject: [PATCH 07/10] fix: simplify --- packages/core-base/src/context.ts | 27 +++++----------------- packages/core-base/src/translate.ts | 35 +++++++++++++---------------- 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/packages/core-base/src/context.ts b/packages/core-base/src/context.ts index 86d951244..d1e8b20ff 100644 --- a/packages/core-base/src/context.ts +++ b/packages/core-base/src/context.ts @@ -648,22 +648,12 @@ export function isTranslateMissingWarn( } /** @internal */ -export function isImplicitFallback( - context: CoreContext, - key: Path, +export function isAlmostSameLanguage( locale: Locale, - fallback: Locale | undefined + compareLocale: Locale ): boolean { - const localLanguageCode = locale.split('-')[0] - const fallbackLanguageCode = fallback?.split('-')[0] - const messages: Record = context.messages - - if (localLanguageCode === fallbackLanguageCode) { - const message = context.messageResolver(messages[localLanguageCode], key) - return !!message - } else { - return false - } + if (locale === compareLocale) return false + return locale.split('-')[0] === compareLocale.split('-')[0] } /** @internal */ @@ -672,8 +662,7 @@ export function handleMissing( key: Path, locale: Locale, missingWarn: boolean | RegExp, - type: CoreMissingType, - fallbackLocale?: Locale + type: CoreMissingType ): unknown { const { missing, onWarn } = context @@ -694,11 +683,7 @@ export function handleMissing( const ret = missing(context as any, locale, key, type) return isString(ret) ? ret : key } else { - if ( - __DEV__ && - isTranslateMissingWarn(missingWarn, key) && - !isImplicitFallback(context, key, locale, fallbackLocale) - ) { + if (__DEV__ && isTranslateMissingWarn(missingWarn, key)) { onWarn(getWarnMessage(CoreWarnCodes.NOT_FOUND_KEY, { key, locale })) } return key diff --git a/packages/core-base/src/translate.ts b/packages/core-base/src/translate.ts index 311695ffe..b7a3040da 100644 --- a/packages/core-base/src/translate.ts +++ b/packages/core-base/src/translate.ts @@ -20,11 +20,11 @@ import { isMessageAST } from './compilation' import { createMessageContext } from './runtime' import { isTranslateFallbackWarn, + isAlmostSameLanguage, handleMissing, NOT_REOSLVED, getAdditionalMeta, - CoreContext, - isImplicitFallback + CoreContext } from './context' import { CoreWarnCodes, getWarnMessage } from './warnings' import { CoreErrorCodes, createCoreError } from './errors' @@ -840,13 +840,8 @@ function resolveMessageFormat( if ( __DEV__ && locale !== targetLocale && - isTranslateFallbackWarn(fallbackWarn, key) && - !isImplicitFallback( - context as CoreContext, - key, - locale, - targetLocale - ) + !isAlmostSameLanguage(targetLocale, locale) && + isTranslateFallbackWarn(fallbackWarn, key) ) { onWarn( getWarnMessage(CoreWarnCodes.FALLBACK_TO_TRANSLATE, { @@ -912,16 +907,18 @@ function resolveMessageFormat( break } - const missingRet = handleMissing( - context as any, // eslint-disable-line @typescript-eslint/no-explicit-any - key, - targetLocale, - missingWarn, - type, - locale - ) - if (missingRet !== key) { - format = missingRet as PathValue + const fallback = locales[locales.length - 1] + if (!isAlmostSameLanguage(targetLocale, fallback)) { + const missingRet = handleMissing( + context as any, // eslint-disable-line @typescript-eslint/no-explicit-any + key, + targetLocale, + missingWarn, + type + ) + if (missingRet !== key) { + format = missingRet as PathValue + } } from = to } From b21cf0409f4383ae461990ee91215a3d82ded89c Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Sat, 13 Apr 2024 18:14:56 +0900 Subject: [PATCH 08/10] fix: array or object of fallback pattern --- packages/core-base/src/context.ts | 40 ++++++++++++++++++++++------- packages/core-base/src/translate.ts | 8 +++--- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/packages/core-base/src/context.ts b/packages/core-base/src/context.ts index d1e8b20ff..9fbe2b22b 100644 --- a/packages/core-base/src/context.ts +++ b/packages/core-base/src/context.ts @@ -647,15 +647,6 @@ export function isTranslateMissingWarn( return missing instanceof RegExp ? missing.test(key) : missing } -/** @internal */ -export function isAlmostSameLanguage( - locale: Locale, - compareLocale: Locale -): boolean { - if (locale === compareLocale) return false - return locale.split('-')[0] === compareLocale.split('-')[0] -} - /** @internal */ export function handleMissing( context: CoreContext, @@ -701,4 +692,35 @@ export function updateFallbackLocale( ctx.localeFallbacker(ctx, fallback, locale) } +/** @internal */ +export function isAlmostSameLocale( + locale: Locale, + compareLocale: Locale +): boolean { + if (locale === compareLocale) return false + return locale.split('-')[0] === compareLocale.split('-')[0] +} + +/** @internal */ +export function isImplicitFallback( + locale: Locale, + fallbackLocale: FallbackLocale +): boolean { + if (isString(fallbackLocale)) { + return isAlmostSameLocale(locale, fallbackLocale) + } + + if (isArray(fallbackLocale)) { + return fallbackLocale.some(fbLocale => isAlmostSameLocale(locale, fbLocale)) + } + + if (isObject(fallbackLocale)) { + return Object.values(fallbackLocale).some(fbLocales => { + return fbLocales.some(fbLocale => isAlmostSameLocale(locale, fbLocale)) + }) + } + + return false +} + /* eslint-enable @typescript-eslint/no-explicit-any */ diff --git a/packages/core-base/src/translate.ts b/packages/core-base/src/translate.ts index b7a3040da..2644cde61 100644 --- a/packages/core-base/src/translate.ts +++ b/packages/core-base/src/translate.ts @@ -20,7 +20,8 @@ import { isMessageAST } from './compilation' import { createMessageContext } from './runtime' import { isTranslateFallbackWarn, - isAlmostSameLanguage, + isAlmostSameLocale, + isImplicitFallback, handleMissing, NOT_REOSLVED, getAdditionalMeta, @@ -840,7 +841,7 @@ function resolveMessageFormat( if ( __DEV__ && locale !== targetLocale && - !isAlmostSameLanguage(targetLocale, locale) && + !isAlmostSameLocale(locale, targetLocale) && isTranslateFallbackWarn(fallbackWarn, key) ) { onWarn( @@ -907,8 +908,7 @@ function resolveMessageFormat( break } - const fallback = locales[locales.length - 1] - if (!isAlmostSameLanguage(targetLocale, fallback)) { + if (!isImplicitFallback(targetLocale, fallbackLocale)) { const missingRet = handleMissing( context as any, // eslint-disable-line @typescript-eslint/no-explicit-any key, From 90005abc2afd6a39dce6f450a7f4988f36d839b7 Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Sun, 14 Apr 2024 20:32:46 +0900 Subject: [PATCH 09/10] fix: change the way of isImplicitFallback --- packages/core-base/src/context.ts | 21 +++++++++------------ packages/core-base/src/translate.ts | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/core-base/src/context.ts b/packages/core-base/src/context.ts index 7b77ecda9..3104e1c79 100644 --- a/packages/core-base/src/context.ts +++ b/packages/core-base/src/context.ts @@ -703,21 +703,18 @@ export function isAlmostSameLocale( /** @internal */ export function isImplicitFallback( - locale: Locale, - fallbackLocale: FallbackLocale + targetLocale: Locale, + locales: Locale[] ): boolean { - if (isString(fallbackLocale)) { - return isAlmostSameLocale(locale, fallbackLocale) - } - - if (isArray(fallbackLocale)) { - return fallbackLocale.some(fbLocale => isAlmostSameLocale(locale, fbLocale)) + const index = locales.indexOf(targetLocale) + if (index === -1) { + return false } - if (isObject(fallbackLocale)) { - return Object.values(fallbackLocale).some(fbLocales => { - return fbLocales.some(fbLocale => isAlmostSameLocale(locale, fbLocale)) - }) + for (let i = index + 1; i < locales.length; i++) { + if (isAlmostSameLocale(targetLocale, locales[i])) { + return true + } } return false diff --git a/packages/core-base/src/translate.ts b/packages/core-base/src/translate.ts index 2644cde61..70a54e44e 100644 --- a/packages/core-base/src/translate.ts +++ b/packages/core-base/src/translate.ts @@ -908,7 +908,7 @@ function resolveMessageFormat( break } - if (!isImplicitFallback(targetLocale, fallbackLocale)) { + if (!isImplicitFallback(targetLocale, locales)) { const missingRet = handleMissing( context as any, // eslint-disable-line @typescript-eslint/no-explicit-any key, From 2d2052f0b3ab2291e49775560760e69a3bbb1160 Mon Sep 17 00:00:00 2001 From: ShinnosukeKomiya Date: Sun, 14 Apr 2024 20:33:58 +0900 Subject: [PATCH 10/10] test: add Explicit fallback with decision maps test --- packages/vue-i18n-core/test/issues.test.ts | 71 ++++++++++++++++------ 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/packages/vue-i18n-core/test/issues.test.ts b/packages/vue-i18n-core/test/issues.test.ts index 0a6df49dd..c635eef96 100644 --- a/packages/vue-i18n-core/test/issues.test.ts +++ b/packages/vue-i18n-core/test/issues.test.ts @@ -1359,30 +1359,65 @@ test('issue #1738', async () => { expect(wrapper.find('#te2')?.textContent).toEqual(`true - expected true`) }) -test('issue #1768', async () => { - const mockWarn = vi.spyOn(shared, 'warn') - // eslint-disable-next-line @typescript-eslint/no-empty-function - mockWarn.mockImplementation(() => {}) +describe('issue #1768', () => { + test('Implicit fallback using locales', async () => { + const mockWarn = vi.spyOn(shared, 'warn') + // eslint-disable-next-line @typescript-eslint/no-empty-function + mockWarn.mockImplementation(() => {}) - const i18n = createI18n({ - locale: 'en-US', - fallbackLocale: 'en', - messages: { - en: { - hello: { - 'vue-i18n': 'Hello, Vue I18n' + const i18n = createI18n({ + locale: 'en-US', + fallbackLocale: 'en', + messages: { + en: { + hello: { + 'vue-i18n': 'Hello, Vue I18n' + } } } - } - }) + }) - const App = defineComponent({ - template: `
{{ $t('hello.vue-i18n') }}
` + const App = defineComponent({ + template: `
{{ $t('hello.vue-i18n') }}
` + }) + const wrapper = await mount(App, i18n) + + expect(wrapper.html()).toEqual('
Hello, Vue I18n
') + expect(mockWarn).toHaveBeenCalledTimes(0) }) - const wrapper = await mount(App, i18n) - expect(wrapper.html()).toEqual('
Hello, Vue I18n
') - expect(mockWarn).toHaveBeenCalledTimes(0) + test('Explicit fallback with decision maps', async () => { + const mockWarn = vi.spyOn(shared, 'warn') + // eslint-disable-next-line @typescript-eslint/no-empty-function + mockWarn.mockImplementation(() => {}) + + const i18n = createI18n({ + locale: 'zh-Hant', + fallbackLocale: { + 'de-CH': ['fr', 'it'], + 'zh-Hant': ['zh-Hans'], + 'es-CL': ['es-AR'], + es: ['en-GB'], + pt: ['es-AR'], + default: ['en', 'da'] + }, + messages: { + zh: { + hello: { + 'vue-i18n': '你好,Vue I18n' + } + } + } + }) + + const App = defineComponent({ + template: `
{{ $t('hello.vue-i18n') }}
` + }) + const wrapper = await mount(App, i18n) + + expect(wrapper.html()).toEqual('
你好,Vue I18n
') + expect(mockWarn).toHaveBeenCalledTimes(0) + }) }) test('#1796', async () => {