1082815dcSEvan Baconimport * as fs from 'fs'; 2082815dcSEvan Baconimport { vol } from 'memfs'; 3082815dcSEvan Bacon 4*8a424bebSJames Ideimport { getDirFromFS } from './utils/getDirFromFS'; 5ed3bd27bSEvan Baconimport rnFixture from '../../plugins/__tests__/fixtures/react-native-project'; 6082815dcSEvan Baconimport * as WarningAggregator from '../../utils/warnings'; 7082815dcSEvan Baconimport { getLocales, setLocalesAsync } from '../Locales'; 8082815dcSEvan Baconimport { getPbxproj } from '../utils/Xcodeproj'; 9082815dcSEvan Bacon 10082815dcSEvan Baconjest.mock('fs'); 11082815dcSEvan Baconjest.mock('../../utils/warnings'); 12082815dcSEvan Bacon 13082815dcSEvan Bacondescribe('iOS Locales', () => { 14082815dcSEvan Bacon it(`returns null if no values are provided`, () => { 15082815dcSEvan Bacon expect(getLocales({})).toBeNull(); 16082815dcSEvan Bacon }); 17082815dcSEvan Bacon 18082815dcSEvan Bacon it(`returns the locales object`, () => { 19082815dcSEvan Bacon expect( 20082815dcSEvan Bacon getLocales({ 21082815dcSEvan Bacon locales: {}, 22082815dcSEvan Bacon }) 23082815dcSEvan Bacon ).toStrictEqual({}); 24082815dcSEvan Bacon }); 25082815dcSEvan Bacon}); 26082815dcSEvan Bacon 27082815dcSEvan Bacondescribe('e2e: iOS locales', () => { 28082815dcSEvan Bacon const projectRoot = '/app'; 29082815dcSEvan Bacon beforeAll(async () => { 30082815dcSEvan Bacon vol.fromJSON( 31082815dcSEvan Bacon { 32ed3bd27bSEvan Bacon 'ios/testproject.xcodeproj/project.pbxproj': 33ed3bd27bSEvan Bacon rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'], 34082815dcSEvan Bacon 'ios/testproject/AppDelegate.m': '', 35082815dcSEvan Bacon 'lang/fr.json': JSON.stringify({ 36082815dcSEvan Bacon CFBundleDisplayName: 'french-name', 37082815dcSEvan Bacon }), 38082815dcSEvan Bacon }, 39082815dcSEvan Bacon projectRoot 40082815dcSEvan Bacon ); 41082815dcSEvan Bacon }); 42082815dcSEvan Bacon 43082815dcSEvan Bacon afterAll(() => { 44082815dcSEvan Bacon vol.reset(); 45082815dcSEvan Bacon }); 46082815dcSEvan Bacon 47082815dcSEvan Bacon it('writes all the image files expected', async () => { 48082815dcSEvan Bacon let project = getPbxproj(projectRoot); 49082815dcSEvan Bacon 50082815dcSEvan Bacon project = await setLocalesAsync( 51082815dcSEvan Bacon { 52082815dcSEvan Bacon locales: { 53082815dcSEvan Bacon fr: 'lang/fr.json', 54082815dcSEvan Bacon // doesn't exist 55082815dcSEvan Bacon xx: 'lang/xx.json', 56082815dcSEvan Bacon // partially support inlining the JSON so our Expo Config type doesn't conflict with the resolved manifest type. 57082815dcSEvan Bacon es: { CFBundleDisplayName: 'spanish-name' }, 58082815dcSEvan Bacon }, 59082815dcSEvan Bacon }, 60082815dcSEvan Bacon { project, projectRoot } 61082815dcSEvan Bacon ); 62082815dcSEvan Bacon // Sync the Xcode project with the changes. 63082815dcSEvan Bacon fs.writeFileSync(project.filepath, project.writeSync()); 64082815dcSEvan Bacon 65082815dcSEvan Bacon const after = getDirFromFS(vol.toJSON(), projectRoot); 66082815dcSEvan Bacon const locales = Object.keys(after).filter((value) => value.endsWith('InfoPlist.strings')); 67082815dcSEvan Bacon 68082815dcSEvan Bacon expect(locales.length).toBe(2); 69082815dcSEvan Bacon expect(after[locales[0]]).toMatchSnapshot(); 70082815dcSEvan Bacon // Test that the inlined locale is resolved. 71082815dcSEvan Bacon expect(after[locales[1]]).toMatch(/spanish-name/); 72082815dcSEvan Bacon // Test a warning is thrown for an invalid locale JSON file. 73082815dcSEvan Bacon expect(WarningAggregator.addWarningIOS).toHaveBeenCalledWith( 74082815dcSEvan Bacon 'locales.xx', 75082815dcSEvan Bacon 'Failed to parse JSON of locale file for language: xx', 76082815dcSEvan Bacon 'https://docs.expo.dev/distribution/app-stores/#localizing-your-ios-app' 77082815dcSEvan Bacon ); 78082815dcSEvan Bacon }); 79082815dcSEvan Bacon}); 80