// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'dart:core';
import 'dart:io';
import 'dart:typed_data';

import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_goldens/flutter_goldens.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';

import 'json_templates.dart';

const String _kFlutterRoot = '/flutter';

// 1x1 transparent pixel
const List<int> _kTestPngBytes =
<int>[137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0,
  1, 0, 0, 0, 1, 8, 6, 0, 0, 0, 31, 21, 196, 137, 0, 0, 0, 11, 73, 68, 65, 84,
  120, 1, 99, 97, 0, 2, 0, 0, 25, 0, 5, 144, 240, 54, 245, 0, 0, 0, 0, 73, 69,
  78, 68, 174, 66, 96, 130];

// 1x1 colored pixel
const List<int> _kFailPngBytes =
<int>[137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0,
  1, 0, 0, 0, 1, 8, 6, 0, 0, 0, 31, 21, 196, 137, 0, 0, 0, 13, 73, 68, 65, 84,
  120, 1, 99, 249, 207, 240, 255, 63, 0, 7, 18, 3, 2, 164, 147, 160, 197, 0,
  0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130];

void main() {
  MemoryFileSystem fs;
  FakePlatform platform;
  MockProcessManager process;
  MockHttpClient mockHttpClient;

  setUp(() {
    fs = MemoryFileSystem();
    platform = FakePlatform(
      environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
      operatingSystem: 'macos'
    );
    process = MockProcessManager();
    mockHttpClient = MockHttpClient();
    fs.directory(_kFlutterRoot).createSync(recursive: true);
  });

  group('SkiaGoldClient', () {
    SkiaGoldClient skiaClient;

    setUp(() {
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: mockHttpClient,
      );
    });

    group('auth', () {
      test('performs minimal work if already authorized', () async {
        fs.file('/workDirectory/temp/auth_opt.json')
          ..createSync(recursive: true);
        when(process.run(any))
          .thenAnswer((_) => Future<ProcessResult>
            .value(ProcessResult(123, 0, '', '')));
        await skiaClient.auth();

        verifyNever(process.run(
            captureAny,
            workingDirectory: captureAnyNamed('workingDirectory'),
        ));
      });
    });

    group('Request Handling', () {
      String testName;
      String pullRequestNumber;
      String expectation;
      Uri url;
      MockHttpClientRequest mockHttpRequest;

      setUp(() {
        testName = 'flutter.golden_test.1.png';
        pullRequestNumber = '1234';
        expectation = '55109a4bed52acc780530f7a9aeff6c0';
        mockHttpRequest = MockHttpClientRequest();
      });

      test('validates SkiaDigest', () {
        final Map<String, dynamic> skiaJson = json.decode(digestResponseTemplate());
        final SkiaGoldDigest digest = SkiaGoldDigest.fromJson(skiaJson['digest']);
        expect(
          digest.isValid(
            platform,
            'flutter.golden_test.1',
            expectation,
          ),
          isTrue,
        );
      });

      test('invalidates bad SkiaDigest - platform', () {
        final Map<String, dynamic> skiaJson = json.decode(
          digestResponseTemplate(platform: 'linux')
        );
        final SkiaGoldDigest digest = SkiaGoldDigest.fromJson(skiaJson['digest']);
        expect(
          digest.isValid(
            platform,
            'flutter.golden_test.1',
            expectation,
          ),
          isFalse,
        );
      });

      test('invalidates bad SkiaDigest - test name', () {
        final Map<String, dynamic> skiaJson = json.decode(
          digestResponseTemplate(testName: 'flutter.golden_test.2')
        );
        final SkiaGoldDigest digest = SkiaGoldDigest.fromJson(skiaJson['digest']);
        expect(
          digest.isValid(
            platform,
            'flutter.golden_test.1',
            expectation,
          ),
          isFalse,
        );
      });

      test('invalidates bad SkiaDigest - expectation', () {
        final Map<String, dynamic> skiaJson = json.decode(
          digestResponseTemplate(expectation: '1deg543sf645erg44awqcc78')
        );
        final SkiaGoldDigest digest = SkiaGoldDigest.fromJson(skiaJson['digest']);
        expect(
          digest.isValid(
            platform,
            'flutter.golden_test.1',
            expectation,
          ),
          isFalse,
        );
      });

      test('invalidates bad SkiaDigest - status', () {
        final Map<String, dynamic> skiaJson = json.decode(
          digestResponseTemplate(status: 'negative')
        );
        final SkiaGoldDigest digest = SkiaGoldDigest.fromJson(skiaJson['digest']);
        expect(
          digest.isValid(
            platform,
            'flutter.golden_test.1',
            expectation,
          ),
          isFalse,
        );
      });

      test('sets up expectations', () async {
        url = Uri.parse('https://flutter-gold.skia.org/json/expectations/commit/HEAD');
        final MockHttpClientResponse mockHttpResponse = MockHttpClientResponse(
          utf8.encode(rawExpectationsTemplate())
        );
        when(mockHttpClient.getUrl(url))
          .thenAnswer((_) => Future<MockHttpClientRequest>.value(mockHttpRequest));
        when(mockHttpRequest.close())
          .thenAnswer((_) => Future<MockHttpClientResponse>.value(mockHttpResponse));

        await skiaClient.getExpectations();
        expect(skiaClient.expectations, isNotNull);
        expect(
          skiaClient.expectations['flutter.golden_test.1'],
          contains(expectation),
        );
      });

      test('detects invalid digests SkiaDigest', () {
        const String testName = 'flutter.golden_test.2';
        final Map<String, dynamic> skiaJson = json.decode(digestResponseTemplate());
        final SkiaGoldDigest digest = SkiaGoldDigest.fromJson(skiaJson['digest']);
        expect(digest.isValid(platform, testName, expectation), isFalse);
      });

      test('image bytes are processed properly', () async {
        final Uri imageUrl = Uri.parse(
          'https://flutter-gold.skia.org/img/images/$expectation.png'
        );
        final MockHttpClientRequest mockImageRequest = MockHttpClientRequest();
        final MockHttpImageResponse mockImageResponse = MockHttpImageResponse(
          imageResponseTemplate()
        );
        when(mockHttpClient.getUrl(imageUrl))
          .thenAnswer((_) => Future<MockHttpClientRequest>.value(mockImageRequest));
        when(mockImageRequest.close())
          .thenAnswer((_) => Future<MockHttpImageResponse>.value(mockImageResponse));

        final List<int> masterBytes = await skiaClient.getImageBytes(expectation);

        expect(masterBytes, equals(_kTestPngBytes));
      });

      group('ignores', () {
        Uri url;
        MockHttpClientRequest mockHttpRequest;
        MockHttpClientResponse mockHttpResponse;

        setUp(() {
          url = Uri.parse('https://flutter-gold.skia.org/json/ignores');
          mockHttpRequest = MockHttpClientRequest();
          mockHttpResponse = MockHttpClientResponse(utf8.encode(
              ignoreResponseTemplate(
                pullRequestNumber: pullRequestNumber,
                expires: DateTime.now()
                  .add(const Duration(days: 1))
                  .toString(),
                otherTestName: 'unrelatedTest.1'
              )
          ));
          when(mockHttpClient.getUrl(url))
            .thenAnswer((_) => Future<MockHttpClientRequest>.value(mockHttpRequest));
          when(mockHttpRequest.close())
            .thenAnswer((_) => Future<MockHttpClientResponse>.value(mockHttpResponse));
        });

        test('returns true for ignored test and ignored pull request number', () async {
          expect(
            await skiaClient.testIsIgnoredForPullRequest(
              pullRequestNumber,
              testName,
            ),
            isTrue,
          );
        });

        test('returns true for ignored test and not ignored pull request number', () async {
          expect(
            await skiaClient.testIsIgnoredForPullRequest(
              '5678',
              testName,
            ),
            isTrue,
          );
        });

        test('returns false for not ignored test and ignored pull request number', () async {
         expect(
            await skiaClient.testIsIgnoredForPullRequest(
              pullRequestNumber,
              'failure.png',
            ),
            isFalse,
          );
        });

        test('throws exception for expired ignore', () async {
          mockHttpResponse = MockHttpClientResponse(utf8.encode(
            ignoreResponseTemplate(
              pullRequestNumber: pullRequestNumber,
            )
          ));
          when(mockHttpRequest.close())
            .thenAnswer((_) => Future<MockHttpClientResponse>.value(mockHttpResponse));
          final Future<bool> test = skiaClient.testIsIgnoredForPullRequest(
            pullRequestNumber,
            testName,
          );
          expect(
            test,
            throwsException,
          );
        });

        test('throws exception for first expired ignore among multiple', () async {
          mockHttpResponse = MockHttpClientResponse(utf8.encode(
            ignoreResponseTemplate(
              pullRequestNumber: pullRequestNumber,
              otherExpires: DateTime.now()
                .add(const Duration(days: 1))
                .toString(),
            )
          ));
          when(mockHttpRequest.close())
            .thenAnswer((_) => Future<MockHttpClientResponse>.value(mockHttpResponse));
          final Future<bool> test = skiaClient.testIsIgnoredForPullRequest(
            pullRequestNumber,
            testName,
          );
          expect(
            test,
            throwsException,
          );
        });

        test('throws exception for later expired ignore among multiple', () async {
          mockHttpResponse = MockHttpClientResponse(utf8.encode(
            ignoreResponseTemplate(
              pullRequestNumber: pullRequestNumber,
              expires: DateTime.now()
                .add(const Duration(days: 1))
                .toString(),
            )
          ));
          when(mockHttpRequest.close())
            .thenAnswer((_) => Future<MockHttpClientResponse>.value(mockHttpResponse));
          final Future<bool> test = skiaClient.testIsIgnoredForPullRequest(
            pullRequestNumber,
            testName,
          );
          expect(
            test,
            throwsException,
          );
        });
      });

      group('digest parsing', () {
        Uri url;
        MockHttpClientRequest mockHttpRequest;
        MockHttpClientResponse mockHttpResponse;

        setUp(() {
          url = Uri.parse(
            'https://flutter-gold.skia.org/json/details?'
              'test=flutter.golden_test.1&digest=$expectation'
          );
          mockHttpRequest = MockHttpClientRequest();
          when(mockHttpClient.getUrl(url))
            .thenAnswer((_) => Future<MockHttpClientRequest>.value(mockHttpRequest));
        });

        test('succeeds when valid', () async {
          mockHttpResponse = MockHttpClientResponse(utf8.encode(digestResponseTemplate()));
          when(mockHttpRequest.close())
            .thenAnswer((_) => Future<MockHttpClientResponse>.value(mockHttpResponse));
          expect(
            await skiaClient.isValidDigestForExpectation(
              expectation,
              testName,
            ),
            isTrue,
          );
        });

        test('fails when invalid', () async {
          mockHttpResponse = MockHttpClientResponse(utf8.encode(
            digestResponseTemplate(platform: 'linux')
          ));
          when(mockHttpRequest.close())
            .thenAnswer((_) => Future<MockHttpClientResponse>.value(mockHttpResponse));
          expect(
            await skiaClient.isValidDigestForExpectation(
              expectation,
              testName,
            ),
            isFalse,
          );
        });
      });
    });
  });

  group('FlutterGoldenFileComparator', () {
    FlutterSkiaGoldFileComparator comparator;

    setUp(() {
      final Directory basedir = fs.directory('flutter/test/library/')
        ..createSync(recursive: true);
      comparator = FlutterSkiaGoldFileComparator(
        basedir.uri,
        MockSkiaGoldClient(),
        fs: fs,
        platform: platform,
      );
    });

    test('calculates the basedir correctly from defaultComparator', () async {
      final MockLocalFileComparator defaultComparator = MockLocalFileComparator();
      final Directory flutterRoot = fs.directory(platform.environment['FLUTTER_ROOT'])
        ..createSync(recursive: true);
      when(defaultComparator.basedir).thenReturn(flutterRoot.childDirectory('baz').uri);

      final Directory basedir = FlutterGoldenFileComparator.getBaseDirectory(
        defaultComparator,
        platform,
      );
      expect(
        basedir.uri,
        fs.directory('/flutter/bin/cache/pkg/skia_goldens/baz').uri,
      );
    });

    test('ignores version number', () {
      final Uri key = comparator.getTestUri(Uri.parse('foo.png'), 1);
      expect(key, Uri.parse('foo.png'));
    });

    group('Post-Submit', () {
      final MockSkiaGoldClient mockSkiaClient = MockSkiaGoldClient();

      setUp(() {
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        comparator = FlutterSkiaGoldFileComparator(
          basedir.uri,
          mockSkiaClient,
          fs: fs,
          platform: platform,
        );
      });

      group('correctly determines testing environment', () {
        test('returns true', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI': 'true',
              'CIRRUS_PR': '',
              'CIRRUS_BRANCH': 'master',
              'GOLD_SERVICE_ACCOUNT': 'service account...',
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterSkiaGoldFileComparator.isAvailableForEnvironment(platform),
            isTrue,
          );
        });

        test('returns false - PR active', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI': 'true',
              'CIRRUS_PR': '1234',
              'CIRRUS_BRANCH': 'master',
              'GOLD_SERVICE_ACCOUNT': 'service account...',
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterSkiaGoldFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - no service account', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI': 'true',
              'CIRRUS_PR': '',
              'CIRRUS_BRANCH': 'master',
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterSkiaGoldFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - not on cirrus', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'SWARMING_ID' : '1234567890',
              'GOLD_SERVICE_ACCOUNT': 'service account...'
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterSkiaGoldFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - not on master', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI': 'true',
              'CIRRUS_PR': '',
              'CIRRUS_BRANCH': 'hotfix',
              'GOLD_SERVICE_ACCOUNT': 'service account...'
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterSkiaGoldFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });
      });
    });

    group('Pre-Submit', () {
      FlutterPreSubmitFileComparator comparator;
      final MockSkiaGoldClient mockSkiaClient = MockSkiaGoldClient();

      setUp(() {
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        comparator = FlutterPreSubmitFileComparator(
          basedir.uri,
          mockSkiaClient,
          fs: fs,
          platform: FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI' : 'true',
              'CIRRUS_PR' : '1234',
              'GOLD_SERVICE_ACCOUNT' : 'service account...'
            },
            operatingSystem: 'macos'
          ),
        );

        when(mockSkiaClient.getImageBytes('55109a4bed52acc780530f7a9aeff6c0'))
          .thenAnswer((_) => Future<List<int>>.value(_kTestPngBytes));
        when(mockSkiaClient.expectations)
          .thenReturn(expectationsTemplate());
        when(mockSkiaClient.cleanTestName('library.flutter.golden_test.1.png'))
          .thenReturn('flutter.golden_test.1');
        when(mockSkiaClient.isValidDigestForExpectation(
          '55109a4bed52acc780530f7a9aeff6c0',
          'library.flutter.golden_test.1.png',
        ))
          .thenAnswer((_) => Future<bool>.value(false));
      });
      group('correctly determines testing environment', () {
        test('returns true', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI': 'true',
              'CIRRUS_PR': '1234',
              'GOLD_SERVICE_ACCOUNT' : 'service account...',
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
            isTrue,
          );
        });

        test('returns false - no PR', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI': 'true',
              'CIRRUS_PR': '',
              'GOLD_SERVICE_ACCOUNT' : 'service account...',
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - no service account', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI': 'true',
              'CIRRUS_PR': '1234',
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - not on Cirrus', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });
      });

      test('comparison passes test that is ignored for this PR', () async {
        when(mockSkiaClient.getImageBytes('55109a4bed52acc780530f7a9aeff6c0'))
          .thenAnswer((_) => Future<List<int>>.value(_kTestPngBytes));
        when(mockSkiaClient.testIsIgnoredForPullRequest(
          '1234',
          'library.flutter.golden_test.1.png',
        ))
          .thenAnswer((_) => Future<bool>.value(true));
        expect(
          await comparator.compare(
            Uint8List.fromList(_kFailPngBytes),
            Uri.parse('flutter.golden_test.1.png'),
          ),
          isTrue,
        );
      });

      test('fails test that is not ignored', () async {
        when(mockSkiaClient.getImageBytes('55109a4bed52acc780530f7a9aeff6c0'))
          .thenAnswer((_) => Future<List<int>>.value(_kTestPngBytes));
        when(mockSkiaClient.testIsIgnoredForPullRequest(
          '1234',
          'library.flutter.golden_test.1.png',
        ))
          .thenAnswer((_) => Future<bool>.value(false));
        expect(
          await comparator.compare(
            Uint8List.fromList(_kFailPngBytes),
            Uri.parse('flutter.golden_test.1.png'),
          ),
          isFalse,
        );
      });

      test('passes non-existent baseline for new test', () async {
        expect(
          await comparator.compare(
            Uint8List.fromList(_kFailPngBytes),
            Uri.parse('flutter.new_golden_test.1.png'),
          ),
          isTrue,
        );
      });
    });

    group('Skipping', () {
      group('correctly determines testing environment', () {
        test('returns true on LUCI', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'SWARMING_TASK_ID' : '1234567890',
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterSkippingGoldenFileComparator.isAvailableForEnvironment(platform),
            isTrue,
          );
        });

        test('returns true on Cirrus', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI' : 'yep',
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterSkippingGoldenFileComparator.isAvailableForEnvironment(platform),
            isTrue,
          );
        });
        test('returns false', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterSkippingGoldenFileComparator.isAvailableForEnvironment(
              platform),
            isFalse,
          );
        });
      });
    });

    group('Local', () {
      FlutterLocalFileComparator comparator;
      final MockSkiaGoldClient mockSkiaClient = MockSkiaGoldClient();

      setUp(() async {
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        comparator = FlutterLocalFileComparator(
          basedir.uri,
          mockSkiaClient,
          fs: fs,
          platform: FakePlatform(
            environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
            operatingSystem: 'macos'
          ),
        );

        when(mockSkiaClient.getImageBytes('55109a4bed52acc780530f7a9aeff6c0'))
          .thenAnswer((_) => Future<List<int>>.value(_kTestPngBytes));
        when(mockSkiaClient.expectations)
          .thenReturn(expectationsTemplate());
        when(mockSkiaClient.cleanTestName('library.flutter.golden_test.1.png'))
          .thenReturn('flutter.golden_test.1');
        when(mockSkiaClient.isValidDigestForExpectation(
          '55109a4bed52acc780530f7a9aeff6c0',
          'library.flutter.golden_test.1.png',
        ))
          .thenAnswer((_) => Future<bool>.value(false));
      });

      test('passes when bytes match', () async {
        expect(
          await comparator.compare(
            Uint8List.fromList(_kTestPngBytes),
            Uri.parse('flutter.golden_test.1.png'),
          ),
          isTrue,
        );
      });

      test('passes non-existent baseline for new test', () async {
        expect(
          await comparator.compare(
            Uint8List.fromList(_kFailPngBytes),
            Uri.parse('flutter.new_golden_test.1'),
          ),
          isTrue,
        );
      });

      test('compare properly awaits validation & output before failing.', () async {
        final Completer<bool> completer = Completer<bool>();
        when(mockSkiaClient.isValidDigestForExpectation(
          '55109a4bed52acc780530f7a9aeff6c0',
          'library.flutter.golden_test.1.png',
        ))
          .thenAnswer((_) => completer.future);
        final Future<bool> result = comparator.compare(
          Uint8List.fromList(_kFailPngBytes),
          Uri.parse('flutter.golden_test.1.png'),
        );
        bool shouldThrow = true;
        result.then((_) {
          if (shouldThrow)
            fail('Compare completed before validation completed!');
        });
        await Future<void>.value();
        shouldThrow = false;
        completer.complete(Future<bool>.value(false));
      });

      test('returns FlutterSkippingGoldenFileComparator when network connection is unavailable', () async {
        final MockDirectory mockDirectory = MockDirectory();
        when(mockDirectory.existsSync()).thenReturn(true);
        when(mockDirectory.uri).thenReturn(Uri.parse('/flutter'));
        when(mockSkiaClient.getExpectations())
          .thenAnswer((_) => throw const OSError());
        final FlutterGoldenFileComparator comparator = await FlutterLocalFileComparator.fromDefaultComparator(
          platform,
          goldens: mockSkiaClient,
          baseDirectory: mockDirectory,
        );
        expect(comparator.runtimeType, FlutterSkippingGoldenFileComparator);
      });
    });
  });
}

class MockProcessManager extends Mock implements ProcessManager {}

class MockSkiaGoldClient extends Mock implements SkiaGoldClient {}

class MockLocalFileComparator extends Mock implements LocalFileComparator {}

class MockDirectory extends Mock implements Directory {}

class MockHttpClient extends Mock implements HttpClient {}

class MockHttpClientRequest extends Mock implements HttpClientRequest {}

class MockHttpClientResponse extends Mock implements HttpClientResponse {
  MockHttpClientResponse(this.response);

  final Uint8List response;

  @override
  StreamSubscription<Uint8List> listen(
    void onData(Uint8List event), {
      Function onError,
      void onDone(),
      bool cancelOnError,
    }) {
    return Stream<Uint8List>.fromFuture(Future<Uint8List>.value(response))
      .listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }
}

class MockHttpImageResponse extends Mock implements HttpClientResponse {
  MockHttpImageResponse(this.response);

  final List<List<int>> response;

  @override
  Future<void> forEach(void action(List<int> element)) async {
    response.forEach(action);
  }
}
