1082815dcSEvan Baconimport * as fs from 'fs';
2082815dcSEvan Baconimport { vol } from 'memfs';
3082815dcSEvan Bacon
4082815dcSEvan Baconimport { XcodeProject } from '../../Plugin.types';
5*ed3bd27bSEvan Baconimport rnFixture from '../../plugins/__tests__/fixtures/react-native-project';
6082815dcSEvan Baconimport * as WarningAggregator from '../../utils/warnings';
7082815dcSEvan Baconimport { setBitcodeWithConfig } from '../Bitcode';
8082815dcSEvan Baconimport { getPbxproj, isNotComment } from '../utils/Xcodeproj';
9082815dcSEvan Bacon
10082815dcSEvan Baconjest.mock('fs');
11082815dcSEvan Baconjest.mock('../../utils/warnings');
12082815dcSEvan Bacon
13082815dcSEvan Bacondescribe(setBitcodeWithConfig, () => {
14082815dcSEvan Bacon  const projectRoot = '/tablet';
15082815dcSEvan Bacon  beforeEach(async () => {
16082815dcSEvan Bacon    vol.fromJSON(
17082815dcSEvan Bacon      {
18*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
19*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
20082815dcSEvan Bacon        'ios/testproject/AppDelegate.m': '',
21082815dcSEvan Bacon      },
22082815dcSEvan Bacon      projectRoot
23082815dcSEvan Bacon    );
24082815dcSEvan Bacon  });
25082815dcSEvan Bacon
26082815dcSEvan Bacon  afterEach(() => {
27082815dcSEvan Bacon    vol.reset();
28082815dcSEvan Bacon  });
29082815dcSEvan Bacon
30082815dcSEvan Bacon  it('defaults to not modifying the bitcode settings', async () => {
31082815dcSEvan Bacon    setBitcodeEnabledForRoot({ ios: {} }, projectRoot, validateDefaultBitcode);
32082815dcSEvan Bacon  });
33082815dcSEvan Bacon
34082815dcSEvan Bacon  it('enables bitcode for everything', async () => {
35082815dcSEvan Bacon    setBitcodeEnabledForRoot({ ios: { bitcode: true } }, projectRoot, (project) => {
36082815dcSEvan Bacon      const configurations = getConfigurations(project);
37082815dcSEvan Bacon      for (const [, configuration] of configurations) {
38082815dcSEvan Bacon        expect(configuration.buildSettings.ENABLE_BITCODE).toBe('YES');
39082815dcSEvan Bacon      }
40082815dcSEvan Bacon    });
41082815dcSEvan Bacon  });
42082815dcSEvan Bacon
43082815dcSEvan Bacon  it('disables bitcode for everything', async () => {
44082815dcSEvan Bacon    setBitcodeEnabledForRoot({ ios: { bitcode: false } }, projectRoot, (project) => {
45082815dcSEvan Bacon      const configurations = getConfigurations(project);
46082815dcSEvan Bacon      for (const [, configuration] of configurations) {
47082815dcSEvan Bacon        expect(configuration.buildSettings.ENABLE_BITCODE).toBe('NO');
48082815dcSEvan Bacon      }
49082815dcSEvan Bacon    });
50082815dcSEvan Bacon  });
51082815dcSEvan Bacon
52082815dcSEvan Bacon  it('enables bitcode on specific configuration', async () => {
53082815dcSEvan Bacon    setBitcodeEnabledForRoot({ ios: { bitcode: 'Debug' } }, projectRoot, (project) => {
54082815dcSEvan Bacon      const configurations = getConfigurations(project);
55082815dcSEvan Bacon      for (const [, configuration] of configurations) {
56082815dcSEvan Bacon        // ensure all others are disabled
57082815dcSEvan Bacon        expect(configuration.buildSettings.ENABLE_BITCODE).toBe(
58082815dcSEvan Bacon          configuration.name === 'Debug' ? 'YES' : 'NO'
59082815dcSEvan Bacon        );
60082815dcSEvan Bacon      }
61082815dcSEvan Bacon    });
62082815dcSEvan Bacon  });
63082815dcSEvan Bacon
64082815dcSEvan Bacon  it('warns when enabling bitcode on an invalid configuration', async () => {
65082815dcSEvan Bacon    setBitcodeEnabledForRoot({ ios: { bitcode: 'Bacon' } }, projectRoot, validateDefaultBitcode);
66082815dcSEvan Bacon    expect(WarningAggregator.addWarningIOS).toHaveBeenLastCalledWith(
67082815dcSEvan Bacon      'ios.bitcode',
68082815dcSEvan Bacon      'No configuration named "Bacon". Expected one of: "Debug", "Release".'
69082815dcSEvan Bacon    );
70082815dcSEvan Bacon  });
71082815dcSEvan Bacon});
72082815dcSEvan Bacon
73082815dcSEvan Baconfunction getConfigurations(project: XcodeProject) {
74082815dcSEvan Bacon  return Object.entries(project.pbxXCBuildConfigurationSection()).filter(isNotComment);
75082815dcSEvan Bacon}
76082815dcSEvan Bacon
77082815dcSEvan Baconfunction setBitcodeEnabledForRoot(
78082815dcSEvan Bacon  config: { ios?: { bitcode?: boolean | string } & any },
79082815dcSEvan Bacon  projectRoot: string,
80082815dcSEvan Bacon  validate: (project: XcodeProject) => void
81082815dcSEvan Bacon) {
82082815dcSEvan Bacon  let project = getPbxproj(projectRoot);
83082815dcSEvan Bacon  project = setBitcodeWithConfig(config, { project });
84082815dcSEvan Bacon  validate(project);
85082815dcSEvan Bacon  fs.writeFileSync(project.filepath, project.writeSync());
86082815dcSEvan Bacon}
87082815dcSEvan Bacon
88082815dcSEvan Baconfunction validateDefaultBitcode(project: XcodeProject) {
89082815dcSEvan Bacon  const configurations = getConfigurations(project);
90082815dcSEvan Bacon  for (const [id, configuration] of configurations) {
91082815dcSEvan Bacon    expect(configuration.buildSettings.ENABLE_BITCODE).toBe(
92082815dcSEvan Bacon      // Ensure nothing changed.
93082815dcSEvan Bacon      {
94082815dcSEvan Bacon        '13B07F941A680F5B00A75B9A': 'NO',
95082815dcSEvan Bacon        '13B07F951A680F5B00A75B9A': undefined,
96082815dcSEvan Bacon        '83CBBA201A601CBA00E9B192': undefined,
97082815dcSEvan Bacon        '83CBBA211A601CBA00E9B192': undefined,
98082815dcSEvan Bacon      }[id]
99082815dcSEvan Bacon    );
100082815dcSEvan Bacon  }
101082815dcSEvan Bacon}
102