resolveSources<T> function Null safety

Future<T> resolveSources<T>(
  1. Map<String, String> inputs,
  2. FutureOr<T> action(
    1. Resolver resolver
    ),
  3. {PackageConfig? packageConfig,
  4. String? resolverFor,
  5. String? rootPackage,
  6. Future<void>? tearDown,
  7. Resolvers? resolvers}
)

Resolves and runs action using a created resolver for inputs.

Inputs accepts the pattern of <package>|<path>.dart, for example:

{
  'test_lib|lib/test_lib.dart': r'''
    // Contents of test_lib.dart go here.
  ''',
}

You may provide useAssetReader as the value of any input in order to read it from the file system instead of being forced to provide it inline as a string. This is useful for mixing real and mocked assets.

Example use:

import 'package:build_test/build_test.dart';
import 'package:test/test.dart';

void main() {
  test('should find a Foo type', () async {
    var library = await resolveSources({
      'test_lib|lib/test_lib.dart': r'''
        library example;

        class Foo {}
      ''',
    }, (resolver) => resolver.findLibraryByName('example'));
    expect(library.getType('Foo'), isNotNull);
  });
}

By default the Resolver is unusable after action completes. To keep the resolver active across multiple tests (for example, use setUpAll and tearDownAll, provide a tearDown Future:

import 'dart:async';
import 'package:build/build.dart';
import 'package:build_test/build_test.dart';
import 'package:test/test.dart';

void main() {
  Resolver resolver;
  var resolverDone = new Completer<Null>();

  setUpAll(() async {
    resolver = await resolveSources(
      {...},
      (resolver) => resolver,
      tearDown: resolverDone.future,
    );
  });

  tearDownAll(() => resolverDone.complete());

  test('...', () async {
    // Use the resolver here, and in other tests.
  });
}

May provide resolverFor to return the Resolver for the asset provided, otherwise defaults to the first one in inputs.

NOTE: All package dependencies are resolved using PackageAssetReader

Implementation

Future<T> resolveSources<T>(
  Map<String, String> inputs,
  FutureOr<T> Function(Resolver resolver) action, {
  PackageConfig? packageConfig,
  String? resolverFor,
  String? rootPackage,
  Future<void>? tearDown,
  Resolvers? resolvers,
}) {
  if (inputs.isEmpty) {
    throw ArgumentError.value(inputs, 'inputs', 'Must be a non-empty Map');
  }
  return _resolveAssets(
    inputs,
    rootPackage ?? AssetId.parse(inputs.keys.first).package,
    action,
    packageConfig: packageConfig,
    resolverFor: AssetId.parse(resolverFor ?? inputs.keys.first),
    tearDown: tearDown,
    resolvers: resolvers,
  );
}