build static method

Future<EnsembleTestExecutionPlan> build({
  1. EnsembleTestAppTarget? target,
  2. EnsembleTestSelection selection = const EnsembleTestSelection(),
})

Discovers assets, parses every file, validates graph, returns run order.

Implementation

static Future<EnsembleTestExecutionPlan> build({
  EnsembleTestAppTarget? target,
  EnsembleTestSelection selection = const EnsembleTestSelection(),
}) async {
  final resolvedTarget =
      target ?? await EnsembleTestDiscovery.loadAppTarget();
  final paths = await EnsembleTestDiscovery.findTestYamlAssets(
    resolvedTarget.testsAssetPrefix,
  );
  if (paths.isEmpty) {
    throw EnsembleTestFailure(
      'No declarative tests found. Add *.test.yaml files under '
      '${resolvedTarget.testsAssetPrefix}',
    );
  }

  final byId = <String, EnsembleTestDefinition>{};
  for (final path in paths) {
    final testCase = await EnsembleTestParser.parseFile(path);
    final existing = byId[testCase.id];
    if (existing != null) {
      throw EnsembleTestFailure(
        'Duplicate test id "${testCase.id}" in ${existing.assetPath} and $path',
      );
    }
    byId[testCase.id] = EnsembleTestDefinition(
      assetPath: path,
      testCase: testCase,
    );
  }

  final selectedById = _applySelection(byId, selection);

  for (final def in selectedById.values) {
    final prereq = def.testCase.prerequisite;
    if (prereq != null && !selectedById.containsKey(prereq)) {
      throw EnsembleTestFailure(
        'Test "${def.testCase.id}" in ${def.assetPath} references unknown '
        'prerequisite "$prereq"',
      );
    }
  }

  final ordered = _topologicalSort(selectedById);
  return EnsembleTestExecutionPlan(ordered: ordered);
}