Port test logic to Dart.
This commit is contained in:
parent
1cadf1256d
commit
3419068cb3
@ -87,25 +87,27 @@ Testing the `flutter` package is currently a bit harder because we don't yet
|
|||||||
support testing the `flutter` package with pre-built binaries. To test the
|
support testing the `flutter` package with pre-built binaries. To test the
|
||||||
package, you'll need to follow the [instructions below](#working-on-the-engine-and-the-framework-at-the-same-time)
|
package, you'll need to follow the [instructions below](#working-on-the-engine-and-the-framework-at-the-same-time)
|
||||||
for working with this repository and the Flutter engine repository
|
for working with this repository and the Flutter engine repository
|
||||||
simultaneously and then run the following command:
|
simultaneously and then run the following command (assuming the `flutter/bin`
|
||||||
|
directory is in your path):
|
||||||
|
|
||||||
* `./dev/run_tests --debug`
|
* `flutter test --debug`
|
||||||
|
|
||||||
Creating a workflow for running the test with a prebuilt binary is
|
Creating a workflow for running the test with a prebuilt binary is
|
||||||
[Issue #56](https://github.com/flutter/flutter/issues/56). If you want to run
|
[Issue #56](https://github.com/flutter/flutter/issues/56). If you want
|
||||||
a single test individually:
|
to run a single test individually:
|
||||||
|
|
||||||
* `./dev/run_tests --debug test/harness/trivial_test.dart`
|
* `flutter test --debug trivial_test.dart`
|
||||||
|
|
||||||
Note: The tests are headless, you won't see any UI. You can use `print` to
|
Note: The tests are headless, you won't see any UI. You can use
|
||||||
generate console output or you can interact with the DartVM via observatory at [http://localhost:8181/](http://localhost:8181/).
|
`print` to generate console output or you can interact with the DartVM
|
||||||
|
via observatory at [http://localhost:8181/](http://localhost:8181/).
|
||||||
|
|
||||||
Adding a test
|
Adding a test
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
To add a test, simply create a file whose name ends with `_test.dart` in the
|
To add a test, simply create a file whose name ends with `_test.dart`
|
||||||
`packags/unit/test` directory. The test should have a `main` function and use
|
in the `packages/unit/test` directory. The test should have a `main`
|
||||||
the `test` package.
|
function and use the `test` package.
|
||||||
|
|
||||||
Contributing code
|
Contributing code
|
||||||
-----------------
|
-----------------
|
||||||
@ -120,7 +122,7 @@ To start working on a patch:
|
|||||||
and [design principles](https://github.com/flutter/engine/blob/master/sky/specs/design.md)
|
and [design principles](https://github.com/flutter/engine/blob/master/sky/specs/design.md)
|
||||||
before working on anything non-trivial. These guidelines are intended to keep
|
before working on anything non-trivial. These guidelines are intended to keep
|
||||||
the code consistent and avoid common pitfalls.
|
the code consistent and avoid common pitfalls.
|
||||||
* `git commit -a -m "<your brief but informative commit message>"`
|
* `git commit -a -m "<your informative commit message>"`
|
||||||
* `git push origin name_of_your_branch`
|
* `git push origin name_of_your_branch`
|
||||||
|
|
||||||
To send us a pull request:
|
To send us a pull request:
|
||||||
@ -163,15 +165,15 @@ the following steps.
|
|||||||
(e.g., `out/Debug`). To run examples on Android, build one of the Android
|
(e.g., `out/Debug`). To run examples on Android, build one of the Android
|
||||||
configurations (e.g., `out/android_Debug`).
|
configurations (e.g., `out/android_Debug`).
|
||||||
|
|
||||||
You should now be able to run the tests against your locally built engine using
|
You should now be able to run the tests against your locally built
|
||||||
the `./dev/run_tests` script. To run one of the examples on your device using
|
engine using the `flutter test --debug` command. To run one of the
|
||||||
your locally built engine, use the `--engine-src-path` option to the `flutter`
|
examples on your device using your locally built engine, use the
|
||||||
tool:
|
`--debug` option to the `flutter` tool:
|
||||||
|
|
||||||
* `flutter start --engine-src-path /foo/bar/engine/src`
|
* `flutter start --debug`
|
||||||
|
|
||||||
Eventually, the `--local-build` flag for the `flutter` command will
|
If you want to test the release version instead of the debug version,
|
||||||
automatically set the correct engine src path (see [Issue #57](https://github.com/flutter/flutter/issues/57)).
|
use `--release` instead of `--debug`.
|
||||||
|
|
||||||
Making a breaking change to the engine
|
Making a breaking change to the engine
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# Copyright 2015 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 os
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
FLUTTER_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
FLUTTER = os.path.join(FLUTTER_ROOT, 'bin', 'flutter')
|
|
||||||
|
|
||||||
UNIT_DIR = os.path.join(FLUTTER_ROOT, 'packages', 'unit')
|
|
||||||
TESTS_DIR = os.path.join(UNIT_DIR, 'test')
|
|
||||||
DEFAULT_ENGINE_DIR = os.path.abspath(os.path.join(FLUTTER_ROOT, '..', 'engine', 'src'))
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(description='Runs Flutter unit tests')
|
|
||||||
parser.add_argument('--engine-src-path', default=DEFAULT_ENGINE_DIR)
|
|
||||||
parser.add_argument('--config', default='Debug')
|
|
||||||
parser.add_argument('--debug', dest='config', action='store_const', const='Debug')
|
|
||||||
parser.add_argument('--release', dest='config', action='store_const', const='Release')
|
|
||||||
args, remaining = parser.parse_known_args()
|
|
||||||
|
|
||||||
build_dir = os.path.join(os.path.abspath(args.engine_src_path), 'out', args.config)
|
|
||||||
|
|
||||||
if not remaining:
|
|
||||||
for root, dirs, files in os.walk(TESTS_DIR):
|
|
||||||
remaining.extend(os.path.join(root, f)
|
|
||||||
for f in files if f.endswith("_test.dart"))
|
|
||||||
|
|
||||||
if os.environ['TERM'] == 'dumb':
|
|
||||||
remaining = [ '--no-color' ] + remaining
|
|
||||||
|
|
||||||
return subprocess.call([
|
|
||||||
FLUTTER,
|
|
||||||
'test',
|
|
||||||
'--build-dir=%s' % build_dir
|
|
||||||
] + remaining, cwd=UNIT_DIR)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
@ -1,11 +0,0 @@
|
|||||||
// Copyright 2015 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 'package:sky_tools/src/test/loader.dart' as loader;
|
|
||||||
import 'package:test/src/executable.dart' as executable;
|
|
||||||
|
|
||||||
main(List<String> args) {
|
|
||||||
loader.installHook();
|
|
||||||
return executable.main(args);
|
|
||||||
}
|
|
@ -74,6 +74,7 @@ class ApplicationPackageStore {
|
|||||||
return iOS;
|
return iOS;
|
||||||
case TargetPlatform.iOSSimulator:
|
case TargetPlatform.iOSSimulator:
|
||||||
return iOSSimulator;
|
return iOSSimulator;
|
||||||
|
case TargetPlatform.mac:
|
||||||
case TargetPlatform.linux:
|
case TargetPlatform.linux:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -110,6 +111,7 @@ class ApplicationPackageStore {
|
|||||||
iOSSimulator = new IOSApp(localPath: path.join(config.buildDir, IOSApp._defaultName));
|
iOSSimulator = new IOSApp(localPath: path.join(config.buildDir, IOSApp._defaultName));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TargetPlatform.mac:
|
||||||
case TargetPlatform.linux:
|
case TargetPlatform.linux:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ String _getNameForTargetPlatform(TargetPlatform platform) {
|
|||||||
return 'ios-arm';
|
return 'ios-arm';
|
||||||
case TargetPlatform.iOSSimulator:
|
case TargetPlatform.iOSSimulator:
|
||||||
return 'ios-x64';
|
return 'ios-x64';
|
||||||
|
case TargetPlatform.mac:
|
||||||
|
return 'darwin-x64';
|
||||||
case TargetPlatform.linux:
|
case TargetPlatform.linux:
|
||||||
return 'linux-x64';
|
return 'linux-x64';
|
||||||
}
|
}
|
||||||
@ -158,12 +160,31 @@ class ArtifactStore {
|
|||||||
|
|
||||||
// These values are initialized by FlutterCommandRunner on startup.
|
// These values are initialized by FlutterCommandRunner on startup.
|
||||||
static String flutterRoot;
|
static String flutterRoot;
|
||||||
static String packageRoot;
|
static String packageRoot = 'packages';
|
||||||
|
|
||||||
|
static bool get isPackageRootValid {
|
||||||
|
return FileSystemEntity.isDirectorySync(packageRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ensurePackageRootIsValid() {
|
||||||
|
if (!isPackageRootValid) {
|
||||||
|
String message = '$packageRoot is not a valid directory.';
|
||||||
|
if (packageRoot == 'packages') {
|
||||||
|
if (FileSystemEntity.isFileSync('pubspec.yaml'))
|
||||||
|
message += '\nDid you run `pub get` in this directory?';
|
||||||
|
else
|
||||||
|
message += '\nDid you run this command from the same directory as your pubspec.yaml file?';
|
||||||
|
}
|
||||||
|
stderr.writeln(message);
|
||||||
|
throw new ProcessExit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static String _engineRevision;
|
static String _engineRevision;
|
||||||
|
|
||||||
static String get engineRevision {
|
static String get engineRevision {
|
||||||
if (_engineRevision == null) {
|
if (_engineRevision == null) {
|
||||||
|
ensurePackageRootIsValid();
|
||||||
File revisionFile = new File(path.join(packageRoot, 'sky_engine', 'REVISION'));
|
File revisionFile = new File(path.join(packageRoot, 'sky_engine', 'REVISION'));
|
||||||
if (revisionFile.existsSync())
|
if (revisionFile.existsSync())
|
||||||
_engineRevision = revisionFile.readAsStringSync();
|
_engineRevision = revisionFile.readAsStringSync();
|
||||||
|
@ -24,6 +24,7 @@ enum TargetPlatform {
|
|||||||
android,
|
android,
|
||||||
iOS,
|
iOS,
|
||||||
iOSSimulator,
|
iOSSimulator,
|
||||||
|
mac,
|
||||||
linux,
|
linux,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,12 +37,21 @@ HostPlatform getCurrentHostPlatform() {
|
|||||||
return HostPlatform.linux;
|
return HostPlatform.linux;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TargetPlatform getCurrentHostPlatformAsTarget() {
|
||||||
|
if (Platform.isMacOS)
|
||||||
|
return TargetPlatform.mac;
|
||||||
|
if (Platform.isLinux)
|
||||||
|
return TargetPlatform.linux;
|
||||||
|
_logging.warning('Unsupported host platform, defaulting to Linux');
|
||||||
|
return TargetPlatform.linux;
|
||||||
|
}
|
||||||
|
|
||||||
class BuildConfiguration {
|
class BuildConfiguration {
|
||||||
BuildConfiguration.prebuilt({
|
BuildConfiguration.prebuilt({
|
||||||
this.hostPlatform,
|
this.hostPlatform,
|
||||||
this.targetPlatform,
|
this.targetPlatform,
|
||||||
this.deviceId
|
this.deviceId
|
||||||
}) : type = BuildType.prebuilt, buildDir = null;
|
}) : type = BuildType.prebuilt, buildDir = null, testable = false;
|
||||||
|
|
||||||
BuildConfiguration.local({
|
BuildConfiguration.local({
|
||||||
this.type,
|
this.type,
|
||||||
@ -49,7 +59,8 @@ class BuildConfiguration {
|
|||||||
this.targetPlatform,
|
this.targetPlatform,
|
||||||
String enginePath,
|
String enginePath,
|
||||||
String buildPath,
|
String buildPath,
|
||||||
this.deviceId
|
this.deviceId,
|
||||||
|
this.testable: false
|
||||||
}) : buildDir = path.normalize(path.join(enginePath, buildPath)) {
|
}) : buildDir = path.normalize(path.join(enginePath, buildPath)) {
|
||||||
assert(type == BuildType.debug || type == BuildType.release);
|
assert(type == BuildType.debug || type == BuildType.release);
|
||||||
}
|
}
|
||||||
@ -59,4 +70,5 @@ class BuildConfiguration {
|
|||||||
final TargetPlatform targetPlatform;
|
final TargetPlatform targetPlatform;
|
||||||
final String buildDir;
|
final String buildDir;
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
|
final bool testable;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import 'dart:io';
|
|||||||
import 'package:args/command_runner.dart';
|
import 'package:args/command_runner.dart';
|
||||||
|
|
||||||
import '../application_package.dart';
|
import '../application_package.dart';
|
||||||
|
import '../build_configuration.dart';
|
||||||
import '../device.dart';
|
import '../device.dart';
|
||||||
import '../toolchain.dart';
|
import '../toolchain.dart';
|
||||||
import 'flutter_command_runner.dart';
|
import 'flutter_command_runner.dart';
|
||||||
@ -18,19 +19,21 @@ abstract class FlutterCommand extends Command {
|
|||||||
/// Whether this command needs to be run from the root of a project.
|
/// Whether this command needs to be run from the root of a project.
|
||||||
bool get requiresProjectRoot => true;
|
bool get requiresProjectRoot => true;
|
||||||
|
|
||||||
|
List<BuildConfiguration> get buildConfigurations => runner.buildConfigurations;
|
||||||
|
|
||||||
Future downloadApplicationPackages() async {
|
Future downloadApplicationPackages() async {
|
||||||
if (applicationPackages == null)
|
if (applicationPackages == null)
|
||||||
applicationPackages = await ApplicationPackageStore.forConfigs(runner.buildConfigurations);
|
applicationPackages = await ApplicationPackageStore.forConfigs(buildConfigurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future downloadToolchain() async {
|
Future downloadToolchain() async {
|
||||||
if (toolchain == null)
|
if (toolchain == null)
|
||||||
toolchain = await Toolchain.forConfigs(runner.buildConfigurations);
|
toolchain = await Toolchain.forConfigs(buildConfigurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void connectToDevices() {
|
void connectToDevices() {
|
||||||
if (devices == null)
|
if (devices == null)
|
||||||
devices = new DeviceStore.forConfigs(runner.buildConfigurations);
|
devices = new DeviceStore.forConfigs(buildConfigurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future downloadApplicationPackagesAndConnectToDevices() async {
|
Future downloadApplicationPackagesAndConnectToDevices() async {
|
||||||
|
@ -16,6 +16,12 @@ import '../process.dart';
|
|||||||
|
|
||||||
final Logger _logging = new Logger('sky_tools.flutter_command_runner');
|
final Logger _logging = new Logger('sky_tools.flutter_command_runner');
|
||||||
|
|
||||||
|
const String kFlutterRootEnvironmentVariableName = 'FLUTTER_ROOT'; // should point to //flutter/ (root of flutter/flutter repo)
|
||||||
|
const String kFlutterEngineEnvironmentVariableName = 'FLUTTER_ENGINE'; // should point to //engine/src/ (root of flutter/engine repo)
|
||||||
|
const String kSnapshotFileName = 'flutter_tools.snapshot'; // in //flutter/bin/cache/
|
||||||
|
const String kFlutterToolsScriptFileName = 'sky_tools.dart'; // in //flutter/packages/flutter_tools/bin/
|
||||||
|
const String kFlutterEnginePackageName = 'sky_engine';
|
||||||
|
|
||||||
class FlutterCommandRunner extends CommandRunner {
|
class FlutterCommandRunner extends CommandRunner {
|
||||||
FlutterCommandRunner()
|
FlutterCommandRunner()
|
||||||
: super('flutter', 'Manage your Flutter app development.') {
|
: super('flutter', 'Manage your Flutter app development.') {
|
||||||
@ -27,67 +33,76 @@ class FlutterCommandRunner extends CommandRunner {
|
|||||||
negatable: false,
|
negatable: false,
|
||||||
help: 'Very noisy logging, including the output of all '
|
help: 'Very noisy logging, including the output of all '
|
||||||
'shell commands executed.');
|
'shell commands executed.');
|
||||||
|
String packagesHelp;
|
||||||
|
if (ArtifactStore.isPackageRootValid)
|
||||||
|
packagesHelp = '\n(defaults to "${ArtifactStore.packageRoot}")';
|
||||||
|
else
|
||||||
|
packagesHelp = '\n(required, since the current directory does not contain a "packages" subdirectory)';
|
||||||
argParser.addOption('package-root',
|
argParser.addOption('package-root',
|
||||||
help: 'Path to your packages directory.', defaultsTo: 'packages');
|
help: 'Path to your packages directory.$packagesHelp');
|
||||||
argParser.addOption('flutter-root', hide: true,
|
argParser.addOption('flutter-root',
|
||||||
help: 'The root directory of the Flutter repository.');
|
help: 'The root directory of the Flutter repository. Defaults to \$$kFlutterRootEnvironmentVariableName if set,\n'
|
||||||
|
'otherwise defaults to a value derived from the location of this tool.', defaultsTo: defaultFlutterRoot);
|
||||||
|
|
||||||
argParser.addOption('android-device-id',
|
argParser.addOption('android-device-id',
|
||||||
help: 'Serial number of the target Android device.');
|
help: 'Serial number of the target Android device.');
|
||||||
|
|
||||||
argParser.addSeparator('Local build selection options:');
|
argParser.addSeparator('Local build selection options (not normally required):');
|
||||||
argParser.addFlag('debug',
|
argParser.addFlag('debug',
|
||||||
negatable: false,
|
negatable: false,
|
||||||
help:
|
help:
|
||||||
'Set this if you are building Flutter locally and want to use the debug build products. '
|
'Set this if you are building Flutter locally and want to use the debug build products.\n'
|
||||||
'When set, attempts to automaticaly determine engine-src-path if engine-src-path is '
|
'Defaults to true if --engine-src-path is specified and --release is not, otherwise false.');
|
||||||
'not set. Not normally required.');
|
|
||||||
argParser.addFlag('release',
|
argParser.addFlag('release',
|
||||||
negatable: false,
|
negatable: false,
|
||||||
help:
|
help:
|
||||||
'Set this if you are building Flutter locally and want to use the release build products. '
|
'Set this if you are building Flutter locally and want to use the release build products.\n'
|
||||||
'When set, attempts to automaticaly determine engine-src-path if engine-src-path is '
|
'The --release option is not compatible with the listen command on iOS devices and simulators.');
|
||||||
'not set. Note that release is not compatible with the listen command '
|
|
||||||
'on iOS devices and simulators. Not normally required.');
|
|
||||||
argParser.addFlag('local-build',
|
|
||||||
negatable: false,
|
|
||||||
hide: true,
|
|
||||||
help:
|
|
||||||
'Automatically detect your engine src directory from an overridden Flutter package. '
|
|
||||||
'Useful if you are building Flutter locally and are using a dependency_override for'
|
|
||||||
'the Flutter package that points to your engine src directory.');
|
|
||||||
argParser.addOption('engine-src-path',
|
argParser.addOption('engine-src-path',
|
||||||
help:
|
help:
|
||||||
'Path to your engine src directory, if you are building Flutter locally. '
|
'Path to your engine src directory, if you are building Flutter locally.\n'
|
||||||
'Ignored if neither debug nor release is set. Not normally required.');
|
'Defaults to \$$kFlutterEngineEnvironmentVariableName if set, otherwise defaults to the path given in your pubspec.yaml\n'
|
||||||
|
'dependency_overrides for $kFlutterEnginePackageName, if any, or, failing that, tries to guess at the location\n'
|
||||||
|
'based on the value of the --flutter-root option.');
|
||||||
|
argParser.addOption('host-debug-build-path', hide: true,
|
||||||
|
help:
|
||||||
|
'Path to your host Debug out directory (i.e. the one that runs on your workstation, not a device), if you are building Flutter locally.\n'
|
||||||
|
'This path is relative to --engine-src-path. Not normally required.',
|
||||||
|
defaultsTo: 'out/Debug/');
|
||||||
|
argParser.addOption('host-release-build-path', hide: true,
|
||||||
|
help:
|
||||||
|
'Path to your host Release out directory (i.e. the one that runs on your workstation, not a device), if you are building Flutter locally.\n'
|
||||||
|
'This path is relative to --engine-src-path. Not normally required.',
|
||||||
|
defaultsTo: 'out/Release/');
|
||||||
argParser.addOption('android-debug-build-path', hide: true,
|
argParser.addOption('android-debug-build-path', hide: true,
|
||||||
help:
|
help:
|
||||||
'Path to your Android Debug out directory, if you are building Flutter locally. '
|
'Path to your Android Debug out directory, if you are building Flutter locally.\n'
|
||||||
'This path is relative to engine-src-path. Not normally required.',
|
'This path is relative to --engine-src-path. Not normally required.',
|
||||||
defaultsTo: 'out/android_Debug/');
|
defaultsTo: 'out/android_Debug/');
|
||||||
argParser.addOption('android-release-build-path', hide: true,
|
argParser.addOption('android-release-build-path', hide: true,
|
||||||
help:
|
help:
|
||||||
'Path to your Android Release out directory, if you are building Flutter locally. '
|
'Path to your Android Release out directory, if you are building Flutter locally.\n'
|
||||||
'This path is relative to engine-src-path. Not normally required.',
|
'This path is relative to --engine-src-path. Not normally required.',
|
||||||
defaultsTo: 'out/android_Release/');
|
defaultsTo: 'out/android_Release/');
|
||||||
argParser.addOption('ios-debug-build-path', hide: true,
|
argParser.addOption('ios-debug-build-path', hide: true,
|
||||||
help:
|
help:
|
||||||
'Path to your iOS Debug out directory, if you are building Flutter locally. '
|
'Path to your iOS Debug out directory, if you are building Flutter locally.\n'
|
||||||
'This path is relative to engine-src-path. Not normally required.',
|
'This path is relative to --engine-src-path. Not normally required.',
|
||||||
defaultsTo: 'out/ios_Debug/');
|
defaultsTo: 'out/ios_Debug/');
|
||||||
argParser.addOption('ios-release-build-path', hide: true,
|
argParser.addOption('ios-release-build-path', hide: true,
|
||||||
help:
|
help:
|
||||||
'Path to your iOS Release out directory, if you are building Flutter locally. '
|
'Path to your iOS Release out directory, if you are building Flutter locally.\n'
|
||||||
'This path is relative to engine-src-path. Not normally required.',
|
'This path is relative to --engine-src-path. Not normally required.',
|
||||||
defaultsTo: 'out/ios_Release/');
|
defaultsTo: 'out/ios_Release/');
|
||||||
argParser.addOption('ios-sim-debug-build-path', hide: true,
|
argParser.addOption('ios-sim-debug-build-path', hide: true,
|
||||||
help:
|
help:
|
||||||
'Path to your iOS Simulator Debug out directory, if you are building Sky locally. '
|
'Path to your iOS Simulator Debug out directory, if you are building Flutter locally.\n'
|
||||||
'This path is relative to engine-src-path. Not normally required.',
|
'This path is relative to --engine-src-path. Not normally required.',
|
||||||
defaultsTo: 'out/ios_sim_Debug/');
|
defaultsTo: 'out/ios_sim_Debug/');
|
||||||
argParser.addOption('ios-sim-release-build-path', hide: true,
|
argParser.addOption('ios-sim-release-build-path', hide: true,
|
||||||
help:
|
help:
|
||||||
'Path to your iOS Simulator Release out directory, if you are building Sky locally. '
|
'Path to your iOS Simulator Release out directory, if you are building Flutter locally.\n'
|
||||||
'This path is relative to engine-src-path. Not normally required.',
|
'This path is relative to --engine-src-path. Not normally required.',
|
||||||
defaultsTo: 'out/ios_sim_Release/');
|
defaultsTo: 'out/ios_sim_Release/');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +115,17 @@ class FlutterCommandRunner extends CommandRunner {
|
|||||||
|
|
||||||
ArgResults _globalResults;
|
ArgResults _globalResults;
|
||||||
|
|
||||||
|
String get defaultFlutterRoot {
|
||||||
|
String script = Platform.script.toFilePath();
|
||||||
|
if (Platform.environment.containsKey(kFlutterRootEnvironmentVariableName))
|
||||||
|
return Platform.environment[kFlutterRootEnvironmentVariableName];
|
||||||
|
if (path.basename(script) == kSnapshotFileName)
|
||||||
|
return path.dirname(path.dirname(path.dirname(script)));
|
||||||
|
if (path.basename(script) == kFlutterToolsScriptFileName)
|
||||||
|
return path.dirname(path.dirname(path.dirname(path.dirname(script))));
|
||||||
|
return '.';
|
||||||
|
}
|
||||||
|
|
||||||
Future<int> runCommand(ArgResults globalResults) {
|
Future<int> runCommand(ArgResults globalResults) {
|
||||||
if (globalResults['verbose'])
|
if (globalResults['verbose'])
|
||||||
Logger.root.level = Level.INFO;
|
Logger.root.level = Level.INFO;
|
||||||
@ -108,39 +134,44 @@ class FlutterCommandRunner extends CommandRunner {
|
|||||||
Logger.root.level = Level.FINE;
|
Logger.root.level = Level.FINE;
|
||||||
|
|
||||||
_globalResults = globalResults;
|
_globalResults = globalResults;
|
||||||
ArtifactStore.flutterRoot = globalResults['flutter-root'] ?? Platform.environment['FLUTTER_ROOT'];
|
ArtifactStore.flutterRoot = globalResults['flutter-root'];
|
||||||
ArtifactStore.packageRoot = globalResults['package-root'];
|
if (globalResults.wasParsed('package-root'))
|
||||||
|
ArtifactStore.packageRoot = globalResults['package-root'];
|
||||||
|
|
||||||
return super.runCommand(globalResults);
|
return super.runCommand(globalResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<BuildConfiguration> _createBuildConfigurations(ArgResults globalResults) {
|
List<BuildConfiguration> _createBuildConfigurations(ArgResults globalResults) {
|
||||||
if (!FileSystemEntity.isDirectorySync(ArtifactStore.packageRoot)) {
|
String enginePath = globalResults['engine-src-path'] ?? Platform.environment[kFlutterEngineEnvironmentVariableName];
|
||||||
String message = '${ArtifactStore.packageRoot} is not a valid directory.';
|
|
||||||
if (ArtifactStore.packageRoot == 'packages') {
|
|
||||||
if (FileSystemEntity.isFileSync('pubspec.yaml'))
|
|
||||||
message += '\nDid you run `pub get` in this directory?';
|
|
||||||
else
|
|
||||||
message += '\nDid you run this command from the same directory as your pubspec.yaml file?';
|
|
||||||
}
|
|
||||||
stderr.writeln(message);
|
|
||||||
throw new ProcessExit(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
String enginePath = globalResults['engine-src-path'];
|
|
||||||
bool isDebug = globalResults['debug'];
|
bool isDebug = globalResults['debug'];
|
||||||
bool isRelease = globalResults['release'];
|
bool isRelease = globalResults['release'];
|
||||||
HostPlatform hostPlatform = getCurrentHostPlatform();
|
HostPlatform hostPlatform = getCurrentHostPlatform();
|
||||||
|
TargetPlatform hostPlatformAsTarget = getCurrentHostPlatformAsTarget();
|
||||||
|
|
||||||
if (enginePath == null && globalResults['local-build']) {
|
if (enginePath == null && (isDebug || isRelease)) {
|
||||||
Directory flutterDir = new Directory(path.join(globalResults['package-root'], 'flutter'));
|
if (ArtifactStore.isPackageRootValid) {
|
||||||
String realFlutterPath = flutterDir.resolveSymbolicLinksSync();
|
Directory engineDir = new Directory(path.join(ArtifactStore.packageRoot, kFlutterEnginePackageName));
|
||||||
|
try {
|
||||||
enginePath = path.dirname(path.dirname(path.dirname(path.dirname(realFlutterPath))));
|
String realEnginePath = engineDir.resolveSymbolicLinksSync();
|
||||||
bool dirExists = FileSystemEntity.isDirectorySync(path.join(enginePath, 'out'));
|
enginePath = path.dirname(path.dirname(path.dirname(path.dirname(realEnginePath))));
|
||||||
if (enginePath == '/' || enginePath.isEmpty || !dirExists) {
|
bool dirExists = FileSystemEntity.isDirectorySync(path.join(enginePath, 'out'));
|
||||||
stderr.writeln('Unable to detect local build in $enginePath.\n'
|
if (enginePath == '/' || enginePath.isEmpty || !dirExists)
|
||||||
'Do you have a dependency override for the flutter package?');
|
enginePath = null;
|
||||||
|
} on FileSystemException { }
|
||||||
|
}
|
||||||
|
if (enginePath == null) {
|
||||||
|
String tryEnginePath(String enginePath) {
|
||||||
|
if (FileSystemEntity.isDirectorySync(path.join(enginePath, 'out')))
|
||||||
|
return enginePath;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
enginePath = tryEnginePath(path.join(ArtifactStore.flutterRoot, '../engine/src'));
|
||||||
|
}
|
||||||
|
if (enginePath == null) {
|
||||||
|
stderr.writeln('Unable to detect local Flutter engine build directory.\n'
|
||||||
|
'Either specify a dependency_override for the $kFlutterEnginePackageName package in your pubspec.yaml and\n'
|
||||||
|
'ensure --package-root is set if necessary, or set the \$$kFlutterEngineEnvironmentVariableName environment variable, or\n'
|
||||||
|
'use --engine-src-path to specify the path to the root of your flutter/engine repository.');
|
||||||
throw new ProcessExit(2);
|
throw new ProcessExit(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,6 +192,15 @@ class FlutterCommandRunner extends CommandRunner {
|
|||||||
isDebug = true;
|
isDebug = true;
|
||||||
|
|
||||||
if (isDebug) {
|
if (isDebug) {
|
||||||
|
configs.add(new BuildConfiguration.local(
|
||||||
|
type: BuildType.debug,
|
||||||
|
hostPlatform: hostPlatform,
|
||||||
|
targetPlatform: hostPlatformAsTarget,
|
||||||
|
enginePath: enginePath,
|
||||||
|
buildPath: globalResults['host-debug-build-path'],
|
||||||
|
testable: true
|
||||||
|
));
|
||||||
|
|
||||||
configs.add(new BuildConfiguration.local(
|
configs.add(new BuildConfiguration.local(
|
||||||
type: BuildType.debug,
|
type: BuildType.debug,
|
||||||
hostPlatform: hostPlatform,
|
hostPlatform: hostPlatform,
|
||||||
@ -190,6 +230,15 @@ class FlutterCommandRunner extends CommandRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isRelease) {
|
if (isRelease) {
|
||||||
|
configs.add(new BuildConfiguration.local(
|
||||||
|
type: BuildType.release,
|
||||||
|
hostPlatform: hostPlatform,
|
||||||
|
targetPlatform: hostPlatformAsTarget,
|
||||||
|
enginePath: enginePath,
|
||||||
|
buildPath: globalResults['host-release-build-path'],
|
||||||
|
testable: true
|
||||||
|
));
|
||||||
|
|
||||||
configs.add(new BuildConfiguration.local(
|
configs.add(new BuildConfiguration.local(
|
||||||
type: BuildType.release,
|
type: BuildType.release,
|
||||||
hostPlatform: hostPlatform,
|
hostPlatform: hostPlatform,
|
||||||
|
@ -9,36 +9,66 @@ import 'package:logging/logging.dart';
|
|||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:test/src/executable.dart' as executable;
|
import 'package:test/src/executable.dart' as executable;
|
||||||
|
|
||||||
import 'flutter_command.dart';
|
import '../artifacts.dart';
|
||||||
|
import '../build_configuration.dart';
|
||||||
import '../test/loader.dart' as loader;
|
import '../test/loader.dart' as loader;
|
||||||
|
import 'flutter_command.dart';
|
||||||
|
|
||||||
final Logger _logging = new Logger('sky_tools.test');
|
final Logger _logging = new Logger('sky_tools.test');
|
||||||
|
|
||||||
class TestCommand extends FlutterCommand {
|
class TestCommand extends FlutterCommand {
|
||||||
final String name = 'test';
|
String get name => 'test';
|
||||||
final String description = 'Runs Flutter unit tests for the current project (requires a local build of the engine).';
|
String get description => 'Runs Flutter unit tests for the current project. At least one of --debug and --release must be set.';
|
||||||
|
|
||||||
TestCommand() {
|
bool get requiresProjectRoot => false;
|
||||||
argParser.addOption('build-dir', help: 'The directory in which to find a prebuilt engine');
|
|
||||||
}
|
|
||||||
|
|
||||||
String get _shellPath {
|
String getShellPath(TargetPlatform platform, String buildPath) {
|
||||||
if (Platform.isLinux)
|
switch (platform) {
|
||||||
return path.join(argResults['build-dir'], 'sky_shell');
|
case TargetPlatform.linux:
|
||||||
if (Platform.isMacOS)
|
return path.join(buildPath, 'sky_shell');
|
||||||
return path.join(argResults['build-dir'], 'SkyShell.app', 'Contents', 'MacOS', 'SkyShell');
|
case TargetPlatform.mac:
|
||||||
throw new Exception('Unsupported platform.');
|
return path.join(buildPath, 'SkyShell.app', 'Contents', 'MacOS', 'SkyShell');
|
||||||
|
default:
|
||||||
|
throw new Exception('Unsupported platform.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> runInProject() async {
|
Future<int> runInProject() async {
|
||||||
loader.shellPath = _shellPath;
|
List<String> testArgs = argResults.rest.toList();
|
||||||
if (!FileSystemEntity.isFileSync(loader.shellPath)) {
|
Directory testDir = new Directory(path.join(ArtifactStore.flutterRoot, 'packages/unit/test'));
|
||||||
_logging.severe('Cannot find Flutter Shell at ${loader.shellPath}');
|
if (testArgs.isEmpty) {
|
||||||
|
testArgs.addAll(testDir.listSync(recursive: true, followLinks: false)
|
||||||
|
.where((FileSystemEntity entity) => entity.path.endsWith('_test.dart') && FileSystemEntity.isFileSync(entity.path))
|
||||||
|
.map((FileSystemEntity entity) => path.absolute(entity.path)));
|
||||||
|
}
|
||||||
|
testArgs.insert(0, '--');
|
||||||
|
if (Platform.environment['TERM'] == 'dumb')
|
||||||
|
testArgs.insert(0, '--no-color');
|
||||||
|
List<BuildConfiguration> configs = buildConfigurations;
|
||||||
|
bool foundOne = false;
|
||||||
|
String currentDirectory = Directory.current.path;
|
||||||
|
Directory.current = testDir.path;
|
||||||
|
// TODO(ianh): Verify that this directory has had 'pub get' run in it at least once.
|
||||||
|
loader.installHook();
|
||||||
|
for (BuildConfiguration config in configs) {
|
||||||
|
if (!config.testable)
|
||||||
|
continue;
|
||||||
|
foundOne = true;
|
||||||
|
loader.shellPath = path.join(currentDirectory, getShellPath(config.targetPlatform, config.buildDir));
|
||||||
|
if (!FileSystemEntity.isFileSync(loader.shellPath)) {
|
||||||
|
_logging.severe('Cannot find Flutter shell at ${loader.shellPath}');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
await executable.main(testArgs);
|
||||||
|
if (exitCode != 0)
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
if (!foundOne) {
|
||||||
|
stderr.writeln('At least one of --debug or --release must be set, to specify the local build products to test.');
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
loader.installHook();
|
|
||||||
await executable.main(argResults.rest);
|
return 0;
|
||||||
return exitCode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -920,6 +920,7 @@ class DeviceStore {
|
|||||||
assert(iOSSimulator == null);
|
assert(iOSSimulator == null);
|
||||||
iOSSimulator = new IOSSimulator();
|
iOSSimulator = new IOSSimulator();
|
||||||
break;
|
break;
|
||||||
|
case TargetPlatform.mac:
|
||||||
case TargetPlatform.linux:
|
case TargetPlatform.linux:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6,4 +6,4 @@ set -ex
|
|||||||
(cd packages/flx; pub global run tuneup check; pub run test -j1)
|
(cd packages/flx; pub global run tuneup check; pub run test -j1)
|
||||||
(cd packages/newton; pub global run tuneup check; pub run test -j1)
|
(cd packages/newton; pub global run tuneup check; pub run test -j1)
|
||||||
|
|
||||||
./dev/run_tests --engine-src-path bin/cache/travis
|
./bin/flutter test --engine-src-path bin/cache/travis
|
||||||
|
Loading…
x
Reference in New Issue
Block a user