checkOutputs function Null safety

void checkOutputs(
  1. Map<String, Object>? outputs,
  2. Iterable<AssetId> actualAssets,
  3. RecordingAssetWriter writer,
  4. {AssetId mapAssetIds(
    1. AssetId id
    ) = _passThrough}
)

Validates that actualAssets matches the expected outputs.

The keys in outputs should be serialized AssetIds in the form 'package|path'. The values should match the expected content for the written asset and may be a String which will match against the utf8 decoded bytes, a List<int> matching the raw bytes, or a Matcher for a List<int> of bytes. For writing a Matcher against the String contents, you can wrap your Matcher in a call to decodedMatches.

actualAssets are the IDs that were recorded as written during the build.

Assets are checked against those that were written to writer. If other assets were written through the writer, but not as part of the build process, they will be ignored. Only the IDs in actualAssets are checked.

If assets are written to a location that does not match their logical association to a package pass mapAssetIds to translate from the logical location to the actual written location.

Implementation

void checkOutputs(
    Map<String, /*List<int>|String|Matcher<List<int>>*/ Object>? outputs,
    Iterable<AssetId> actualAssets,
    RecordingAssetWriter writer,
    {AssetId Function(AssetId id) mapAssetIds = _passThrough}) {
  var modifiableActualAssets = Set.from(actualAssets);
  if (outputs != null) {
    outputs.forEach((serializedId, contentsMatcher) {
      assert(contentsMatcher is String ||
          contentsMatcher is List<int> ||
          contentsMatcher is Matcher);

      var assetId = makeAssetId(serializedId);

      // Check that the asset was produced.
      expect(modifiableActualAssets, contains(assetId),
          reason: 'Builder failed to write asset $assetId');
      modifiableActualAssets.remove(assetId);
      var actual = writer.assets[mapAssetIds(assetId)]!;
      Object expected;
      if (contentsMatcher is String) {
        expected = utf8.decode(actual);
      } else if (contentsMatcher is List<int>) {
        expected = actual;
      } else if (contentsMatcher is Matcher) {
        expected = actual;
      } else {
        throw ArgumentError('Expected values for `outputs` to be of type '
            '`String`, `List<int>`, or `Matcher`, but got `$contentsMatcher`.');
      }
      expect(expected, contentsMatcher,
          reason: 'Unexpected content for $assetId in result.outputs.');
    });
    // Check that no extra assets were produced.
    expect(modifiableActualAssets, isEmpty,
        reason:
            'Unexpected outputs found `$actualAssets`. Only expected $outputs');
  }
}