diff --git a/script/tool/lib/src/java_test_command.dart b/script/tool/lib/src/java_test_command.dart index d7e453b6ad74..77b8aa70a6e4 100644 --- a/script/tool/lib/src/java_test_command.dart +++ b/script/tool/lib/src/java_test_command.dart @@ -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 run() async { - final Stream examplesWithTests = getExamples().where( - (Directory d) => + Future> runForPackage(Directory package) async { + final Iterable examplesWithTests = getExamplesForPlugin(package) + .where((Directory d) => isFlutterPackage(d) && (d .childDirectory('android') @@ -44,18 +44,17 @@ class JavaTestCommand extends PluginCommand { .childDirectory('test') .existsSync())); - final List failingPackages = []; - final List missingFlutterBuild = []; - 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 errors = []; + 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 { ['testDebugUnitTest', '--info'], workingDir: androidDirectory); if (exitCode != 0) { - failingPackages.add(packageName); - } - } - - 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'); + errors.add('$exampleName tests failed.'); } } - - if (failingPackages.isNotEmpty || missingFlutterBuild.isNotEmpty) { - throw ToolExit(1); - } - - print('All Java tests successful!'); + return errors; } } diff --git a/script/tool/test/java_test_command_test.dart b/script/tool/test/java_test_command_test.dart index fc80961462c7..894a5c3fce70 100644 --- a/script/tool/test/java_test_command_test.dart +++ b/script/tool/test/java_test_command_test.dart @@ -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(['java-test']); + await runCapturingPrint(runner, ['java-test']); expect( processRunner.recordedCalls, @@ -72,7 +73,7 @@ void main() { ], ); - await runner.run(['java-test']); + await runCapturingPrint(runner, ['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: { + kPlatformAndroid: PlatformSupport.inline + }, + extraFiles: [ + 'example/android/app/src/test/example_test.java', + ], + ); + + Error? commandError; + final List output = await runCapturingPrint( + runner, ['java-test'], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + + expect( + output, + containsAllInOrder([ + 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: { + kPlatformAndroid: PlatformSupport.inline + }, + extraFiles: [ + '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 output = await runCapturingPrint( + runner, ['java-test'], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + + expect( + output, + containsAllInOrder([ + contains('plugin1:\n' + ' example tests failed.') + ]), + ); + }); }); }