matrixOf function
The apps of the matrix of modules: every app that the contract harness
builds for them, which covers every module and every provider with each
subset of the roles it uses, and the apps with every module, one for each
combination of the providers of roles that take one
(see ContractHarness.casesOfAll).
Each app gets roleOptions, the values of role options for every app,
the options of its case, and the answers of the harness to the
questions of the roles that they leave open (see
ContractResult.answers), such as --start with the first of several
screens that can start the app: smf create then makes the same
choices without a terminal. The harness renders each app in memory
first, so a case that it finds errors in is among the failed ones,
since its app could not be generated.
Implementation
Future<({List<MatrixApp> apps, List<ContractResult> failed})> matrixOf(
List<SmfModule> modules, {
Map<String, String?> roleOptions = const {},
}) async {
final harness = ContractHarness(
ModuleRegistry(modules),
roleOptions: roleOptions,
);
final results = [
...await harness.checkAll(),
for (final contractCase in harness.casesOfAll())
await harness.check(contractCase),
];
final apps = <MatrixApp>[];
final failed = <ContractResult>[];
final keys = <String>{};
for (final result in results) {
final resolution = result.resolution;
if (result.errors.isNotEmpty || resolution == null) {
failed.add(result);
continue;
}
if (!keys.add(result.appKey!)) continue;
apps.add(
MatrixApp(
'${result.contractCase}',
[for (final module in resolution.modules) module.id],
roleOptions: {
...roleOptions,
...result.contractCase.roleOptions,
...result.answers,
},
),
);
}
return (apps: apps, failed: failed);
}