1import fs from 'fs';
2import { vol } from 'memfs';
3import path from 'path';
4
5import {
6  getApplicationTargetNameForSchemeAsync,
7  getArchiveBuildConfigurationForSchemeAsync,
8  getRunnableSchemesFromXcodeproj,
9} from '../BuildScheme';
10
11const fsReal = jest.requireActual('fs') as typeof fs;
12
13jest.mock('fs');
14
15describe(getRunnableSchemesFromXcodeproj, () => {
16  beforeAll(async () => {
17    vol.fromJSON(
18      {
19        'ios/project.xcodeproj/project.pbxproj': fsReal.readFileSync(
20          path.join(__dirname, 'fixtures/project-multitarget.pbxproj'),
21          'utf-8'
22        ),
23      },
24      '/app'
25    );
26  });
27
28  afterAll(() => {
29    vol.reset();
30  });
31  it(`parses for runnable schemes`, async () => {
32    const schemes = getRunnableSchemesFromXcodeproj('/app');
33    expect(schemes).toStrictEqual([
34      { name: 'multitarget', osType: 'iOS', type: 'com.apple.product-type.application' },
35      { name: 'shareextension', osType: 'iOS', type: 'com.apple.product-type.app-extension' },
36    ]);
37  });
38});
39
40describe(getApplicationTargetNameForSchemeAsync, () => {
41  describe('single build action entry', () => {
42    beforeAll(async () => {
43      vol.fromJSON(
44        {
45          'ios/testproject.xcodeproj/xcshareddata/xcschemes/testproject.xcscheme':
46            fsReal.readFileSync(path.join(__dirname, 'fixtures/testproject.xcscheme'), 'utf-8'),
47        },
48        '/app'
49      );
50    });
51
52    afterAll(() => {
53      vol.reset();
54    });
55
56    it('returns the target name for existing scheme', async () => {
57      const target = await getApplicationTargetNameForSchemeAsync('/app', 'testproject');
58      expect(target).toBe('testproject');
59    });
60
61    it('throws if the scheme does not exist', async () => {
62      await expect(() =>
63        getApplicationTargetNameForSchemeAsync('/app', 'nonexistentscheme')
64      ).rejects.toThrow(/does not exist/);
65    });
66  });
67  describe('multiple build action entries', () => {
68    beforeAll(async () => {
69      vol.fromJSON(
70        {
71          'ios/testproject.xcodeproj/xcshareddata/xcschemes/testproject.xcscheme':
72            fsReal.readFileSync(path.join(__dirname, 'fixtures/testproject-2.xcscheme'), 'utf-8'),
73        },
74        '/app'
75      );
76    });
77
78    afterAll(() => {
79      vol.reset();
80    });
81
82    it('returns the target name for existing scheme', async () => {
83      const target = await getApplicationTargetNameForSchemeAsync('/app', 'testproject');
84      expect(target).toBe('testproject');
85    });
86
87    it('throws if the scheme does not exist', async () => {
88      await expect(() =>
89        getApplicationTargetNameForSchemeAsync('/app', 'nonexistentscheme')
90      ).rejects.toThrow(/does not exist/);
91    });
92  });
93});
94
95describe(getArchiveBuildConfigurationForSchemeAsync, () => {
96  beforeAll(async () => {
97    vol.fromJSON(
98      {
99        'ios/testproject.xcodeproj/xcshareddata/xcschemes/testproject.xcscheme':
100          fsReal.readFileSync(path.join(__dirname, 'fixtures/testproject.xcscheme'), 'utf-8'),
101      },
102      '/app'
103    );
104  });
105
106  afterAll(() => {
107    vol.reset();
108  });
109
110  it('returns build configuration name for existing scheme', async () => {
111    const buildConfiguration = await getArchiveBuildConfigurationForSchemeAsync(
112      '/app',
113      'testproject'
114    );
115    expect(buildConfiguration).toBe('Release');
116  });
117
118  it('throws if the scheme does not exist', async () => {
119    await expect(() =>
120      getArchiveBuildConfigurationForSchemeAsync('/app', 'nonexistentscheme')
121    ).rejects.toThrow(/does not exist/);
122  });
123});
124