mirror of
https://github.com/flutter/packages.git
synced 2025-05-25 16:58:01 +08:00
[flutter_plugin_tools] Make no unit tests fatal for iOS/macOS (#4341)
Brings iOS and macOS into alignment with the other platforms, where having unit tests set up is required. - For deprecated plugins with no tests, `--exclude`s them, as on other platforms. - For `quick_actions` and `share`, which have integration tests but no unit tests, sets up the unit test scaffolding. (This is done for `share` even though it's deprecated since unlike other platforms, iOS/macOS runs both native tests in the same command, and setting up a special way to exclude just units tests for that one case would be much more effort.) Fixes flutter/flutter#85469
This commit is contained in:
@ -251,8 +251,6 @@ this command.
|
||||
final bool hasIntegrationTests =
|
||||
exampleHasNativeIntegrationTests(example);
|
||||
|
||||
// TODO(stuartmorgan): Make !hasUnitTests fatal. See
|
||||
// https://github.com/flutter/flutter/issues/85469
|
||||
if (mode.unit && !hasUnitTests) {
|
||||
_printNoExampleTestsMessage(example, 'Android unit');
|
||||
}
|
||||
@ -355,33 +353,40 @@ this command.
|
||||
List<String> extraFlags = const <String>[],
|
||||
}) async {
|
||||
String? testTarget;
|
||||
const String unitTestTarget = 'RunnerTests';
|
||||
if (mode.unitOnly) {
|
||||
testTarget = 'RunnerTests';
|
||||
testTarget = unitTestTarget;
|
||||
} else if (mode.integrationOnly) {
|
||||
testTarget = 'RunnerUITests';
|
||||
}
|
||||
|
||||
bool ranUnitTests = false;
|
||||
// Assume skipped until at least one test has run.
|
||||
RunState overallResult = RunState.skipped;
|
||||
for (final RepositoryPackage example in plugin.getExamples()) {
|
||||
final String exampleName = example.displayName;
|
||||
|
||||
// TODO(stuartmorgan): Always check for RunnerTests, and make it fatal if
|
||||
// no examples have it. See
|
||||
// https://github.com/flutter/flutter/issues/85469
|
||||
if (testTarget != null) {
|
||||
final Directory project = example.directory
|
||||
.childDirectory(platform.toLowerCase())
|
||||
.childDirectory('Runner.xcodeproj');
|
||||
// If running a specific target, check that. Otherwise, check if there
|
||||
// are unit tests, since having no unit tests for a plugin is fatal
|
||||
// (by repo policy) even if there are integration tests.
|
||||
bool exampleHasUnitTests = false;
|
||||
final String? targetToCheck =
|
||||
testTarget ?? (mode.unit ? unitTestTarget : null);
|
||||
final Directory xcodeProject = example.directory
|
||||
.childDirectory(platform.toLowerCase())
|
||||
.childDirectory('Runner.xcodeproj');
|
||||
if (targetToCheck != null) {
|
||||
final bool? hasTarget =
|
||||
await _xcode.projectHasTarget(project, testTarget);
|
||||
await _xcode.projectHasTarget(xcodeProject, targetToCheck);
|
||||
if (hasTarget == null) {
|
||||
printError('Unable to check targets for $exampleName.');
|
||||
overallResult = RunState.failed;
|
||||
continue;
|
||||
} else if (!hasTarget) {
|
||||
print('No "$testTarget" target in $exampleName; skipping.');
|
||||
print('No "$targetToCheck" target in $exampleName; skipping.');
|
||||
continue;
|
||||
} else if (targetToCheck == unitTestTarget) {
|
||||
exampleHasUnitTests = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,20 +409,39 @@ this command.
|
||||
switch (exitCode) {
|
||||
case _xcodebuildNoTestExitCode:
|
||||
_printNoExampleTestsMessage(example, platform);
|
||||
continue;
|
||||
break;
|
||||
case 0:
|
||||
printSuccess('Successfully ran $platform xctest for $exampleName');
|
||||
// If this is the first test, assume success until something fails.
|
||||
if (overallResult == RunState.skipped) {
|
||||
overallResult = RunState.succeeded;
|
||||
}
|
||||
if (exampleHasUnitTests) {
|
||||
ranUnitTests = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Any failure means a failure overall.
|
||||
overallResult = RunState.failed;
|
||||
// If unit tests ran, note that even if they failed.
|
||||
if (exampleHasUnitTests) {
|
||||
ranUnitTests = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mode.integrationOnly && !ranUnitTests) {
|
||||
printError('No unit tests ran. Plugins are required to have unit tests.');
|
||||
// Only return a specific summary error message about the missing unit
|
||||
// tests if there weren't also failures, to avoid having a misleadingly
|
||||
// specific message.
|
||||
if (overallResult != RunState.failed) {
|
||||
return _PlatformResult(RunState.failed,
|
||||
error: 'No unit tests ran (use --exclude if this is intentional).');
|
||||
}
|
||||
}
|
||||
|
||||
return _PlatformResult(overallResult);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user