From c7e00449a87de83c0c631d1875bd05053c2e1f0d Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Mon, 23 Nov 2015 13:31:24 -0800 Subject: [PATCH] Make it possible to run tests outside the Flutter repo This patch still requires a locally built engine. I'll remove the need for a locally built engine in a future patch. Fixes #278 --- packages/flutter_tools/lib/src/artifacts.dart | 18 +++--- .../lib/src/commands/flutter_command.dart | 26 +++++---- .../flutter_tools/lib/src/commands/test.dart | 57 ++++++++++++++----- travis/test.sh | 2 +- 4 files changed, 71 insertions(+), 32 deletions(-) diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart index 0b70f5c590..345a527177 100644 --- a/packages/flutter_tools/lib/src/artifacts.dart +++ b/packages/flutter_tools/lib/src/artifacts.dart @@ -83,15 +83,11 @@ class Artifact { return null; } - String getUrl(String revision) { - return _getCloudStorageBaseUrl( - platform: platform, - revision: revision - ) + fileName; - } - // Whether the artifact needs to be marked as executable on disk. - bool get executable => type == ArtifactType.snapshot; + bool get executable { + return type == ArtifactType.snapshot || + (type == ArtifactType.shell && targetPlatform == TargetPlatform.linux); + } } class ArtifactStore { @@ -102,6 +98,12 @@ class ArtifactStore { type: ArtifactType.shell, targetPlatform: TargetPlatform.android ), + const Artifact._( + name: 'Sky Shell', + fileName: 'sky_shell', + type: ArtifactType.shell, + targetPlatform: TargetPlatform.linux + ), const Artifact._( name: 'Sky Snapshot', fileName: 'sky_snapshot', diff --git a/packages/flutter_tools/lib/src/commands/flutter_command.dart b/packages/flutter_tools/lib/src/commands/flutter_command.dart index 7838bebf51..6aa76eb2a4 100644 --- a/packages/flutter_tools/lib/src/commands/flutter_command.dart +++ b/packages/flutter_tools/lib/src/commands/flutter_command.dart @@ -19,6 +19,12 @@ abstract class FlutterCommand extends Command { /// Whether this command needs to be run from the root of a project. bool get requiresProjectRoot => true; + String get projectRootValidationErrorMessage { + return 'Error: No pubspec.yaml file found.\n' + 'This command should be run from the root of your Flutter project. Do not run\n' + 'this command from the root of your git clone of Flutter.'; + } + List get buildConfigurations => runner.buildConfigurations; Future downloadApplicationPackages() async { @@ -48,19 +54,19 @@ abstract class FlutterCommand extends Command { } Future run() async { - if (requiresProjectRoot) { - if (!FileSystemEntity.isFileSync('pubspec.yaml')) { - stderr.writeln('Error: No pubspec.yaml file found. ' - 'This command should be run from the root of your Flutter project. ' - 'Do not run this command from the root of your git clone ' - 'of Flutter.'); - return 1; - } - } - + if (requiresProjectRoot && !validateProjectRoot()) + return 1; return await runInProject(); } + bool validateProjectRoot() { + if (!FileSystemEntity.isFileSync('pubspec.yaml')) { + stderr.writeln(projectRootValidationErrorMessage); + return false; + } + return true; + } + Future runInProject(); ApplicationPackageStore applicationPackages; diff --git a/packages/flutter_tools/lib/src/commands/test.dart b/packages/flutter_tools/lib/src/commands/test.dart index 5d268345c9..f721936cc4 100644 --- a/packages/flutter_tools/lib/src/commands/test.dart +++ b/packages/flutter_tools/lib/src/commands/test.dart @@ -22,6 +22,12 @@ class TestCommand extends FlutterCommand { bool get requiresProjectRoot => false; + String get projectRootValidationErrorMessage { + return 'Error: No pubspec.yaml file found.\n' + 'If you wish to run the tests in the flutter repo, pass --flutter-repo before\n' + 'any test paths. Otherwise, run this command from the root of your project.'; + } + String getShellPath(TargetPlatform platform, String buildPath) { switch (platform) { case TargetPlatform.linux: @@ -33,34 +39,59 @@ class TestCommand extends FlutterCommand { } } + TestCommand() { + argParser.addFlag('flutter-repo', help: 'Run tests from the Flutter repository instead of the current directory.', defaultsTo: false); + } + + Iterable _findTests(Directory directory) { + return directory.listSync(recursive: true, followLinks: false) + .where((FileSystemEntity entity) => entity.path.endsWith('_test.dart') && FileSystemEntity.isFileSync(entity.path)) + .map((FileSystemEntity entity) => path.absolute(entity.path)); + } + + Directory get _flutterUnitTestDir { + return new Directory(path.join(ArtifactStore.flutterRoot, 'packages', 'unit', 'test')); + } + + Future _runTests(List testArgs, Directory testDirectory) async { + Directory currentDirectory = Directory.current; + try { + Directory.current = testDirectory; + return await executable.main(testArgs); + } finally { + Directory.current = currentDirectory; + } + } + @override Future runInProject() async { - List testArgs = argResults.rest.toList(); - Directory flutterDir = new Directory(path.join(ArtifactStore.flutterRoot, 'packages/unit')); // see https://github.com/flutter/flutter/issues/50 - Directory testDir = new Directory(path.join(flutterDir.path, 'test')); - 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))); - } + List testArgs = argResults.rest.map((String testPath) => path.absolute(testPath)).toList(); + + final bool runFlutterTests = argResults['flutter-repo']; + if (!runFlutterTests && !validateProjectRoot()) + return 1; + + Directory testDir = runFlutterTests ? _flutterUnitTestDir : Directory.current; + + if (testArgs.isEmpty) + testArgs.addAll(_findTests(testDir)); + testArgs.insert(0, '--'); if (Platform.environment['TERM'] == 'dumb') testArgs.insert(0, '--no-color'); List configs = buildConfigurations; bool foundOne = false; - String currentDirectory = Directory.current.path; - Directory.current = flutterDir.path; loader.installHook(); for (BuildConfiguration config in configs) { if (!config.testable) continue; foundOne = true; - loader.shellPath = path.join(currentDirectory, getShellPath(config.targetPlatform, config.buildDir)); + loader.shellPath = path.join(Directory.current.path, 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); + await _runTests(testArgs, testDir); if (exitCode != 0) return exitCode; } @@ -71,4 +102,4 @@ class TestCommand extends FlutterCommand { return 0; } -} \ No newline at end of file +} diff --git a/travis/test.sh b/travis/test.sh index fa5e48b779..cd713cbc39 100755 --- a/travis/test.sh +++ b/travis/test.sh @@ -5,7 +5,7 @@ set -ex ./bin/flutter analyze --flutter-repo --no-current-directory --no-current-package --congratulate # flutter package tests -./bin/flutter test --engine-src-path bin/cache/travis +./bin/flutter test --flutter-repo --engine-src-path bin/cache/travis (cd packages/cassowary; pub run test -j1) # (cd packages/flutter_sprites; ) # No tests to run.