blob: 62c14f693829730887c15a36d59b0d67d615abe6 [file] [log] [blame]
yjbanova2b1bd42016-02-19 16:31:34 -08001// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:async';
6
7import 'package:file/file.dart';
Yegor Jbanov677e63b2016-02-25 15:58:09 -08008import 'package:flutter_tools/src/android/android_device.dart';
yjbanova2b1bd42016-02-19 16:31:34 -08009import 'package:flutter_tools/src/base/file_system.dart';
10import 'package:flutter_tools/src/base/logger.dart';
Yegor Jbanov677e63b2016-02-25 15:58:09 -080011import 'package:flutter_tools/src/base/os.dart';
12import 'package:flutter_tools/src/commands/drive.dart';
13import 'package:flutter_tools/src/device.dart';
yjbanova2b1bd42016-02-19 16:31:34 -080014import 'package:flutter_tools/src/globals.dart';
Yegor Jbanov677e63b2016-02-25 15:58:09 -080015import 'package:flutter_tools/src/ios/simulators.dart';
16import 'package:mockito/mockito.dart';
yjbanova2b1bd42016-02-19 16:31:34 -080017import 'package:test/test.dart';
18
19import 'src/common.dart';
20import 'src/context.dart';
21import 'src/mocks.dart';
22
Hixiec7339de2016-03-09 17:43:14 -080023void main() {
yjbanova2b1bd42016-02-19 16:31:34 -080024 group('drive', () {
Yegor Jbanov677e63b2016-02-25 15:58:09 -080025 DriveCommand command;
26 Device mockDevice;
27
28 void withMockDevice([Device mock]) {
29 mockDevice = mock ?? new MockDevice();
30 targetDeviceFinder = () async => mockDevice;
31 testDeviceManager.addDevice(mockDevice);
32 }
33
yjbanova2b1bd42016-02-19 16:31:34 -080034 setUp(() {
Yegor Jbanov677e63b2016-02-25 15:58:09 -080035 command = new DriveCommand();
36 applyMocksToCommand(command);
yjbanov278630e2016-02-22 14:55:17 -080037 useInMemoryFileSystem(cwd: '/some/app');
Yegor Jbanov677e63b2016-02-25 15:58:09 -080038 toolchainDownloader = (_) async { };
39 targetDeviceFinder = () {
40 throw 'Unexpected call to targetDeviceFinder';
41 };
42 appStarter = (_) {
43 throw 'Unexpected call to appStarter';
44 };
45 testRunner = (_) {
46 throw 'Unexpected call to testRunner';
47 };
48 appStopper = (_) {
49 throw 'Unexpected call to appStopper';
50 };
yjbanova2b1bd42016-02-19 16:31:34 -080051 });
52
53 tearDown(() {
Yegor Jbanov677e63b2016-02-25 15:58:09 -080054 command = null;
yjbanova2b1bd42016-02-19 16:31:34 -080055 restoreFileSystem();
Yegor Jbanov677e63b2016-02-25 15:58:09 -080056 restoreAppStarter();
57 restoreAppStopper();
58 restoreTestRunner();
59 restoreTargetDeviceFinder();
yjbanova2b1bd42016-02-19 16:31:34 -080060 });
61
62 testUsingContext('returns 1 when test file is not found', () {
Yegor Jbanov677e63b2016-02-25 15:58:09 -080063 withMockDevice();
yjbanova2b1bd42016-02-19 16:31:34 -080064 List<String> args = [
65 'drive',
66 '--target=/some/app/test/e2e.dart',
67 ];
68 return createTestCommandRunner(command).run(args).then((int code) {
69 expect(code, equals(1));
70 BufferLogger buffer = logger;
71 expect(buffer.errorText,
yjbanov278630e2016-02-22 14:55:17 -080072 contains('Test file not found: /some/app/test_driver/e2e_test.dart'));
yjbanova2b1bd42016-02-19 16:31:34 -080073 });
74 });
75
76 testUsingContext('returns 1 when app fails to run', () async {
Yegor Jbanov677e63b2016-02-25 15:58:09 -080077 withMockDevice();
78 appStarter = expectAsync((_) async => 1);
yjbanova2b1bd42016-02-19 16:31:34 -080079
yjbanov278630e2016-02-22 14:55:17 -080080 String testApp = '/some/app/test_driver/e2e.dart';
81 String testFile = '/some/app/test_driver/e2e_test.dart';
yjbanova2b1bd42016-02-19 16:31:34 -080082
83 MemoryFileSystem memFs = fs;
84 await memFs.file(testApp).writeAsString('main() {}');
85 await memFs.file(testFile).writeAsString('main() {}');
86
87 List<String> args = [
88 'drive',
89 '--target=$testApp',
90 ];
91 return createTestCommandRunner(command).run(args).then((int code) {
92 expect(code, equals(1));
93 BufferLogger buffer = logger;
94 expect(buffer.errorText, contains(
95 'Application failed to start. Will not run test. Quitting.'
96 ));
97 });
98 });
99
yjbanov278630e2016-02-22 14:55:17 -0800100 testUsingContext('returns 1 when app file is outside package', () async {
101 String packageDir = '/my/app';
102 useInMemoryFileSystem(cwd: packageDir);
yjbanov278630e2016-02-22 14:55:17 -0800103
104 String appFile = '/not/in/my/app.dart';
105 List<String> args = [
106 'drive',
107 '--target=$appFile',
108 ];
109 return createTestCommandRunner(command).run(args).then((int code) {
110 expect(code, equals(1));
111 BufferLogger buffer = logger;
112 expect(buffer.errorText, contains(
113 'Application file $appFile is outside the package directory $packageDir'
114 ));
115 });
116 });
117
118 testUsingContext('returns 1 when app file is in the root dir', () async {
119 String packageDir = '/my/app';
120 useInMemoryFileSystem(cwd: packageDir);
yjbanov278630e2016-02-22 14:55:17 -0800121
122 String appFile = '/my/app/main.dart';
123 List<String> args = [
124 'drive',
125 '--target=$appFile',
126 ];
127 return createTestCommandRunner(command).run(args).then((int code) {
128 expect(code, equals(1));
129 BufferLogger buffer = logger;
130 expect(buffer.errorText, contains(
131 'Application file main.dart must reside in one of the '
132 'sub-directories of the package structure, not in the root directory.'
133 ));
134 });
135 });
136
yjbanova2b1bd42016-02-19 16:31:34 -0800137 testUsingContext('returns 0 when test ends successfully', () async {
Yegor Jbanov677e63b2016-02-25 15:58:09 -0800138 withMockDevice();
139
yjbanova2b1bd42016-02-19 16:31:34 -0800140 String testApp = '/some/app/test/e2e.dart';
yjbanov278630e2016-02-22 14:55:17 -0800141 String testFile = '/some/app/test_driver/e2e_test.dart';
yjbanova2b1bd42016-02-19 16:31:34 -0800142
Yegor Jbanov677e63b2016-02-25 15:58:09 -0800143 appStarter = expectAsync((_) {
144 return new Future<int>.value(0);
145 });
146 testRunner = expectAsync((List<String> testArgs) {
147 expect(testArgs, [testFile]);
148 return new Future<Null>.value();
149 });
150 appStopper = expectAsync((_) {
151 return new Future<int>.value(0);
152 });
yjbanova2b1bd42016-02-19 16:31:34 -0800153
154 MemoryFileSystem memFs = fs;
155 await memFs.file(testApp).writeAsString('main() {}');
156 await memFs.file(testFile).writeAsString('main() {}');
157
158 List<String> args = [
159 'drive',
160 '--target=$testApp',
161 ];
162 return createTestCommandRunner(command).run(args).then((int code) {
163 expect(code, equals(0));
164 BufferLogger buffer = logger;
165 expect(buffer.errorText, isEmpty);
166 });
167 });
Yegor Jbanov677e63b2016-02-25 15:58:09 -0800168
169
170 group('findTargetDevice', () {
171 testUsingContext('uses specified device', () async {
172 testDeviceManager.specifiedDeviceId = '123';
173 withMockDevice();
174 when(mockDevice.name).thenReturn('specified-device');
175 when(mockDevice.id).thenReturn('123');
176
177 Device device = await findTargetDevice();
178 expect(device.name, 'specified-device');
179 });
180 });
181
182 group('findTargetDevice on iOS', () {
Hixiec7339de2016-03-09 17:43:14 -0800183 void setOs() {
Yegor Jbanov677e63b2016-02-25 15:58:09 -0800184 when(os.isMacOS).thenReturn(true);
185 when(os.isLinux).thenReturn(false);
186 }
187
188 testUsingContext('uses existing emulator', () async {
189 setOs();
190 withMockDevice();
191 when(mockDevice.name).thenReturn('mock-simulator');
192 when(mockDevice.isLocalEmulator).thenReturn(true);
193
194 Device device = await findTargetDevice();
195 expect(device.name, 'mock-simulator');
196 });
197
198 testUsingContext('uses existing Android device if and there are no simulators', () async {
199 setOs();
200 mockDevice = new MockAndroidDevice();
201 when(mockDevice.name).thenReturn('mock-android-device');
202 when(mockDevice.isLocalEmulator).thenReturn(false);
203 withMockDevice(mockDevice);
204
205 Device device = await findTargetDevice();
206 expect(device.name, 'mock-android-device');
207 });
208
209 testUsingContext('launches emulator', () async {
210 setOs();
211 when(SimControl.instance.boot()).thenReturn(true);
212 Device emulator = new MockDevice();
213 when(emulator.name).thenReturn('new-simulator');
214 when(IOSSimulatorUtils.instance.getAttachedDevices())
215 .thenReturn([emulator]);
216
217 Device device = await findTargetDevice();
218 expect(device.name, 'new-simulator');
219 });
220 });
221
222 group('findTargetDevice on Linux', () {
Hixiec7339de2016-03-09 17:43:14 -0800223 void setOs() {
Yegor Jbanov677e63b2016-02-25 15:58:09 -0800224 when(os.isMacOS).thenReturn(false);
225 when(os.isLinux).thenReturn(true);
226 }
227
228 testUsingContext('returns null if no devices found', () async {
229 setOs();
230 expect(await findTargetDevice(), isNull);
231 });
232
233 testUsingContext('uses existing Android device', () async {
234 setOs();
235 mockDevice = new MockAndroidDevice();
236 when(mockDevice.name).thenReturn('mock-android-device');
237 withMockDevice(mockDevice);
238
239 Device device = await findTargetDevice();
240 expect(device.name, 'mock-android-device');
241 });
242 });
yjbanova2b1bd42016-02-19 16:31:34 -0800243 });
244}
Yegor Jbanov677e63b2016-02-25 15:58:09 -0800245
246class MockDevice extends Mock implements Device {
247 MockDevice() {
248 when(this.isSupported()).thenReturn(true);
249 }
250}
251
252class MockAndroidDevice extends Mock implements AndroidDevice { }