[flutter_plugin_tools] Migrate java-test to new base command (#4105)

Switches `java-test` to the new base command that handles the boilerplate of looping over target packages.

Includes test improvements:
- Adds failure tests; previously no failure cases were covered.
- Captures output so test output isn't spammed with command output.

Part of flutter/flutter#83413
This commit is contained in:
stuartmorgan
2021-06-28 11:26:34 -07:00
committed by GitHub
parent 355ffc0a88
commit 40162caa65
2 changed files with 84 additions and 41 deletions

View File

@ -6,17 +6,19 @@ import 'package:file/file.dart';
import 'package:path/path.dart' as p;
import 'common/core.dart';
import 'common/plugin_command.dart';
import 'common/package_looping_command.dart';
import 'common/process_runner.dart';
/// A command to run the Java tests of Android plugins.
class JavaTestCommand extends PluginCommand {
class JavaTestCommand extends PackageLoopingCommand {
/// Creates an instance of the test runner.
JavaTestCommand(
Directory packagesDir, {
ProcessRunner processRunner = const ProcessRunner(),
}) : super(packagesDir, processRunner: processRunner);
static const String _gradleWrapper = 'gradlew';
@override
final String name = 'java-test';
@ -25,12 +27,10 @@ class JavaTestCommand extends PluginCommand {
'Building the apks of the example apps is required before executing this'
'command.';
static const String _gradleWrapper = 'gradlew';
@override
Future<void> run() async {
final Stream<Directory> examplesWithTests = getExamples().where(
(Directory d) =>
Future<List<String>> runForPackage(Directory package) async {
final Iterable<Directory> examplesWithTests = getExamplesForPlugin(package)
.where((Directory d) =>
isFlutterPackage(d) &&
(d
.childDirectory('android')
@ -44,18 +44,17 @@ class JavaTestCommand extends PluginCommand {
.childDirectory('test')
.existsSync()));
final List<String> failingPackages = <String>[];
final List<String> missingFlutterBuild = <String>[];
await for (final Directory example in examplesWithTests) {
final String packageName =
p.relative(example.path, from: packagesDir.path);
print('\nRUNNING JAVA TESTS for $packageName');
final List<String> errors = <String>[];
for (final Directory example in examplesWithTests) {
final String exampleName = p.relative(example.path, from: package.path);
print('\nRUNNING JAVA TESTS for $exampleName');
final Directory androidDirectory = example.childDirectory('android');
if (!androidDirectory.childFile(_gradleWrapper).existsSync()) {
print('ERROR: Run "flutter build apk" on example app of $packageName'
printError('ERROR: Run "flutter build apk" on $exampleName, or run '
'this tool\'s "build-examples --apk" command, '
'before executing tests.');
missingFlutterBuild.add(packageName);
errors.add('$exampleName has not been built.');
continue;
}
@ -64,31 +63,9 @@ class JavaTestCommand extends PluginCommand {
<String>['testDebugUnitTest', '--info'],
workingDir: androidDirectory);
if (exitCode != 0) {
failingPackages.add(packageName);
errors.add('$exampleName tests failed.');
}
}
print('\n\n');
if (failingPackages.isNotEmpty) {
print(
'The Java tests for the following packages are failing (see above for'
'details):');
for (final String package in failingPackages) {
print(' * $package');
}
}
if (missingFlutterBuild.isNotEmpty) {
print('Run "pub global run flutter_plugin_tools build-examples --apk" on'
'the following packages before executing tests again:');
for (final String package in missingFlutterBuild) {
print(' * $package');
}
}
if (failingPackages.isNotEmpty || missingFlutterBuild.isNotEmpty) {
throw ToolExit(1);
}
print('All Java tests successful!');
return errors;
}
}

View File

@ -11,6 +11,7 @@ import 'package:flutter_plugin_tools/src/java_test_command.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'mocks.dart';
import 'util.dart';
void main() {
@ -45,7 +46,7 @@ void main() {
],
);
await runner.run(<String>['java-test']);
await runCapturingPrint(runner, <String>['java-test']);
expect(
processRunner.recordedCalls,
@ -72,7 +73,7 @@ void main() {
],
);
await runner.run(<String>['java-test']);
await runCapturingPrint(runner, <String>['java-test']);
expect(
processRunner.recordedCalls,
@ -85,5 +86,70 @@ void main() {
]),
);
});
test('fails when the app needs to be built', () async {
createFakePlugin(
'plugin1',
packagesDir,
platformSupport: <String, PlatformSupport>{
kPlatformAndroid: PlatformSupport.inline
},
extraFiles: <String>[
'example/android/app/src/test/example_test.java',
],
);
Error? commandError;
final List<String> output = await runCapturingPrint(
runner, <String>['java-test'], errorHandler: (Error e) {
commandError = e;
});
expect(commandError, isA<ToolExit>());
expect(
output,
containsAllInOrder(<Matcher>[
contains('ERROR: Run "flutter build apk" on example'),
contains('plugin1:\n'
' example has not been built.')
]),
);
});
test('fails when a test fails', () async {
createFakePlugin(
'plugin1',
packagesDir,
platformSupport: <String, PlatformSupport>{
kPlatformAndroid: PlatformSupport.inline
},
extraFiles: <String>[
'example/android/gradlew',
'example/android/app/src/test/example_test.java',
],
);
// Simulate failure from `gradlew`.
final MockProcess mockDriveProcess = MockProcess();
mockDriveProcess.exitCodeCompleter.complete(1);
processRunner.processToReturn = mockDriveProcess;
Error? commandError;
final List<String> output = await runCapturingPrint(
runner, <String>['java-test'], errorHandler: (Error e) {
commandError = e;
});
expect(commandError, isA<ToolExit>());
expect(
output,
containsAllInOrder(<Matcher>[
contains('plugin1:\n'
' example tests failed.')
]),
);
});
});
}