fix(localize): support fallback locale

This commit is contained in:
Mikhail Bashkirov 2019-07-15 14:32:48 +02:00
parent 688fcb6690
commit e7ea9cb6f4
2 changed files with 72 additions and 4 deletions

View file

@ -16,6 +16,7 @@ export class LocalizeManager extends LionSingleton {
}
this._autoLoadOnLocaleChange = !!params.autoLoadOnLocaleChange;
this._fallbackLocale = params.fallbackLocale;
this.__storage = {};
this.__namespacePatternsMap = new Map();
this.__namespaceLoadersCache = {};
@ -163,13 +164,24 @@ export class LocalizeManager extends LionSingleton {
return loader;
}
_getNamespaceLoaderPromise(loader, locale, namespace) {
_getNamespaceLoaderPromise(loader, locale, namespace, fallbackLocale = this._fallbackLocale) {
return loader(locale, namespace).catch(() => {
const lang = this._getLangFromLocale(locale);
return loader(lang, namespace).catch(() => {
if (fallbackLocale) {
return this._getNamespaceLoaderPromise(loader, fallbackLocale, namespace, false).catch(
() => {
const fallbackLang = this._getLangFromLocale(fallbackLocale);
throw new Error(
`Data for namespace "${namespace}" and current locale "${locale}" or fallback locale "${fallbackLocale}" could not be loaded. ` +
`Make sure you have data either for locale "${locale}" (and/or generic language "${lang}") or for fallback "${fallbackLocale}" (and/or "${fallbackLang}").`,
);
},
);
}
throw new Error(
`Data for namespace "${namespace}" and locale "${locale}" could not be loaded. ` +
`Make sure you have data for locale "${locale}" and/or generic language "${lang}".`,
`Make sure you have data for locale "${locale}" (and/or generic language "${lang}").`,
);
});
});

View file

@ -213,7 +213,7 @@ describe('LocalizeManager', () => {
});
});
it('fallbacks to language file if locale file is not found', async () => {
it('loads generic language file if locale file is not found', async () => {
setupFakeImport('./my-component/en.js', { default: { greeting: 'Hello!' } });
manager = new LocalizeManager();
@ -240,13 +240,69 @@ describe('LocalizeManager', () => {
expect(e).to.be.instanceof(Error);
expect(e.message).to.equal(
'Data for namespace "my-component" and locale "en-GB" could not be loaded. ' +
'Make sure you have data for locale "en-GB" and/or generic language "en".',
'Make sure you have data for locale "en-GB" (and/or generic language "en").',
);
return;
}
throw new Error('did not throw');
});
describe('fallback locale', () => {
it('can load a fallback locale if current one can not be loaded', async () => {
manager = new LocalizeManager({ fallbackLocale: 'en-GB' });
manager.locale = 'nl-NL';
setupFakeImport('./my-component/en-GB.js', { default: { greeting: 'Hello!' } });
await manager.loadNamespace({
'my-component': locale => fakeImport(`./my-component/${locale}.js`),
});
expect(manager.__storage).to.deep.equal({
'nl-NL': {
'my-component': { greeting: 'Hello!' },
},
});
});
it('can load fallback generic language file if fallback locale file is not found', async () => {
manager = new LocalizeManager({ fallbackLocale: 'en-GB' });
manager.locale = 'nl-NL';
setupFakeImport('./my-component/en.js', { default: { greeting: 'Hello!' } });
await manager.loadNamespace({
'my-component': locale => fakeImport(`./my-component/${locale}.js`),
});
expect(manager.__storage).to.deep.equal({
'nl-NL': {
'my-component': { greeting: 'Hello!' },
},
});
});
it('throws if neither current locale nor fallback locale are found', async () => {
manager = new LocalizeManager({ fallbackLocale: 'en-GB' });
manager.locale = 'nl-NL';
try {
await manager.loadNamespace({
'my-component': locale => fakeImport(`./my-component/${locale}.js`),
});
} catch (e) {
expect(e).to.be.instanceof(Error);
expect(e.message).to.equal(
'Data for namespace "my-component" and current locale "nl-NL" or fallback locale "en-GB" could not be loaded. ' +
'Make sure you have data either for locale "nl-NL" (and/or generic language "nl") or for fallback "en-GB" (and/or "en").',
);
return;
}
throw new Error('did not throw');
});
});
});
describe('loading using routes predefined via setupNamespaceLoader()', () => {