diff --git a/packages/osd-i18n/src/core/i18n.test.ts b/packages/osd-i18n/src/core/i18n.test.ts index ebfd546f8561..ad5ed920fd01 100644 --- a/packages/osd-i18n/src/core/i18n.test.ts +++ b/packages/osd-i18n/src/core/i18n.test.ts @@ -178,7 +178,7 @@ describe('I18n engine', () => { 'en-us' ); - expect(i18n.getLocale()).toBe('en-us'); + expect(i18n.getLocale()).toBe('en-US'); expect(i18n.getTranslation()).toEqual({ messages: { ['a.b.c']: 'bar', @@ -246,9 +246,19 @@ describe('I18n engine', () => { expect(i18n.getLocale()).toBe('foo'); }); - test('should normalize passed locale', () => { - i18n.setLocale('en-US'); - expect(i18n.getLocale()).toBe('en-us'); + test('should normalize basic locale', () => { + i18n.setLocale('It-iT'); + expect(i18n.getLocale()).toBe('it-IT'); + }); + + test('should normalize simple locale', () => { + i18n.setLocale('en-LATN-us_PRIVATE-variant'); + expect(i18n.getLocale()).toBe('en-Latn-US'); + }); + + test('should normalize complex locale', () => { + i18n.setLocale('FR-CA-X-FALLBACK-und-u@keyword=calendarKey'); + expect(i18n.getLocale()).toBe('fr-CA'); }); }); @@ -280,8 +290,8 @@ describe('I18n engine', () => { }); test('should normalize passed locale', () => { - i18n.setDefaultLocale('en-US'); - expect(i18n.getDefaultLocale()).toBe('en-us'); + i18n.setDefaultLocale('eN-uS'); + expect(i18n.getDefaultLocale()).toBe('en-US'); }); test('should set "en" locale as default for IntlMessageFormat and IntlRelativeFormat', () => { diff --git a/packages/osd-i18n/src/core/i18n.ts b/packages/osd-i18n/src/core/i18n.ts index 65da4931ef13..fc040bb834e6 100644 --- a/packages/osd-i18n/src/core/i18n.ts +++ b/packages/osd-i18n/src/core/i18n.ts @@ -44,6 +44,16 @@ const EN_LOCALE = 'en'; const translationsForLocale: Record = {}; const getMessageFormat = memoizeIntlConstructor(IntlMessageFormat); +/* A locale code is made of several components: + * * lang: The two- and three-letter lower-case language code follows the ISO 639-1 and ISO 639-2/3 standards, respectively. + * * script: The optional four-letter title-case code follows the ISO 15924 standard for representing writing systems. + * * region: The two-letter upper-case region code follows the ISO 3166-1 alpha-2 standard. + * + * Ref: https://www.rfc-editor.org/rfc/rfc5646.txt + * Note: While case carries no distinction with locale codes, proper formatting is recommended. + */ +const localeParser = /^(?[a-z]{2,3})(?:-(?