Commit 587b5bce authored by Adam Barth's avatar Adam Barth

Merge pull request #554 from abarth/test_outside_repo

Make it possible to run tests outside the Flutter repo
parents c60bb1b1 c7e00449
......@@ -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',
......
......@@ -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<BuildConfiguration> get buildConfigurations => runner.buildConfigurations;
Future downloadApplicationPackages() async {
......@@ -48,19 +54,19 @@ abstract class FlutterCommand extends Command {
}
Future<int> 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<int> runInProject();
ApplicationPackageStore applicationPackages;
......
......@@ -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<String> _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<int> _runTests(List<String> testArgs, Directory testDirectory) async {
Directory currentDirectory = Directory.current;
try {
Directory.current = testDirectory;
return await executable.main(testArgs);
} finally {
Directory.current = currentDirectory;
}
}
@override
Future<int> runInProject() async {
List<String> 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<String> 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<BuildConfiguration> 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
}
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment