modeAppsOf function
The apps with every module of modules for the other values of the
mode options of their roles (see RoleOption.mode): each app of
everyModuleAppsOf once more for every combination of the values of
the mode options of its roles, but the combination of the first value
of each, which is that app itself (see ContractHarness.casesOfModes).
Each is an app with every module too: it has the
MatrixApp.everyModuleWith of the app with its modules, so the tests
that a matrix runs in its apps with every module run in it, and its
MatrixApp.modes tell it from that app. None for modules without a
role with a mode option, and none for an option that roleOptions, the
options of every app, give a value.
The harness renders all of them in memory, and those that it finds
errors in are among the failed ones. A run of the matrix generates
only those that its selection takes (see
EveryModuleSelection.selectModes). CI generates none of them to build
it for a platform or to start it on a device: the apps of those jobs
are apps of everyModuleAppsOf, which get no value of a mode option
from the matrix, and so the first one.
Implementation
Future<({List<MatrixApp> apps, List<ContractResult> failed})> modeAppsOf(
List<SmfModule> modules, {
Map<String, String?> roleOptions = const {},
}) async {
final registry = ModuleRegistry(modules);
final harness = ContractHarness(registry, roleOptions: roleOptions);
final apps = <MatrixApp>[];
final failed = <ContractResult>[];
for (final contractCase in harness.casesOfModes()) {
final result = await harness.check(contractCase);
final app = _appOf(
result,
harness,
everyModuleWith: _everyModuleWith(contractCase, registry),
);
switch (app) {
case final app?:
apps.add(app);
case null:
failed.add(result);
}
}
return (apps: apps, failed: failed);
}