1import type { ExpoConfig } from '@expo/config-types'; 2import fs from 'fs'; 3import { vol } from 'memfs'; 4 5import rnFixture from '../../plugins/__tests__/fixtures/react-native-project'; 6import { getName, setDisplayName, setName, setProductName } from '../Name'; 7import { getPbxproj, isBuildConfig, isNotComment } from '../utils/Xcodeproj'; 8 9jest.mock('fs'); 10 11describe(getName, () => { 12 it(`returns null if no bundleIdentifier is provided`, () => { 13 expect(getName({} as any)).toBe(null); 14 }); 15 16 it(`returns the name if provided`, () => { 17 expect(getName({ name: 'Some iOS app' })).toBe('Some iOS app'); 18 }); 19}); 20describe(setDisplayName, () => { 21 it(`sets the CFBundleDisplayName if name is given`, () => { 22 expect(setDisplayName({ name: 'Expo app' }, {})).toMatchObject({ 23 CFBundleDisplayName: 'Expo app', 24 }); 25 }); 26}); 27describe(setName, () => { 28 it(`makes no changes to the infoPlist no name is provided`, () => { 29 expect(setName({} as any, {})).toMatchObject({}); 30 }); 31}); 32describe(setProductName, () => { 33 const projectRoot = '/'; 34 beforeAll(async () => { 35 vol.fromJSON( 36 { 37 'ios/testproject.xcodeproj/project.pbxproj': 38 rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'], 39 'ios/testproject/AppDelegate.m': '', 40 }, 41 projectRoot 42 ); 43 }); 44 45 afterAll(() => { 46 vol.reset(); 47 }); 48 49 it(`sets the iOS PRODUCT_NAME value`, () => { 50 for (const [input, output] of [ 51 ['My Cool Thing', `"MyCoolThing"`], 52 ['h"&<world/>', `"hworld"`], 53 ]) { 54 // Ensure the value can be parsed and written. 55 const project = setProductNameForRoot({ name: input, slug: '' }, projectRoot); 56 expect( 57 Object.entries(project.pbxXCBuildConfigurationSection()) 58 .filter(isNotComment) 59 // @ts-ignore 60 .filter(isBuildConfig)[0][1]?.buildSettings?.PRODUCT_NAME 61 // Ensure the value is wrapped in quotes. 62 ).toBe(output); 63 } 64 }); 65}); 66 67function setProductNameForRoot(config: ExpoConfig, projectRoot: string) { 68 let project = getPbxproj(projectRoot); 69 project = setProductName(config, project); 70 fs.writeFileSync(project.filepath, project.writeSync()); 71 return project; 72} 73