1a47a1472SVille Immonenimport * as Localization from 'expo-localization'; 2f2c6b866SŁukasz Kosmatyimport i18n from 'i18n-js'; 3d1736fc2SHein Rutjesimport { Platform } from 'react-native'; 4740b3867SJames Ide 5ad26c082SEvan Baconconst en = { 667f55e2bSStanisław Chmiela good: 'good', 767f55e2bSStanisław Chmiela morning: 'morning', 8ad26c082SEvan Bacon}; 9ad26c082SEvan Bacon 10ad26c082SEvan Baconconst fr = { 1167f55e2bSStanisław Chmiela good: 'bien', 1267f55e2bSStanisław Chmiela morning: 'matin', 1367f55e2bSStanisław Chmiela}; 1467f55e2bSStanisław Chmiela 1567f55e2bSStanisław Chmielaconst pl = { 1667f55e2bSStanisław Chmiela good: 'dobry', 1767f55e2bSStanisław Chmiela morning: 'rano', 18ad26c082SEvan Bacon}; 19740b3867SJames Ide 20740b3867SJames Ideexport const name = 'Localization'; 21740b3867SJames Ide 22740b3867SJames Ideexport function test(t) { 23ad26c082SEvan Bacon function validateString(result) { 24ad26c082SEvan Bacon t.expect(result).toBeDefined(); 25ad26c082SEvan Bacon t.expect(typeof result).toBe('string'); 26ad26c082SEvan Bacon t.expect(result.length > 0).toBe(true); 27ad26c082SEvan Bacon } 28ad26c082SEvan Bacon 29ad26c082SEvan Bacon function validateStringArray(result) { 30ad26c082SEvan Bacon t.expect(result).toBeDefined(); 31ad26c082SEvan Bacon t.expect(Array.isArray(result)).toBe(true); 32ad26c082SEvan Bacon } 33ad26c082SEvan Bacon 34d1736fc2SHein Rutjes t.describe(`Localization methods`, () => { 35*17185210Saleqsio t.it('expect to getLocales return preferred locales', () => { 36*17185210Saleqsio const locales = Localization.getLocales(); 37*17185210Saleqsio t.expect(locales.length).toBeGreaterThanOrEqual(1); 38*17185210Saleqsio const { 39*17185210Saleqsio languageTag, 40*17185210Saleqsio languageCode, 41*17185210Saleqsio regionCode, 42*17185210Saleqsio currencyCode, 43*17185210Saleqsio currencySymbol, 44*17185210Saleqsio decimalSeparator, 45*17185210Saleqsio digitGroupingSeparator, 46*17185210Saleqsio textDirection, 47*17185210Saleqsio measurementSystem, 48*17185210Saleqsio } = locales[0]; 49*17185210Saleqsio validateString(languageTag); 50*17185210Saleqsio validateString(languageCode); 51*17185210Saleqsio // following properties can be nullish if the locale does not provide/override them 52*17185210Saleqsio t.expect(regionCode).toBeDefined(); 53*17185210Saleqsio t.expect(currencyCode).toBeDefined(); 54*17185210Saleqsio t.expect(currencySymbol).toBeDefined(); 55*17185210Saleqsio t.expect(decimalSeparator).toBeDefined(); 56*17185210Saleqsio t.expect(digitGroupingSeparator).toBeDefined(); 57*17185210Saleqsio t.expect(textDirection).toBeDefined(); 58*17185210Saleqsio if (textDirection) { 59*17185210Saleqsio t.expect(['rtl', 'ltr'].includes(textDirection)).toBe(true); 60*17185210Saleqsio } 61*17185210Saleqsio t.expect(measurementSystem).toBeDefined(); 62*17185210Saleqsio if (measurementSystem) { 63*17185210Saleqsio t.expect(['metric', 'us', 'uk'].includes(measurementSystem)).toBe(true); 64*17185210Saleqsio } 65*17185210Saleqsio }); 66*17185210Saleqsio 67*17185210Saleqsio t.it('expect getCalendars to return at least a single calendar', () => { 68*17185210Saleqsio const calendars = Localization.getCalendars(); 69*17185210Saleqsio t.expect(calendars.length).toBeGreaterThanOrEqual(1); 70*17185210Saleqsio const { calendar, uses24hourClock, firstWeekday, timeZone } = calendars[0]; 71*17185210Saleqsio t.expect(calendar).toBeDefined(); 72*17185210Saleqsio t.expect(timeZone).toBeDefined(); 73*17185210Saleqsio // following properties can be nullish if the locale does not provide/override them 74*17185210Saleqsio t.expect(uses24hourClock).toBeDefined(); 75*17185210Saleqsio if (uses24hourClock !== null) { 76*17185210Saleqsio t.expect(typeof uses24hourClock).toBe('boolean'); 77*17185210Saleqsio } 78*17185210Saleqsio t.expect(firstWeekday).toBeDefined(); 79*17185210Saleqsio if (firstWeekday !== null) { 80*17185210Saleqsio t.expect(typeof firstWeekday).toBe('number'); 81*17185210Saleqsio } 82*17185210Saleqsio }); 83*17185210Saleqsio 84d1736fc2SHein Rutjes t.it('expect async to return locale', async () => { 85ad26c082SEvan Bacon const { 86d1736fc2SHein Rutjes currency, 87d1736fc2SHein Rutjes decimalSeparator, 88d1736fc2SHein Rutjes digitGroupingSeparator, 89d1736fc2SHein Rutjes isoCurrencyCodes, 90d1736fc2SHein Rutjes isMetric, 91d1736fc2SHein Rutjes isRTL, 92ad26c082SEvan Bacon locale, 93ad26c082SEvan Bacon locales, 94ad26c082SEvan Bacon timezone, 95f2c6b866SŁukasz Kosmaty region, 96ad26c082SEvan Bacon } = await Localization.getLocalizationAsync(); 97ad26c082SEvan Bacon 98ad26c082SEvan Bacon validateString(locale); 99ad26c082SEvan Bacon validateString(timezone); 100d1736fc2SHein Rutjes if (Platform.OS !== 'web' || region) { 101f2c6b866SŁukasz Kosmaty validateString(region); 102f2c6b866SŁukasz Kosmaty } 103ad26c082SEvan Bacon validateStringArray(isoCurrencyCodes); 104ad26c082SEvan Bacon validateStringArray(locales); 105ad26c082SEvan Bacon t.expect(locales[0]).toBe(Localization.locale); 106ad26c082SEvan Bacon t.expect(typeof isRTL).toBe('boolean'); 107d1736fc2SHein Rutjes t.expect(typeof isMetric).toBe('boolean'); 108d1736fc2SHein Rutjes validateString(decimalSeparator); 109d1736fc2SHein Rutjes validateString(digitGroupingSeparator); 110d1736fc2SHein Rutjes if (Platform.OS !== 'web' || currency) { 111d1736fc2SHein Rutjes validateString(currency); 112d1736fc2SHein Rutjes } 113ad26c082SEvan Bacon }); 114ad26c082SEvan Bacon }); 115ad26c082SEvan Bacon 116ad26c082SEvan Bacon t.describe(`Localization defines constants`, () => { 117d1736fc2SHein Rutjes t.it('Gets the region', async () => { 118f2c6b866SŁukasz Kosmaty const result = Localization.region; 119d1736fc2SHein Rutjes if (Platform.OS !== 'web' || result) { 120d1736fc2SHein Rutjes validateString(result); 121f2c6b866SŁukasz Kosmaty } 122d1736fc2SHein Rutjes }); 123d1736fc2SHein Rutjes t.it('Gets the locale', async () => { 124d1736fc2SHein Rutjes validateString(Localization.locale); 125740b3867SJames Ide }); 126740b3867SJames Ide t.it('Gets the preferred locales', async () => { 127ad26c082SEvan Bacon const result = Localization.locales; 128d1736fc2SHein Rutjes validateStringArray(result); 129ad26c082SEvan Bacon t.expect(result.length > 0).toBe(true); 130ad26c082SEvan Bacon t.expect(result[0]).toBe(Localization.locale); 131740b3867SJames Ide }); 132740b3867SJames Ide t.it('Gets ISO currency codes', async () => { 133ad26c082SEvan Bacon const result = Localization.isoCurrencyCodes; 134d1736fc2SHein Rutjes validateStringArray(result); 135d1736fc2SHein Rutjes result.map(validateString); 136740b3867SJames Ide }); 137d1736fc2SHein Rutjes t.it('Gets the timezone', async () => { 138ad26c082SEvan Bacon const result = Localization.timezone; 139d1736fc2SHein Rutjes if (result || Platform.OS !== 'web') { 140d1736fc2SHein Rutjes validateString(Localization.timezone); 141f1fde1fbSEvan Bacon } 142d1736fc2SHein Rutjes }); 143d1736fc2SHein Rutjes t.it('Gets the layout direction (ltr only)', async () => { 144ad26c082SEvan Bacon const result = Localization.isRTL; 145d1736fc2SHein Rutjes t.expect(typeof result).toBe('boolean'); 146ad26c082SEvan Bacon t.expect(result).toBe(false); 147ad26c082SEvan Bacon }); 148d1736fc2SHein Rutjes t.it('Gets the measurement system (metric)', async () => { 149d1736fc2SHein Rutjes const result = Localization.isMetric; 150d1736fc2SHein Rutjes t.expect(typeof result).toBe('boolean'); 151d1736fc2SHein Rutjes }); 152d1736fc2SHein Rutjes t.it('Gets the decimal separator', async () => { 153d1736fc2SHein Rutjes validateString(Localization.decimalSeparator); 154d1736fc2SHein Rutjes }); 155d1736fc2SHein Rutjes t.it('Gets the grouping separator', async () => { 156d1736fc2SHein Rutjes const result = Localization.decimalSeparator; 157d1736fc2SHein Rutjes t.expect(result).toBeDefined(); 158d1736fc2SHein Rutjes t.expect(typeof result).toBe('string'); 159d1736fc2SHein Rutjes }); 160d1736fc2SHein Rutjes if (Platform.OS !== 'web') { 161d1736fc2SHein Rutjes t.it('Gets the currency', async () => { 162d1736fc2SHein Rutjes validateString(Localization.currency); 163d1736fc2SHein Rutjes }); 164d1736fc2SHein Rutjes } 165ad26c082SEvan Bacon }); 166ad26c082SEvan Bacon 167ad26c082SEvan Bacon t.describe(`Localization works with i18n-js`, () => { 168ad26c082SEvan Bacon i18n.locale = Localization.locale; 16967f55e2bSStanisław Chmiela i18n.translations = { en, fr, pl }; 170ad26c082SEvan Bacon i18n.missingTranslationPrefix = 'EE: '; 171ad26c082SEvan Bacon i18n.fallbacks = true; 172ad26c082SEvan Bacon 17367f55e2bSStanisław Chmiela t.it('expect language to match strings (en, pl, fr supported)', async () => { 17467f55e2bSStanisław Chmiela const target = 'good'; 175ad26c082SEvan Bacon 176ad26c082SEvan Bacon i18n.locale = Localization.locale; 177ad26c082SEvan Bacon 178ad26c082SEvan Bacon const expoPredictedLangTag = Localization.locale.split('-')[0]; 179ad26c082SEvan Bacon const translation = i18n.translations[expoPredictedLangTag]; 180ad26c082SEvan Bacon 181ad26c082SEvan Bacon t.expect(translation[target]).toBe(i18n.t(target)); 182ad26c082SEvan Bacon }); 183ad26c082SEvan Bacon }); 184740b3867SJames Ide} 185