1import * as fs from 'fs'; 2import { vol } from 'memfs'; 3 4import { XcodeProject } from '../../Plugin.types'; 5import rnFixture from '../../plugins/__tests__/fixtures/react-native-project'; 6import * as WarningAggregator from '../../utils/warnings'; 7import { setBitcodeWithConfig } from '../Bitcode'; 8import { getPbxproj, isNotComment } from '../utils/Xcodeproj'; 9 10jest.mock('fs'); 11jest.mock('../../utils/warnings'); 12 13describe(setBitcodeWithConfig, () => { 14 const projectRoot = '/tablet'; 15 beforeEach(async () => { 16 vol.fromJSON( 17 { 18 'ios/testproject.xcodeproj/project.pbxproj': 19 rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'], 20 'ios/testproject/AppDelegate.m': '', 21 }, 22 projectRoot 23 ); 24 }); 25 26 afterEach(() => { 27 vol.reset(); 28 }); 29 30 it('defaults to not modifying the bitcode settings', async () => { 31 setBitcodeEnabledForRoot({ ios: {} }, projectRoot, validateDefaultBitcode); 32 }); 33 34 it('enables bitcode for everything', async () => { 35 setBitcodeEnabledForRoot({ ios: { bitcode: true } }, projectRoot, (project) => { 36 const configurations = getConfigurations(project); 37 for (const [, configuration] of configurations) { 38 expect(configuration.buildSettings.ENABLE_BITCODE).toBe('YES'); 39 } 40 }); 41 }); 42 43 it('disables bitcode for everything', async () => { 44 setBitcodeEnabledForRoot({ ios: { bitcode: false } }, projectRoot, (project) => { 45 const configurations = getConfigurations(project); 46 for (const [, configuration] of configurations) { 47 expect(configuration.buildSettings.ENABLE_BITCODE).toBe('NO'); 48 } 49 }); 50 }); 51 52 it('enables bitcode on specific configuration', async () => { 53 setBitcodeEnabledForRoot({ ios: { bitcode: 'Debug' } }, projectRoot, (project) => { 54 const configurations = getConfigurations(project); 55 for (const [, configuration] of configurations) { 56 // ensure all others are disabled 57 expect(configuration.buildSettings.ENABLE_BITCODE).toBe( 58 configuration.name === 'Debug' ? 'YES' : 'NO' 59 ); 60 } 61 }); 62 }); 63 64 it('warns when enabling bitcode on an invalid configuration', async () => { 65 setBitcodeEnabledForRoot({ ios: { bitcode: 'Bacon' } }, projectRoot, validateDefaultBitcode); 66 expect(WarningAggregator.addWarningIOS).toHaveBeenLastCalledWith( 67 'ios.bitcode', 68 'No configuration named "Bacon". Expected one of: "Debug", "Release".' 69 ); 70 }); 71}); 72 73function getConfigurations(project: XcodeProject) { 74 return Object.entries(project.pbxXCBuildConfigurationSection()).filter(isNotComment); 75} 76 77function setBitcodeEnabledForRoot( 78 config: { ios?: { bitcode?: boolean | string } & any }, 79 projectRoot: string, 80 validate: (project: XcodeProject) => void 81) { 82 let project = getPbxproj(projectRoot); 83 project = setBitcodeWithConfig(config, { project }); 84 validate(project); 85 fs.writeFileSync(project.filepath, project.writeSync()); 86} 87 88function validateDefaultBitcode(project: XcodeProject) { 89 const configurations = getConfigurations(project); 90 for (const [id, configuration] of configurations) { 91 expect(configuration.buildSettings.ENABLE_BITCODE).toBe( 92 // Ensure nothing changed. 93 { 94 '13B07F941A680F5B00A75B9A': 'NO', 95 '13B07F951A680F5B00A75B9A': undefined, 96 '83CBBA201A601CBA00E9B192': undefined, 97 '83CBBA211A601CBA00E9B192': undefined, 98 }[id] 99 ); 100 } 101} 102