1*c4ef02aeSEvan Baconimport path from 'path';
2*c4ef02aeSEvan Bacon
3*c4ef02aeSEvan Baconimport {
4*c4ef02aeSEvan Bacon  extractEnvVariableFromBuild,
5*c4ef02aeSEvan Bacon  getProcessOptions,
6*c4ef02aeSEvan Bacon  getXcodeBuildArgsAsync,
7*c4ef02aeSEvan Bacon  _assertXcodeBuildResults,
8*c4ef02aeSEvan Bacon} from '../XcodeBuild';
9*c4ef02aeSEvan Baconimport { ensureDeviceIsCodeSignedForDeploymentAsync } from '../codeSigning/configureCodeSigning';
10*c4ef02aeSEvan Bacon
11*c4ef02aeSEvan Baconjest.mock('../codeSigning/configureCodeSigning');
12*c4ef02aeSEvan Bacon
13*c4ef02aeSEvan Baconconst fs = jest.requireActual('fs') as typeof import('fs');
14*c4ef02aeSEvan Bacon
15*c4ef02aeSEvan Baconconst asMock = <T extends (...args: any[]) => any>(fn: T): jest.MockedFunction<T> =>
16*c4ef02aeSEvan Bacon  fn as jest.MockedFunction<T>;
17*c4ef02aeSEvan Bacon
18*c4ef02aeSEvan Bacondescribe(getXcodeBuildArgsAsync, () => {
19*c4ef02aeSEvan Bacon  it(`returns fully qualified arguments for a build`, async () => {
20*c4ef02aeSEvan Bacon    asMock(ensureDeviceIsCodeSignedForDeploymentAsync).mockResolvedValueOnce('my-dev-team');
21*c4ef02aeSEvan Bacon    await expect(
22*c4ef02aeSEvan Bacon      getXcodeBuildArgsAsync({
23*c4ef02aeSEvan Bacon        projectRoot: '/path/to/project',
24*c4ef02aeSEvan Bacon        buildCache: false,
25*c4ef02aeSEvan Bacon        configuration: 'Debug',
26*c4ef02aeSEvan Bacon        isSimulator: false,
27*c4ef02aeSEvan Bacon        scheme: 'project-with-build-configurations',
28*c4ef02aeSEvan Bacon        device: { udid: 'demo-udid', name: 'foobar' },
29*c4ef02aeSEvan Bacon        xcodeProject: {
30*c4ef02aeSEvan Bacon          isWorkspace: true,
31*c4ef02aeSEvan Bacon          name: 'demo-project',
32*c4ef02aeSEvan Bacon        },
33*c4ef02aeSEvan Bacon      })
34*c4ef02aeSEvan Bacon    ).resolves.toEqual([
35*c4ef02aeSEvan Bacon      '-workspace',
36*c4ef02aeSEvan Bacon      'demo-project',
37*c4ef02aeSEvan Bacon      '-configuration',
38*c4ef02aeSEvan Bacon      'Debug',
39*c4ef02aeSEvan Bacon      '-scheme',
40*c4ef02aeSEvan Bacon      'project-with-build-configurations',
41*c4ef02aeSEvan Bacon      '-destination',
42*c4ef02aeSEvan Bacon      'id=demo-udid',
43*c4ef02aeSEvan Bacon      'DEVELOPMENT_TEAM=my-dev-team',
44*c4ef02aeSEvan Bacon      '-allowProvisioningUpdates',
45*c4ef02aeSEvan Bacon      '-allowProvisioningDeviceRegistration',
46*c4ef02aeSEvan Bacon      'clean',
47*c4ef02aeSEvan Bacon      'build',
48*c4ef02aeSEvan Bacon    ]);
49*c4ef02aeSEvan Bacon  });
50*c4ef02aeSEvan Bacon  it(`returns standard simulator arguments`, async () => {
51*c4ef02aeSEvan Bacon    await expect(
52*c4ef02aeSEvan Bacon      getXcodeBuildArgsAsync({
53*c4ef02aeSEvan Bacon        projectRoot: '/path/to/project',
54*c4ef02aeSEvan Bacon        buildCache: true,
55*c4ef02aeSEvan Bacon        configuration: 'Release',
56*c4ef02aeSEvan Bacon        isSimulator: true,
57*c4ef02aeSEvan Bacon        scheme: 'project-with-build-configurations',
58*c4ef02aeSEvan Bacon        device: { udid: 'demo-udid', name: 'foobar' },
59*c4ef02aeSEvan Bacon        xcodeProject: {
60*c4ef02aeSEvan Bacon          isWorkspace: false,
61*c4ef02aeSEvan Bacon          name: 'demo-project',
62*c4ef02aeSEvan Bacon        },
63*c4ef02aeSEvan Bacon      })
64*c4ef02aeSEvan Bacon    ).resolves.toEqual([
65*c4ef02aeSEvan Bacon      '-project',
66*c4ef02aeSEvan Bacon      'demo-project',
67*c4ef02aeSEvan Bacon      '-configuration',
68*c4ef02aeSEvan Bacon      'Release',
69*c4ef02aeSEvan Bacon      '-scheme',
70*c4ef02aeSEvan Bacon      'project-with-build-configurations',
71*c4ef02aeSEvan Bacon      '-destination',
72*c4ef02aeSEvan Bacon      'id=demo-udid',
73*c4ef02aeSEvan Bacon    ]);
74*c4ef02aeSEvan Bacon    expect(ensureDeviceIsCodeSignedForDeploymentAsync).toBeCalledTimes(0);
75*c4ef02aeSEvan Bacon  });
76*c4ef02aeSEvan Bacon});
77*c4ef02aeSEvan Bacon
78*c4ef02aeSEvan Bacondescribe(extractEnvVariableFromBuild, () => {
79*c4ef02aeSEvan Bacon  const fixture = fs.readFileSync(path.join(__dirname, 'fixtures/xcodebuild.log'), 'utf8');
80*c4ef02aeSEvan Bacon  it(`gets env variables from build results`, async () => {
81*c4ef02aeSEvan Bacon    expect(extractEnvVariableFromBuild(fixture, 'APPLE_INTERNAL_LIBRARY_DIR')).toEqual([
82*c4ef02aeSEvan Bacon      '/AppleInternal/Library',
83*c4ef02aeSEvan Bacon    ]);
84*c4ef02aeSEvan Bacon    expect(extractEnvVariableFromBuild(fixture, 'AVAILABLE_PLATFORMS')[0]).toEqual(
85*c4ef02aeSEvan Bacon      'appletvos\\ appletvsimulator\\ driverkit\\ iphoneos\\ iphonesimulator\\ macosx\\ watchos\\ watchsimulator'
86*c4ef02aeSEvan Bacon    );
87*c4ef02aeSEvan Bacon    expect(
88*c4ef02aeSEvan Bacon      extractEnvVariableFromBuild(fixture, 'CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING')[0]
89*c4ef02aeSEvan Bacon    ).toEqual('YES');
90*c4ef02aeSEvan Bacon    expect(extractEnvVariableFromBuild(fixture, 'CONFIGURATION_BUILD_DIR')[0]).toEqual(
91*c4ef02aeSEvan Bacon      '/Users/evanbacon/Library/Developer/Xcode/DerivedData/basicexpoapp-bhxfzfgdguosemfinvpzbtpjpnji/Build/Products/Debug-iphonesimulator/expo-dev-launcher'
92*c4ef02aeSEvan Bacon    );
93*c4ef02aeSEvan Bacon    expect(extractEnvVariableFromBuild(fixture, 'UNLOCALIZED_RESOURCES_FOLDER_PATH')[0]).toEqual(
94*c4ef02aeSEvan Bacon      'basicexpoapp.app'
95*c4ef02aeSEvan Bacon    );
96*c4ef02aeSEvan Bacon  });
97*c4ef02aeSEvan Bacon});
98*c4ef02aeSEvan Bacon
99*c4ef02aeSEvan Baconxdescribe(getProcessOptions, () => {
100*c4ef02aeSEvan Bacon  it(`gets process option when a packager is enabled`, async () => {
101*c4ef02aeSEvan Bacon    expect(
102*c4ef02aeSEvan Bacon      getProcessOptions({
103*c4ef02aeSEvan Bacon        packager: true,
104*c4ef02aeSEvan Bacon        shouldSkipInitialBundling: true,
105*c4ef02aeSEvan Bacon        terminal: 'foobar',
106*c4ef02aeSEvan Bacon        port: 3000,
107*c4ef02aeSEvan Bacon      })
108*c4ef02aeSEvan Bacon    ).toEqual({
109*c4ef02aeSEvan Bacon      env: {},
110*c4ef02aeSEvan Bacon    });
111*c4ef02aeSEvan Bacon  });
112*c4ef02aeSEvan Bacon});
113*c4ef02aeSEvan Bacon
114*c4ef02aeSEvan Bacondescribe(_assertXcodeBuildResults, () => {
115*c4ef02aeSEvan Bacon  it(`asserts invalid Xcode version`, () => {
116*c4ef02aeSEvan Bacon    expect(() =>
117*c4ef02aeSEvan Bacon      _assertXcodeBuildResults(
118*c4ef02aeSEvan Bacon        70,
119*c4ef02aeSEvan Bacon        'foobar',
120*c4ef02aeSEvan Bacon        fs.readFileSync(path.resolve(__dirname, './fixtures/outdated-xcode-error.log'), 'utf8'),
121*c4ef02aeSEvan Bacon        { name: 'name' },
122*c4ef02aeSEvan Bacon        './output.log'
123*c4ef02aeSEvan Bacon      )
124*c4ef02aeSEvan Bacon    ).toThrow(
125*c4ef02aeSEvan Bacon      'This operation can fail if the version of the OS on the device is newer than the version of Xcode that is running.'
126*c4ef02aeSEvan Bacon    );
127*c4ef02aeSEvan Bacon  });
128*c4ef02aeSEvan Bacon});
129