1082815dcSEvan Baconimport { vol } from 'memfs';
2082815dcSEvan Baconimport * as path from 'path';
3082815dcSEvan Bacon
4*ed3bd27bSEvan Baconimport rnFixture from '../../plugins/__tests__/fixtures/react-native-project';
5082815dcSEvan Baconimport { UnexpectedError } from '../../utils/errors';
6082815dcSEvan Baconimport * as WarningAggregator from '../../utils/warnings';
7082815dcSEvan Baconimport {
8082815dcSEvan Bacon  findSchemeNames,
9082815dcSEvan Bacon  getAllInfoPlistPaths,
10082815dcSEvan Bacon  getAppDelegate,
11082815dcSEvan Bacon  getXcodeProjectPath,
12082815dcSEvan Bacon} from '../Paths';
13082815dcSEvan Bacon
14082815dcSEvan Baconjest.mock('fs');
15082815dcSEvan Baconjest.mock('../../utils/warnings');
16082815dcSEvan Bacon
17082815dcSEvan Bacondescribe(findSchemeNames, () => {
18082815dcSEvan Bacon  afterEach(() => {
19082815dcSEvan Bacon    vol.reset();
20082815dcSEvan Bacon  });
21082815dcSEvan Bacon
22082815dcSEvan Bacon  it(`returns project path`, () => {
23082815dcSEvan Bacon    vol.fromJSON(
24082815dcSEvan Bacon      {
25082815dcSEvan Bacon        'ios/my-app.xcodeproj/xcshareddata/xcschemes/my-app.xcscheme': '',
26082815dcSEvan Bacon        'ios/my_app.xcodeproj/xcshareddata/xcschemes/my_app.xcscheme': '',
27082815dcSEvan Bacon        'ios/clientTests.xcodeproj/xcshareddata/xcschemes/client.beta.xcscheme': '',
28082815dcSEvan Bacon      },
29082815dcSEvan Bacon      '/'
30082815dcSEvan Bacon    );
31082815dcSEvan Bacon
32082815dcSEvan Bacon    expect(findSchemeNames('/')).toStrictEqual(['client.beta', 'my_app', 'my-app']);
33082815dcSEvan Bacon  });
34082815dcSEvan Bacon});
35082815dcSEvan Bacon
36082815dcSEvan Bacondescribe(getXcodeProjectPath, () => {
37082815dcSEvan Bacon  afterEach(() => {
38082815dcSEvan Bacon    vol.reset();
39082815dcSEvan Bacon  });
40082815dcSEvan Bacon
41082815dcSEvan Bacon  it(`returns project path`, () => {
42082815dcSEvan Bacon    vol.fromJSON(
43082815dcSEvan Bacon      {
44*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
45*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
46082815dcSEvan Bacon        'ios/Podfile': 'content',
47082815dcSEvan Bacon        'ios/TestPod.podspec': 'noop',
48082815dcSEvan Bacon        'ios/testproject/AppDelegate.m': '',
49082815dcSEvan Bacon      },
50082815dcSEvan Bacon      '/app'
51082815dcSEvan Bacon    );
52082815dcSEvan Bacon    expect(getXcodeProjectPath('/app')).toBe('/app/ios/testproject.xcodeproj');
53082815dcSEvan Bacon  });
54082815dcSEvan Bacon
55082815dcSEvan Bacon  it(`throws when no paths are found`, () => {
56082815dcSEvan Bacon    expect(() => getXcodeProjectPath('/none')).toThrow(UnexpectedError);
57082815dcSEvan Bacon  });
58082815dcSEvan Bacon
59082815dcSEvan Bacon  it(`warns when multiple paths are found`, () => {
60082815dcSEvan Bacon    vol.fromJSON(
61082815dcSEvan Bacon      {
62*ed3bd27bSEvan Bacon        'ios/otherproject.xcodeproj/project.pbxproj':
63*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
64*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
65*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
66082815dcSEvan Bacon        'ios/testproject/AppDelegate.m': '',
67082815dcSEvan Bacon      },
68082815dcSEvan Bacon      '/app'
69082815dcSEvan Bacon    );
70082815dcSEvan Bacon
71082815dcSEvan Bacon    expect(getXcodeProjectPath('/app')).toBe('/app/ios/otherproject.xcodeproj');
72082815dcSEvan Bacon    expect(WarningAggregator.addWarningIOS).toHaveBeenLastCalledWith(
73082815dcSEvan Bacon      'paths-xcodeproj',
74082815dcSEvan Bacon      'Found multiple *.xcodeproj file paths, using "ios/otherproject.xcodeproj". Ignored paths: ["ios/testproject.xcodeproj"]'
75082815dcSEvan Bacon    );
76082815dcSEvan Bacon  });
77082815dcSEvan Bacon
78082815dcSEvan Bacon  it(`selects xcodeproj based on alphabetical order, but picks direct children of ios directory first`, () => {
79082815dcSEvan Bacon    vol.fromJSON(
80082815dcSEvan Bacon      {
81*ed3bd27bSEvan Bacon        'ios/otherproject.xcodeproj/project.pbxproj':
82*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
83*ed3bd27bSEvan Bacon        'ios/aa/otherproject.xcodeproj/project.pbxproj':
84*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
85*ed3bd27bSEvan Bacon        'ios/botherproject.xcodeproj/project.pbxproj':
86*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
87*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
88*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
89082815dcSEvan Bacon        'ios/testproject/AppDelegate.m': '',
90082815dcSEvan Bacon      },
91082815dcSEvan Bacon      '/app'
92082815dcSEvan Bacon    );
93082815dcSEvan Bacon
94082815dcSEvan Bacon    expect(getXcodeProjectPath('/app')).toBe('/app/ios/botherproject.xcodeproj');
95082815dcSEvan Bacon    expect(WarningAggregator.addWarningIOS).toHaveBeenLastCalledWith(
96082815dcSEvan Bacon      'paths-xcodeproj',
97082815dcSEvan Bacon      'Found multiple *.xcodeproj file paths, using "ios/botherproject.xcodeproj". Ignored paths: ["ios/otherproject.xcodeproj","ios/testproject.xcodeproj","ios/aa/otherproject.xcodeproj"]'
98082815dcSEvan Bacon    );
99082815dcSEvan Bacon  });
100082815dcSEvan Bacon
101082815dcSEvan Bacon  it(`warns when multiple paths are found`, () => {
102082815dcSEvan Bacon    vol.fromJSON(
103082815dcSEvan Bacon      {
104*ed3bd27bSEvan Bacon        'ios/otherproject.xcodeproj/project.pbxproj':
105*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
106*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
107*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
108082815dcSEvan Bacon        'ios/testproject/AppDelegate.m': '',
109082815dcSEvan Bacon      },
110082815dcSEvan Bacon      '/app'
111082815dcSEvan Bacon    );
112082815dcSEvan Bacon
113082815dcSEvan Bacon    expect(getXcodeProjectPath('/app')).toBe('/app/ios/otherproject.xcodeproj');
114082815dcSEvan Bacon    expect(WarningAggregator.addWarningIOS).toHaveBeenLastCalledWith(
115082815dcSEvan Bacon      'paths-xcodeproj',
116082815dcSEvan Bacon      'Found multiple *.xcodeproj file paths, using "ios/otherproject.xcodeproj". Ignored paths: ["ios/testproject.xcodeproj"]'
117082815dcSEvan Bacon    );
118082815dcSEvan Bacon  });
119082815dcSEvan Bacon  it(`ignores xcodeproj outside of the ios directory`, () => {
120082815dcSEvan Bacon    vol.fromJSON(
121082815dcSEvan Bacon      {
122*ed3bd27bSEvan Bacon        'lib/testproject.xcodeproj/project.pbxproj':
123*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
124082815dcSEvan Bacon      },
125082815dcSEvan Bacon      '/app'
126082815dcSEvan Bacon    );
127082815dcSEvan Bacon    expect(() => getXcodeProjectPath('/app')).toThrow(UnexpectedError);
128082815dcSEvan Bacon  });
129082815dcSEvan Bacon});
130082815dcSEvan Bacon
131082815dcSEvan Bacondescribe(getAppDelegate, () => {
132082815dcSEvan Bacon  beforeEach(() => {
133082815dcSEvan Bacon    vol.reset();
134082815dcSEvan Bacon  });
135082815dcSEvan Bacon  afterAll(() => {
136082815dcSEvan Bacon    vol.reset();
137082815dcSEvan Bacon  });
138082815dcSEvan Bacon
139082815dcSEvan Bacon  it(`returns objc path`, () => {
140082815dcSEvan Bacon    vol.fromJSON(
141082815dcSEvan Bacon      {
142*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
143*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
144082815dcSEvan Bacon        'ios/Podfile': 'content',
145082815dcSEvan Bacon        'ios/TestPod.podspec': 'noop',
146082815dcSEvan Bacon        'ios/testproject/AppDelegate.m': '',
147082815dcSEvan Bacon        'ios/testproject/AppDelegate.h': '',
148082815dcSEvan Bacon      },
149082815dcSEvan Bacon      '/objc'
150082815dcSEvan Bacon    );
151082815dcSEvan Bacon
152082815dcSEvan Bacon    expect(getAppDelegate('/objc')).toStrictEqual({
153082815dcSEvan Bacon      contents: '',
154082815dcSEvan Bacon      path: '/objc/ios/testproject/AppDelegate.m',
155082815dcSEvan Bacon      language: 'objc',
156082815dcSEvan Bacon    });
157082815dcSEvan Bacon  });
158082815dcSEvan Bacon
159082815dcSEvan Bacon  it(`returns C++ (objcpp) path`, () => {
160*ed3bd27bSEvan Bacon    vol.fromJSON(rnFixture, '/');
161082815dcSEvan Bacon
162082815dcSEvan Bacon    expect(getAppDelegate('/')).toStrictEqual({
163*ed3bd27bSEvan Bacon      contents: expect.any(String),
164*ed3bd27bSEvan Bacon      path: '/ios/HelloWorld/AppDelegate.mm',
165082815dcSEvan Bacon      language: 'objcpp',
166082815dcSEvan Bacon    });
167082815dcSEvan Bacon  });
168082815dcSEvan Bacon
169082815dcSEvan Bacon  it(`returns swift path`, () => {
170082815dcSEvan Bacon    vol.fromJSON(
171082815dcSEvan Bacon      {
172*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
173*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
174082815dcSEvan Bacon        'ios/Podfile': 'content',
175082815dcSEvan Bacon        'ios/TestPod.podspec': 'noop',
176082815dcSEvan Bacon        'ios/testproject/AppDelegate.swift': '',
177082815dcSEvan Bacon      },
178082815dcSEvan Bacon      '/swift'
179082815dcSEvan Bacon    );
180082815dcSEvan Bacon
181082815dcSEvan Bacon    expect(getAppDelegate('/swift')).toStrictEqual({
182082815dcSEvan Bacon      contents: '',
183082815dcSEvan Bacon      path: '/swift/ios/testproject/AppDelegate.swift',
184082815dcSEvan Bacon      language: 'swift',
185082815dcSEvan Bacon    });
186082815dcSEvan Bacon  });
187082815dcSEvan Bacon
188082815dcSEvan Bacon  it(`throws on invalid project`, () => {
189082815dcSEvan Bacon    vol.fromJSON(
190082815dcSEvan Bacon      {
191*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
192*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
193082815dcSEvan Bacon        'ios/Podfile': 'content',
194082815dcSEvan Bacon        'ios/TestPod.podspec': 'noop',
195082815dcSEvan Bacon      },
196082815dcSEvan Bacon      '/invalid'
197082815dcSEvan Bacon    );
198082815dcSEvan Bacon
199082815dcSEvan Bacon    expect(() => getAppDelegate('/invalid')).toThrow(UnexpectedError);
200082815dcSEvan Bacon    expect(() => getAppDelegate('/invalid')).toThrow(/AppDelegate/);
201082815dcSEvan Bacon  });
202082815dcSEvan Bacon
203082815dcSEvan Bacon  it(`warns when multiple paths are found`, () => {
204082815dcSEvan Bacon    vol.fromJSON(
205082815dcSEvan Bacon      {
206*ed3bd27bSEvan Bacon        'ios/testproject.xcodeproj/project.pbxproj':
207*ed3bd27bSEvan Bacon          rnFixture['ios/HelloWorld.xcodeproj/project.pbxproj'],
208082815dcSEvan Bacon        'ios/Podfile': 'content',
209082815dcSEvan Bacon        'ios/TestPod.podspec': 'noop',
210082815dcSEvan Bacon        'ios/testproject/AppDelegate.swift': '',
211082815dcSEvan Bacon        'ios/testproject/AppDelegate.m': '',
212082815dcSEvan Bacon        'ios/testproject/AppDelegate.h': '',
213082815dcSEvan Bacon      },
214082815dcSEvan Bacon      '/confusing'
215082815dcSEvan Bacon    );
216082815dcSEvan Bacon
217082815dcSEvan Bacon    expect(getAppDelegate('/confusing')).toStrictEqual({
218082815dcSEvan Bacon      contents: '',
219082815dcSEvan Bacon      path: '/confusing/ios/testproject/AppDelegate.m',
220082815dcSEvan Bacon      language: 'objc',
221082815dcSEvan Bacon    });
222082815dcSEvan Bacon    expect(WarningAggregator.addWarningIOS).toHaveBeenLastCalledWith(
223082815dcSEvan Bacon      'paths-app-delegate',
224082815dcSEvan Bacon      'Found multiple AppDelegate file paths, using "ios/testproject/AppDelegate.m". Ignored paths: ["ios/testproject/AppDelegate.swift"]'
225082815dcSEvan Bacon    );
226082815dcSEvan Bacon  });
227082815dcSEvan Bacon});
228082815dcSEvan Bacon
229082815dcSEvan Bacondescribe(getAllInfoPlistPaths, () => {
230082815dcSEvan Bacon  beforeAll(async () => {
231082815dcSEvan Bacon    const project = {
232082815dcSEvan Bacon      'ExampleE2E-tvOS/Info.plist': '',
233082815dcSEvan Bacon      'ExampleE2E/Info.plist': '',
234082815dcSEvan Bacon      'ExampleE2E-tvOSTests/Info.plist': '',
235082815dcSEvan Bacon      'ExampleE2ETests/Info.plist': '',
236082815dcSEvan Bacon    };
237082815dcSEvan Bacon    vol.fromJSON(project, path.join('/app', 'ios'));
238082815dcSEvan Bacon    vol.fromJSON(project, '/app');
239082815dcSEvan Bacon  });
240082815dcSEvan Bacon
241082815dcSEvan Bacon  afterAll(() => {
242082815dcSEvan Bacon    vol.reset();
243082815dcSEvan Bacon  });
244082815dcSEvan Bacon
245082815dcSEvan Bacon  it(`gets paths in order`, () => {
246082815dcSEvan Bacon    expect(getAllInfoPlistPaths('/app')).toStrictEqual([
247082815dcSEvan Bacon      '/app/ios/ExampleE2E/Info.plist',
248082815dcSEvan Bacon      '/app/ios/ExampleE2E-tvOS/Info.plist',
249082815dcSEvan Bacon      '/app/ios/ExampleE2ETests/Info.plist',
250082815dcSEvan Bacon      '/app/ios/ExampleE2E-tvOSTests/Info.plist',
251082815dcSEvan Bacon    ]);
252082815dcSEvan Bacon  });
253082815dcSEvan Bacon});
254