mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
304 lines
9.8 KiB
Dart
304 lines
9.8 KiB
Dart
// 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 '../src/common.dart';
|
|
import '../src/context.dart';
|
|
import '../src/mocks.dart';
|
|
|
|
void main() {
|
|
group('drive', () {
|
|
DriveCommand command;
|
|
Device mockDevice;
|
|
MemoryFileSystem fs;
|
|
Directory tempDir;
|
|
|
|
void withMockDevice([ Device mock ]) {
|
|
mockDevice = mock ?? MockDevice();
|
|
targetDeviceFinder = () async => mockDevice;
|
|
testDeviceManager.addDevice(mockDevice);
|
|
}
|
|
|
|
setUpAll(() {
|
|
Cache.disableLocking();
|
|
});
|
|
|
|
setUp(() {
|
|
command = DriveCommand();
|
|
applyMocksToCommand(command);
|
|
fs = MemoryFileSystem();
|
|
tempDir = fs.systemTempDirectory.createTempSync('flutter_drive_test.');
|
|
fs.currentDirectory = tempDir;
|
|
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();
|
|
tryToDelete(tempDir);
|
|
});
|
|
|
|
testUsingContext('returns 1 when test file is not found', () async {
|
|
withMockDevice();
|
|
|
|
final String testApp = fs.path.join(tempDir.path, 'test', 'e2e.dart');
|
|
final String testFile = fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart');
|
|
fs.file(testApp).createSync(recursive: true);
|
|
|
|
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(tempDir.path, 'test_driver', 'e2e.dart');
|
|
final String testFile = fs.path.join(tempDir.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(tempDir.dirname, 'other_app', 'app.dart');
|
|
fs.file(appFile).createSync(recursive: true);
|
|
final List<String> args = <String>[
|
|
'--no-wrap',
|
|
'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 ${tempDir.path}',
|
|
));
|
|
}
|
|
}, overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
});
|
|
|
|
testUsingContext('returns 1 when app file is in the root dir', () async {
|
|
final String appFile = fs.path.join(tempDir.path, 'main.dart');
|
|
fs.file(appFile).createSync(recursive: true);
|
|
final List<String> args = <String>[
|
|
'--no-wrap',
|
|
'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(tempDir.path, 'test', 'e2e.dart');
|
|
final String testFile = fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart');
|
|
|
|
appStarter = expectAsync1((DriveCommand command) async {
|
|
return 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(tempDir.path, 'test', 'e2e.dart');
|
|
final String testFile = fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart');
|
|
|
|
appStarter = expectAsync1((DriveCommand command) async {
|
|
return 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() => 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 = 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() => FakePlatform(operatingSystem: 'macos');
|
|
|
|
testUsingContext('uses existing simulator', () async {
|
|
withMockDevice();
|
|
when(mockDevice.name).thenReturn('mock-simulator');
|
|
when(mockDevice.isLocalEmulator)
|
|
.thenAnswer((Invocation invocation) => 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 { }
|