mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

This prevents multiple simultaneous runs of the analyzer from stomping over each other (e.g. multiple runs of 'update-packages'). Certain long-lived commands (like analyze, run, logs) are exempted once they've done enough work to be safe from most stomping action. This still doesn't make us entirely safe from craziness, e.g. if you're half way through an 'update-packages' run and you call 'git pull', who knows what state you'll end up in. But there's only so much one can do. Fixes https://github.com/flutter/flutter/issues/2762
111 lines
3.4 KiB
Dart
111 lines
3.4 KiB
Dart
// 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 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:path/path.dart' as path;
|
|
import 'package:test/src/executable.dart' as executable; // ignore: implementation_imports
|
|
|
|
import '../base/logger.dart';
|
|
import '../cache.dart';
|
|
import '../dart/package_map.dart';
|
|
import '../globals.dart';
|
|
import '../runner/flutter_command.dart';
|
|
import '../test/flutter_platform.dart' as loader;
|
|
import '../toolchain.dart';
|
|
|
|
class TestCommand extends FlutterCommand {
|
|
TestCommand() {
|
|
usesPubOption();
|
|
}
|
|
|
|
@override
|
|
String get name => 'test';
|
|
|
|
@override
|
|
String get description => 'Run Flutter unit tests for the current project.';
|
|
|
|
@override
|
|
bool get requiresProjectRoot => false;
|
|
|
|
@override
|
|
Validator projectRootValidator = () {
|
|
if (!FileSystemEntity.isFileSync('pubspec.yaml')) {
|
|
printError(
|
|
'Error: No pubspec.yaml file found in the current working directory.\n'
|
|
'Run this command from the root of your project. Test files must be\n'
|
|
'called *_test.dart and must reside in the package\'s \'test\'\n'
|
|
'directory (or one of its subdirectories).');
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
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 _currentPackageTestDir {
|
|
// We don't scan the entire package, only the test/ subdirectory, so that
|
|
// files with names like like "hit_test.dart" don't get run.
|
|
return new Directory('test');
|
|
}
|
|
|
|
Future<int> _runTests(List<String> testArgs, Directory testDirectory) async {
|
|
Directory currentDirectory = Directory.current;
|
|
try {
|
|
if (testDirectory != null) {
|
|
printTrace('switching to directory $testDirectory to run tests');
|
|
PackageMap.globalPackagesPath = path.normalize(path.absolute(PackageMap.globalPackagesPath));
|
|
Directory.current = testDirectory;
|
|
}
|
|
printTrace('running test package with arguments: $testArgs');
|
|
await executable.main(testArgs);
|
|
printTrace('test package returned with exit code $exitCode');
|
|
return exitCode;
|
|
} finally {
|
|
Directory.current = currentDirectory;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<int> runInProject() async {
|
|
List<String> testArgs = argResults.rest.map((String testPath) => path.absolute(testPath)).toList();
|
|
|
|
if (!projectRootValidator())
|
|
return 1;
|
|
|
|
Directory testDir;
|
|
|
|
if (testArgs.isEmpty) {
|
|
testDir = _currentPackageTestDir;
|
|
if (!testDir.existsSync()) {
|
|
printError("Test directory '${testDir.path}' not found.");
|
|
return 1;
|
|
}
|
|
|
|
testArgs.addAll(_findTests(testDir));
|
|
}
|
|
|
|
testArgs.insert(0, '--');
|
|
if (!terminal.supportsColor)
|
|
testArgs.insert(0, '--no-color');
|
|
|
|
loader.installHook();
|
|
loader.shellPath = tools.getHostToolPath(HostTool.SkyShell);
|
|
if (!FileSystemEntity.isFileSync(loader.shellPath)) {
|
|
printError('Cannot find Flutter shell at ${loader.shellPath}');
|
|
return 1;
|
|
}
|
|
|
|
Cache.releaseLockEarly();
|
|
|
|
return await _runTests(testArgs, testDir);
|
|
}
|
|
}
|