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