1082815dcSEvan Baconimport type { ExpoConfig } from '@expo/config-types';
2082815dcSEvan Baconimport fs from 'fs';
3082815dcSEvan Baconimport { vol } from 'memfs';
4082815dcSEvan Bacon
5*ed3bd27bSEvan Baconimport rnFixture from '../../plugins/__tests__/fixtures/react-native-project';
6082815dcSEvan Baconimport { getName, setDisplayName, setName, setProductName } from '../Name';
7082815dcSEvan Baconimport { getPbxproj, isBuildConfig, isNotComment } from '../utils/Xcodeproj';
8082815dcSEvan Bacon
9082815dcSEvan Baconjest.mock('fs');
10082815dcSEvan Bacon
11082815dcSEvan Bacondescribe(getName, () => {
12082815dcSEvan Bacon  it(`returns null if no bundleIdentifier is provided`, () => {
13082815dcSEvan Bacon    expect(getName({} as any)).toBe(null);
14082815dcSEvan Bacon  });
15082815dcSEvan Bacon
16082815dcSEvan Bacon  it(`returns the name if provided`, () => {
17082815dcSEvan Bacon    expect(getName({ name: 'Some iOS app' })).toBe('Some iOS app');
18082815dcSEvan Bacon  });
19082815dcSEvan Bacon});
20082815dcSEvan Bacondescribe(setDisplayName, () => {
21082815dcSEvan Bacon  it(`sets the CFBundleDisplayName if name is given`, () => {
22082815dcSEvan Bacon    expect(setDisplayName({ name: 'Expo app' }, {})).toMatchObject({
23082815dcSEvan Bacon      CFBundleDisplayName: 'Expo app',
24082815dcSEvan Bacon    });
25082815dcSEvan Bacon  });
26082815dcSEvan Bacon});
27082815dcSEvan Bacondescribe(setName, () => {
28082815dcSEvan Bacon  it(`makes no changes to the infoPlist no name is provided`, () => {
29082815dcSEvan Bacon    expect(setName({} as any, {})).toMatchObject({});
30082815dcSEvan Bacon  });
31082815dcSEvan Bacon});
32082815dcSEvan Bacondescribe(setProductName, () => {
33082815dcSEvan Bacon  const projectRoot = '/';
34082815dcSEvan Bacon  beforeAll(async () => {
35082815dcSEvan Bacon    vol.fromJSON(
36082815dcSEvan Bacon      {
37*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
38*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
39082815dcSEvan Bacon        'ios/testproject/AppDelegate.m': '',
40082815dcSEvan Bacon      },
41082815dcSEvan Bacon      projectRoot
42082815dcSEvan Bacon    );
43082815dcSEvan Bacon  });
44082815dcSEvan Bacon
45082815dcSEvan Bacon  afterAll(() => {
46082815dcSEvan Bacon    vol.reset();
47082815dcSEvan Bacon  });
48082815dcSEvan Bacon
49082815dcSEvan Bacon  it(`sets the iOS PRODUCT_NAME value`, () => {
50082815dcSEvan Bacon    for (const [input, output] of [
51082815dcSEvan Bacon      ['My Cool Thing', `"MyCoolThing"`],
52082815dcSEvan Bacon      ['h"&<world/>��', `"hworld"`],
53082815dcSEvan Bacon    ]) {
54082815dcSEvan Bacon      // Ensure the value can be parsed and written.
55082815dcSEvan Bacon      const project = setProductNameForRoot({ name: input, slug: '' }, projectRoot);
56082815dcSEvan Bacon      expect(
57082815dcSEvan Bacon        Object.entries(project.pbxXCBuildConfigurationSection())
58082815dcSEvan Bacon          .filter(isNotComment)
59082815dcSEvan Bacon          // @ts-ignore
60082815dcSEvan Bacon          .filter(isBuildConfig)[0][1]?.buildSettings?.PRODUCT_NAME
61082815dcSEvan Bacon        // Ensure the value is wrapped in quotes.
62082815dcSEvan Bacon      ).toBe(output);
63082815dcSEvan Bacon    }
64082815dcSEvan Bacon  });
65082815dcSEvan Bacon});
66082815dcSEvan Bacon
67082815dcSEvan Baconfunction setProductNameForRoot(config: ExpoConfig, projectRoot: string) {
68082815dcSEvan Bacon  let project = getPbxproj(projectRoot);
69082815dcSEvan Bacon  project = setProductName(config, project);
70082815dcSEvan Bacon  fs.writeFileSync(project.filepath, project.writeSync());
71082815dcSEvan Bacon  return project;
72082815dcSEvan Bacon}
73