testBuildHook function

Future<void> testBuildHook({
  1. required void extraInputSetup(
    1. BuildInputBuilder
    ),
  2. required FutureOr<void> mainMethod(
    1. List<String> arguments
    ),
  3. required FutureOr<void> check(
    1. BuildInput input,
    2. BuildOutput output
    ),
  4. bool? linkingEnabled,
})

Validate a build hook; this will throw an exception on validation errors.

This is intended to be used from tests, e.g.:

test('test my build hook', () async {
  await testCodeBuildHook(
    ...
  );
});

Implementation

Future<void> testBuildHook({
  required void Function(BuildInputBuilder) extraInputSetup,
  required FutureOr<void> Function(List<String> arguments) mainMethod,
  required FutureOr<void> Function(BuildInput input, BuildOutput output) check,
  bool? linkingEnabled,
}) async {
  const keepTempKey = 'KEEP_TEMPORARY_DIRECTORIES';

  final tempDir = await Directory.systemTemp.createTemp();

  try {
    // Deal with Windows temp folder aliases.
    final tempUri =
        Directory(await tempDir.resolveSymbolicLinks()).uri.normalizePath();
    final outputDirectory = tempUri.resolve('output/');
    final outputDirectoryShared = tempUri.resolve('output_shared/');
    final outputFile = tempUri.resolve('output.json');

    await Directory.fromUri(outputDirectory).create();
    await Directory.fromUri(outputDirectoryShared).create();

    final inputBuilder = BuildInputBuilder();
    inputBuilder
      ..setupShared(
        packageRoot: Directory.current.uri,
        packageName: _readPackageNameFromPubspec(),
        outputFile: outputFile,
        outputDirectory: outputDirectory,
        outputDirectoryShared: outputDirectoryShared,
      )
      ..config.setupBuild(linkingEnabled: true);
    extraInputSetup(inputBuilder);

    final input = BuildInput(inputBuilder.json);

    final inputUri = tempUri.resolve('input.json');
    _writeJsonTo(inputUri, input.json);
    await mainMethod(['--config=${inputUri.toFilePath()}']);
    final output = BuildOutput(_readJsonFrom(input.outputFile));

    // Test conformance of protocol invariants.
    final validationErrors = await validateBuildOutput(input, output);
    if (validationErrors.isNotEmpty) {
      throw ValidationFailure(
        'encountered build output validation issues: $validationErrors',
      );
    }

    // Run user-defined tests.
    await check(input, output);
  } finally {
    final keepTempDir = (Platform.environment[keepTempKey] ?? '').isNotEmpty;
    if (!keepTempDir) {
      tempDir.deleteSync(recursive: true);
    } else {
      print('$keepTempKey ${tempDir.uri}');
    }
  }
}