@@ -7,13 +7,14 @@ import 'dart:async';
7
7
import 'package:file/file.dart' ;
8
8
import 'package:flutter_tools/src/application_package.dart' ;
9
9
import 'package:flutter_tools/src/base/file_system.dart' ;
10
- import 'package:flutter_tools/src/base/io.dart' show ProcessResult;
10
+ import 'package:flutter_tools/src/base/io.dart' show ProcessException, ProcessResult;
11
11
import 'package:flutter_tools/src/ios/mac.dart' ;
12
12
import 'package:mockito/mockito.dart' ;
13
13
import 'package:platform/platform.dart' ;
14
14
import 'package:process/process.dart' ;
15
15
import 'package:test/test.dart' ;
16
16
17
+ import '../src/common.dart' ;
17
18
import '../src/context.dart' ;
18
19
19
20
class MockProcessManager extends Mock implements ProcessManager {}
@@ -65,6 +66,97 @@ void main() {
65
66
});
66
67
});
67
68
69
+ group ('Xcode' , () {
70
+ MockProcessManager mockProcessManager;
71
+ Xcode xcode;
72
+
73
+ setUp (() {
74
+ mockProcessManager = new MockProcessManager ();
75
+ xcode = new Xcode ();
76
+ });
77
+
78
+ testUsingContext ('xcodeSelectPath returns null when xcode-select is not installed' , () {
79
+ when (mockProcessManager.runSync (< String > ['/usr/bin/xcode-select' , '--print-path' ]))
80
+ .thenThrow (const ProcessException ('/usr/bin/xcode-select' , const < String > ['--print-path' ]));
81
+ expect (xcode.xcodeSelectPath, isNull);
82
+ }, overrides: < Type , Generator > {
83
+ ProcessManager : () => mockProcessManager,
84
+ });
85
+
86
+ testUsingContext ('xcodeSelectPath returns path when xcode-select is installed' , () {
87
+ final String xcodePath = '/Applications/Xcode8.0.app/Contents/Developer' ;
88
+ when (mockProcessManager.runSync (< String > ['/usr/bin/xcode-select' , '--print-path' ]))
89
+ .thenReturn (new ProcessResult (1 , 0 , xcodePath, '' ));
90
+ expect (xcode.xcodeSelectPath, xcodePath);
91
+ }, overrides: < Type , Generator > {
92
+ ProcessManager : () => mockProcessManager,
93
+ });
94
+
95
+ testUsingContext ('xcodeVersionText returns null when xcodebuild is not installed' , () {
96
+ when (mockProcessManager.runSync (< String > ['/usr/bin/xcodebuild' , '-version' ]))
97
+ .thenThrow (const ProcessException ('/usr/bin/xcodebuild' , const < String > ['-version' ]));
98
+ expect (xcode.xcodeVersionText, isNull);
99
+ }, overrides: < Type , Generator > {
100
+ ProcessManager : () => mockProcessManager,
101
+ });
102
+
103
+ testUsingContext ('xcodeVersionText returns null when xcodebuild is not installed' , () {
104
+ when (mockProcessManager.runSync (< String > ['/usr/bin/xcodebuild' , '-version' ]))
105
+ .thenReturn (new ProcessResult (1 , 0 , 'Xcode 8.3.3\n Build version 8E3004b' , '' ));
106
+ expect (xcode.xcodeVersionText, 'Xcode 8.3.3, Build version 8E3004b' );
107
+ }, overrides: < Type , Generator > {
108
+ ProcessManager : () => mockProcessManager,
109
+ });
110
+
111
+ testUsingContext ('eulaSigned is false when clang is not installed' , () {
112
+ when (mockProcessManager.runSync (< String > ['/usr/bin/xcrun' , 'clang' ]))
113
+ .thenThrow (const ProcessException ('/usr/bin/xcrun' , const < String > ['clang' ]));
114
+ expect (xcode.eulaSigned, isFalse);
115
+ }, overrides: < Type , Generator > {
116
+ ProcessManager : () => mockProcessManager,
117
+ });
118
+
119
+ testUsingContext ('eulaSigned is false when clang output indicates EULA not yet accepted' , () {
120
+ when (mockProcessManager.runSync (< String > ['/usr/bin/xcrun' , 'clang' ]))
121
+ .thenReturn (new ProcessResult (1 , 1 , '' , 'Xcode EULA has not been accepted.\n Launch Xcode and accept the license.' ));
122
+ expect (xcode.eulaSigned, isFalse);
123
+ }, overrides: < Type , Generator > {
124
+ ProcessManager : () => mockProcessManager,
125
+ });
126
+
127
+ testUsingContext ('eulaSigned is true when clang output indicates EULA has been accepted' , () {
128
+ when (mockProcessManager.runSync (< String > ['/usr/bin/xcrun' , 'clang' ]))
129
+ .thenReturn (new ProcessResult (1 , 1 , '' , 'clang: error: no input files' ));
130
+ expect (xcode.eulaSigned, isTrue);
131
+ }, overrides: < Type , Generator > {
132
+ ProcessManager : () => mockProcessManager,
133
+ });
134
+
135
+ testUsingContext ('getAvailableDevices throws ToolExit when instruments is not installed' , () async {
136
+ when (mockProcessManager.run (< String > ['/usr/bin/instruments' , '-s' , 'devices' ]))
137
+ .thenThrow (const ProcessException ('/usr/bin/instruments' , const < String > ['-s' , 'devices' ]));
138
+ expect (() async => await xcode.getAvailableDevices (), throwsToolExit ());
139
+ }, overrides: < Type , Generator > {
140
+ ProcessManager : () => mockProcessManager,
141
+ });
142
+
143
+ testUsingContext ('getAvailableDevices throws ToolExit when instruments returns non-zero' , () async {
144
+ when (mockProcessManager.run (< String > ['/usr/bin/instruments' , '-s' , 'devices' ]))
145
+ .thenReturn (new ProcessResult (1 , 1 , '' , 'Sad today' ));
146
+ expect (() async => await xcode.getAvailableDevices (), throwsToolExit ());
147
+ }, overrides: < Type , Generator > {
148
+ ProcessManager : () => mockProcessManager,
149
+ });
150
+
151
+ testUsingContext ('getAvailableDevices returns instruments output when installed' , () async {
152
+ when (mockProcessManager.run (< String > ['/usr/bin/instruments' , '-s' , 'devices' ]))
153
+ .thenReturn (new ProcessResult (1 , 0 , 'Known Devices:\n iPhone 6s (10.3.3) [foo]' , '' ));
154
+ expect (await xcode.getAvailableDevices (), 'Known Devices:\n iPhone 6s (10.3.3) [foo]' );
155
+ }, overrides: < Type , Generator > {
156
+ ProcessManager : () => mockProcessManager,
157
+ });
158
+ });
159
+
68
160
group ('Diagnose Xcode build failure' , () {
69
161
BuildableIOSApp app;
70
162
0 commit comments