blob: aac769599d4ea90c26dce5b80cbce90643b5fcd1 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/drive.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import '../src/common.dart';
import '../src/context.dart';
import '../src/mocks.dart';
void main() {
group('drive', () {
DriveCommand command;
Device mockDevice;
MemoryFileSystem fs;
Directory cwd;
void withMockDevice([Device mock]) {
mockDevice = mock ?? new MockDevice();
targetDeviceFinder = () async => mockDevice;
testDeviceManager.addDevice(mockDevice);
}
setUpAll(() {
Cache.disableLocking();
});
setUp(() {
command = new DriveCommand();
applyMocksToCommand(command);
fs = new MemoryFileSystem();
cwd = fs.systemTempDirectory.createTempSync('some_app_');
fs.currentDirectory = cwd;
fs.directory('test').createSync();
fs.directory('test_driver').createSync();
fs.file('pubspec.yaml')..createSync();
fs.file('.packages').createSync();
setExitFunctionForTests();
targetDeviceFinder = () {
throw 'Unexpected call to targetDeviceFinder';
};
appStarter = (DriveCommand command) {
throw 'Unexpected call to appStarter';
};
testRunner = (List<String> testArgs, String observatoryUri) {
throw 'Unexpected call to testRunner';
};
appStopper = (DriveCommand command) {
throw 'Unexpected call to appStopper';
};
});
tearDown(() {
command = null;
restoreExitFunction();
restoreAppStarter();
restoreAppStopper();
restoreTestRunner();
restoreTargetDeviceFinder();
});
testUsingContext('returns 1 when test file is not found', () async {
withMockDevice();
final String testApp = fs.path.join(cwd.path, 'test', 'e2e.dart');
final String testFile = fs.path.join(cwd.path, 'test_driver', 'e2e_test.dart');
final List<String> args = <String>[
'drive',
'--target=$testApp}',
];
try {
await createTestCommandRunner(command).run(args);
fail('Expect exception');
} on ToolExit catch (e) {
expect(e.exitCode ?? 1, 1);
expect(e.message, contains('Test file not found: $testFile'));
}
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
testUsingContext('returns 1 when app fails to run', () async {
withMockDevice();
appStarter = expectAsync1((DriveCommand command) async => null);
final String testApp = fs.path.join(cwd.path, 'test_driver', 'e2e.dart');
final String testFile = fs.path.join(cwd.path, 'test_driver', 'e2e_test.dart');
final MemoryFileSystem memFs = fs;
await memFs.file(testApp).writeAsString('main() { }');
await memFs.file(testFile).writeAsString('main() { }');
final List<String> args = <String>[
'drive',
'--target=$testApp',
];
try {
await createTestCommandRunner(command).run(args);
fail('Expect exception');
} on ToolExit catch (e) {
expect(e.exitCode, 1);
expect(e.message, contains('Application failed to start. Will not run test. Quitting.'));
}
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
testUsingContext('returns 1 when app file is outside package', () async {
final String appFile = fs.path.join(cwd.dirname, 'other_app', 'app.dart');
final List<String> args = <String>[
'drive',
'--target=$appFile',
];
try {
await createTestCommandRunner(command).run(args);
fail('Expect exception');
} on ToolExit catch (e) {
expect(e.exitCode ?? 1, 1);
expect(testLogger.errorText, contains(
'Application file $appFile is outside the package directory ${cwd.path}',
));
}
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
testUsingContext('returns 1 when app file is in the root dir', () async {
final String appFile = fs.path.join(cwd.path, 'main.dart');
final List<String> args = <String>[
'drive',
'--target=$appFile',
];
try {
await createTestCommandRunner(command).run(args);
fail('Expect exception');
} on ToolExit catch (e) {
expect(e.exitCode ?? 1, 1);
expect(testLogger.errorText, contains(
'Application file main.dart must reside in one of the '
'sub-directories of the package structure, not in the root directory.',
));
}
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
testUsingContext('returns 0 when test ends successfully', () async {
withMockDevice();
final String testApp = fs.path.join(cwd.path, 'test', 'e2e.dart');
final String testFile = fs.path.join(cwd.path, 'test_driver', 'e2e_test.dart');
appStarter = expectAsync1((DriveCommand command) async {
return new LaunchResult.succeeded();
});
testRunner = expectAsync2((List<String> testArgs, String observatoryUri) async {
expect(testArgs, <String>[testFile]);
return null;
});
appStopper = expectAsync1((DriveCommand command) async {
return true;
});
final MemoryFileSystem memFs = fs;
await memFs.file(testApp).writeAsString('main() {}');
await memFs.file(testFile).writeAsString('main() {}');
final List<String> args = <String>[
'drive',
'--target=$testApp',
];
await createTestCommandRunner(command).run(args);
expect(testLogger.errorText, isEmpty);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
testUsingContext('returns exitCode set by test runner', () async {
withMockDevice();
final String testApp = fs.path.join(cwd.path, 'test', 'e2e.dart');
final String testFile = fs.path.join(cwd.path, 'test_driver', 'e2e_test.dart');
appStarter = expectAsync1((DriveCommand command) async {
return new LaunchResult.succeeded();
});
testRunner = (List<String> testArgs, String observatoryUri) async {
throwToolExit(null, exitCode: 123);
};
appStopper = expectAsync1((DriveCommand command) async {
return true;
});
final MemoryFileSystem memFs = fs;
await memFs.file(testApp).writeAsString('main() {}');
await memFs.file(testFile).writeAsString('main() {}');
final List<String> args = <String>[
'drive',
'--target=$testApp',
];
try {
await createTestCommandRunner(command).run(args);
fail('Expect exception');
} on ToolExit catch (e) {
expect(e.exitCode ?? 1, 123);
expect(e.message, isNull);
}
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
group('findTargetDevice', () {
testUsingContext('uses specified device', () async {
testDeviceManager.specifiedDeviceId = '123';
withMockDevice();
when(mockDevice.name).thenReturn('specified-device');
when(mockDevice.id).thenReturn('123');
final Device device = await findTargetDevice();
expect(device.name, 'specified-device');
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
});
void findTargetDeviceOnOperatingSystem(String operatingSystem) {
Platform platform() => new FakePlatform(operatingSystem: operatingSystem);
testUsingContext('returns null if no devices found', () async {
expect(await findTargetDevice(), isNull);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
Platform: platform,
});
testUsingContext('uses existing Android device', () async {
mockDevice = new MockAndroidDevice();
when(mockDevice.name).thenReturn('mock-android-device');
withMockDevice(mockDevice);
final Device device = await findTargetDevice();
expect(device.name, 'mock-android-device');
}, overrides: <Type, Generator>{
FileSystem: () => fs,
Platform: platform,
});
}
group('findTargetDevice on Linux', () {
findTargetDeviceOnOperatingSystem('linux');
});
group('findTargetDevice on Windows', () {
findTargetDeviceOnOperatingSystem('windows');
});
group('findTargetDevice on macOS', () {
findTargetDeviceOnOperatingSystem('macos');
Platform macOsPlatform() => new FakePlatform(operatingSystem: 'macos');
testUsingContext('uses existing simulator', () async {
withMockDevice();
when(mockDevice.name).thenReturn('mock-simulator');
when(mockDevice.isLocalEmulator).thenReturn(new Future<bool>.value(true));
final Device device = await findTargetDevice();
expect(device.name, 'mock-simulator');
}, overrides: <Type, Generator>{
FileSystem: () => fs,
Platform: macOsPlatform,
});
});
});
}
class MockDevice extends Mock implements Device {
MockDevice() {
when(isSupported()).thenReturn(true);
}
}
class MockAndroidDevice extends Mock implements AndroidDevice { }