1import i18n from 'i18n-js'; 2import { mockProperty, unmockAllProperties } from 'jest-expo'; 3 4import ExpoLocalization from '../ExpoLocalization'; 5import * as Localization from '../Localization'; 6 7const en = { 8 good: 'good', 9 morning: 'morning', 10}; 11 12const fr = { 13 good: 'bien', 14 morning: 'matin', 15}; 16 17const pl = { 18 good: 'dobry', 19 morning: 'rano', 20}; 21 22const fakeLocalization = { 23 locale: 'en-US', 24 locales: ['en-US', 'fr'], 25 timezone: 'Etc/UTC', 26 isoCurrencyCodes: [], 27 region: 'US', 28 isRTL: false, 29 isMetric: false, 30 currency: 'USD', 31 decimalSeparator: '.', 32 digitGroupingSeparator: ',', 33}; 34 35beforeEach(() => { 36 for (const property of Object.keys(fakeLocalization)) { 37 mockProperty(ExpoLocalization, property, fakeLocalization[property]); 38 mockProperty(Localization, property, fakeLocalization[property]); 39 } 40 mockProperty( 41 ExpoLocalization, 42 'getLocalizationAsync', 43 jest.fn(async () => fakeLocalization) 44 ); 45}); 46 47afterEach(() => { 48 unmockAllProperties(); 49}); 50 51function validateString(result) { 52 expect(typeof result).toBe('string'); 53 expect(result.length).toBeGreaterThan(0); 54} 55 56function validateStringArray(result) { 57 expect(result).toBeDefined(); 58 expect(Array.isArray(result)).toBe(true); 59} 60 61describe(`Localization methods`, () => { 62 it(`expect async to return locale`, async () => { 63 const { 64 currency, 65 decimalSeparator, 66 digitGroupingSeparator, 67 isoCurrencyCodes, 68 isMetric, 69 isRTL, 70 locale, 71 locales, 72 timezone, 73 region, 74 } = await Localization.getLocalizationAsync(); 75 76 validateString(locale); 77 validateString(timezone); 78 validateString(region); 79 validateStringArray(isoCurrencyCodes); 80 validateStringArray(locales); 81 expect(locales[0]).toBe(Localization.locale); 82 expect(typeof isRTL).toBe('boolean'); 83 expect(typeof isMetric).toBe('boolean'); 84 validateString(decimalSeparator); 85 validateString(digitGroupingSeparator); 86 validateString(currency); 87 }); 88}); 89 90describe(`Localization defines constants`, () => { 91 it('Gets the region', async () => { 92 validateString(Localization.region); 93 }); 94 it('Gets the locale', async () => { 95 validateString(Localization.locale); 96 }); 97 it('Gets the preferred locales', async () => { 98 const result = Localization.locales; 99 validateStringArray(result); 100 expect(result.length > 0).toBe(true); 101 expect(result[0]).toBe(Localization.locale); 102 }); 103 it('Gets ISO currency codes', async () => { 104 const result = Localization.isoCurrencyCodes; 105 validateStringArray(result); 106 result.forEach(validateString); 107 }); 108 it('Gets the timezone', async () => { 109 validateString(Localization.timezone); 110 }); 111 it('Gets the layout direction (ltr only)', async () => { 112 const result = Localization.isRTL; 113 expect(typeof result).toBe('boolean'); 114 expect(result).toBe(false); 115 }); 116 it('Gets the measurement system (metric)', async () => { 117 const result = Localization.isMetric; 118 expect(typeof result).toBe('boolean'); 119 }); 120 it('Gets the decimal separator', async () => { 121 validateString(Localization.decimalSeparator); 122 }); 123 it('Gets the digit grouping separator', async () => { 124 const result = Localization.digitGroupingSeparator; 125 expect(result).toBeDefined(); 126 expect(typeof result).toBe('string'); 127 }); 128 it('Gets the currency', async () => { 129 validateString(Localization.currency); 130 }); 131}); 132 133describe(`Localization works with i18n-js`, () => { 134 i18n.locale = Localization.locale; 135 i18n.translations = { en, fr, pl }; 136 i18n.missingTranslationPrefix = 'EE: '; 137 i18n.fallbacks = true; 138 139 it(`expect language to match strings (en, pl, fr supported)`, async () => { 140 const target = 'good'; 141 142 i18n.locale = Localization.locale; 143 144 const expoPredictedLangTag = Localization.locale.split('-')[0]; 145 const translation = i18n.translations[expoPredictedLangTag]; 146 147 expect(translation[target]).toBe(i18n.t(target)); 148 }); 149}); 150