// Copyright 2014 The Flutter 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:convert' show jsonEncode;
import 'dart:io' show Directory, File;

import 'package:coverage/coverage.dart' show HitMap;
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart' show FileSystem;
import 'package:flutter_tools/src/test/coverage_collector.dart';
import 'package:flutter_tools/src/test/test_device.dart' show TestDevice;
import 'package:flutter_tools/src/test/test_time_recorder.dart';
import 'package:stream_channel/stream_channel.dart' show StreamChannel;
import 'package:vm_service/vm_service.dart';

import '../src/common.dart';
import '../src/context.dart';
import '../src/fake_vm_services.dart';
import '../src/logging_logger.dart';

void main() {
  testWithoutContext('Coverage collector Can handle coverage SentinelException', () async {
    final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
      requests: <VmServiceExpectation>[
        FakeVmServiceRequest(
          method: 'getVM',
          jsonResponse: (VM.parse(<String, Object>{})!
            ..isolates = <IsolateRef>[
              IsolateRef.parse(<String, Object>{
                'id': '1',
              })!,
            ]
          ).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getVersion',
          jsonResponse: Version(major: 3, minor: 51).toJson(),
        ),
        const FakeVmServiceRequest(
          method: 'getScripts',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'type': 'Sentinel',
          },
        ),
      ],
    );

    final Map<String, Object?> result = await collect(
      Uri(),
      <String>{'foo'},
      serviceOverride: fakeVmServiceHost.vmService,
      coverableLineCache: <String, Set<int>>{},
    );

    expect(result, <String, Object>{'type': 'CodeCoverage', 'coverage': <Object>[]});
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  });

  testWithoutContext('Coverage collector processes coverage and script data', () async {
    final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
      requests: <VmServiceExpectation>[
        FakeVmServiceRequest(
          method: 'getVM',
          jsonResponse: (VM.parse(<String, Object>{})!
            ..isolates = <IsolateRef>[
              IsolateRef.parse(<String, Object>{
                'id': '1',
              })!,
            ]
          ).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getVersion',
          jsonResponse: Version(major: 3, minor: 51).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getScripts',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: ScriptList(scripts: <ScriptRef>[
            ScriptRef(uri: 'package:foo/foo.dart', id: '1'),
            ScriptRef(uri: 'package:bar/bar.dart', id: '2'),
          ]).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getSourceReport',
          args: <String, Object>{
            'isolateId': '1',
            'reports': <Object>['Coverage'],
            'scriptId': '1',
            'forceCompile': true,
            'reportLines': true,
          },
          jsonResponse: SourceReport(
            ranges: <SourceReportRange>[
              SourceReportRange(
                scriptIndex: 0,
                startPos: 0,
                endPos: 0,
                compiled: true,
                coverage: SourceReportCoverage(
                  hits: <int>[1, 3],
                  misses: <int>[2],
                ),
              ),
            ],
            scripts: <ScriptRef>[
              ScriptRef(
                uri: 'package:foo/foo.dart',
                id: '1',
              ),
            ],
          ).toJson(),
        ),
      ],
    );

    final Map<String, Object?> result = await collect(
      Uri(),
      <String>{'foo'},
      serviceOverride: fakeVmServiceHost.vmService,
      coverableLineCache: <String, Set<int>>{},
    );

    expect(result, <String, Object>{
      'type': 'CodeCoverage',
      'coverage': <Object>[
        <String, Object>{
          'source': 'package:foo/foo.dart',
          'script': <String, Object>{
            'type': '@Script',
            'fixedId': true,
            'id': 'libraries/1/scripts/package%3Afoo%2Ffoo.dart',
            'uri': 'package:foo/foo.dart',
            '_kind': 'library',
          },
          'hits': <Object>[1, 1, 3, 1, 2, 0],
        },
      ],
    });
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  });

  testWithoutContext('Coverage collector with null libraryNames accepts all libraries', () async {
    final FakeVmServiceHost fakeVmServiceHost = createFakeVmServiceHostWithFooAndBar();

    final Map<String, Object?> result = await collect(
      Uri(),
      null,
      serviceOverride: fakeVmServiceHost.vmService,
      coverableLineCache: <String, Set<int>>{},
    );

    expect(result, <String, Object>{
      'type': 'CodeCoverage',
      'coverage': <Object>[
        <String, Object>{
          'source': 'package:foo/foo.dart',
          'script': <String, Object>{
            'type': '@Script',
            'fixedId': true,
            'id': 'libraries/1/scripts/package%3Afoo%2Ffoo.dart',
            'uri': 'package:foo/foo.dart',
            '_kind': 'library',
          },
          'hits': <Object>[1, 1, 3, 1, 2, 0],
        },
        <String, Object>{
          'source': 'package:bar/bar.dart',
          'script': <String, Object>{
            'type': '@Script',
            'fixedId': true,
            'id': 'libraries/1/scripts/package%3Abar%2Fbar.dart',
            'uri': 'package:bar/bar.dart',
            '_kind': 'library',
          },
          'hits': <Object>[47, 1, 21, 1, 32, 0, 86, 0],
        },
      ],
    });
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  });

  testWithoutContext('Coverage collector with libraryFilters', () async {
    final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
      requests: <VmServiceExpectation>[
        FakeVmServiceRequest(
          method: 'getVM',
          jsonResponse: (VM.parse(<String, Object>{})!
            ..isolates = <IsolateRef>[
              IsolateRef.parse(<String, Object>{
                'id': '1',
              })!,
            ]
          ).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getVersion',
          jsonResponse: Version(major: 3, minor: 57).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getSourceReport',
          args: <String, Object>{
            'isolateId': '1',
            'reports': <Object>['Coverage'],
            'forceCompile': true,
            'reportLines': true,
            'libraryFilters': <Object>['package:foo/'],
          },
          jsonResponse: SourceReport(
            ranges: <SourceReportRange>[
              SourceReportRange(
                scriptIndex: 0,
                startPos: 0,
                endPos: 0,
                compiled: true,
                coverage: SourceReportCoverage(
                  hits: <int>[1, 3],
                  misses: <int>[2],
                ),
              ),
            ],
            scripts: <ScriptRef>[
              ScriptRef(
                uri: 'package:foo/foo.dart',
                id: '1',
              ),
            ],
          ).toJson(),
        ),
      ],
    );

    final Map<String, Object?> result = await collect(
      Uri(),
      <String>{'foo'},
      serviceOverride: fakeVmServiceHost.vmService,
      coverableLineCache: <String, Set<int>>{},
    );

    expect(result, <String, Object>{
      'type': 'CodeCoverage',
      'coverage': <Object>[
        <String, Object>{
          'source': 'package:foo/foo.dart',
          'script': <String, Object>{
            'type': '@Script',
            'fixedId': true,
            'id': 'libraries/1/scripts/package%3Afoo%2Ffoo.dart',
            'uri': 'package:foo/foo.dart',
            '_kind': 'library',
          },
          'hits': <Object>[1, 1, 3, 1, 2, 0],
        },
      ],
    });
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  });

  testWithoutContext('Coverage collector with libraryFilters and null libraryNames', () async {
    final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
      requests: <VmServiceExpectation>[
        FakeVmServiceRequest(
          method: 'getVM',
          jsonResponse: (VM.parse(<String, Object>{})!
            ..isolates = <IsolateRef>[
              IsolateRef.parse(<String, Object>{
                'id': '1',
              })!,
            ]
          ).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getVersion',
          jsonResponse: Version(major: 3, minor: 57).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getSourceReport',
          args: <String, Object>{
            'isolateId': '1',
            'reports': <Object>['Coverage'],
            'forceCompile': true,
            'reportLines': true,
          },
          jsonResponse: SourceReport(
            ranges: <SourceReportRange>[
              SourceReportRange(
                scriptIndex: 0,
                startPos: 0,
                endPos: 0,
                compiled: true,
                coverage: SourceReportCoverage(
                  hits: <int>[1, 3],
                  misses: <int>[2],
                ),
              ),
            ],
            scripts: <ScriptRef>[
              ScriptRef(
                uri: 'package:foo/foo.dart',
                id: '1',
              ),
            ],
          ).toJson(),
        ),
      ],
    );

    final Map<String, Object?> result = await collect(
      Uri(),
      null,
      serviceOverride: fakeVmServiceHost.vmService,
      coverableLineCache: <String, Set<int>>{},
    );

    expect(result, <String, Object>{
      'type': 'CodeCoverage',
      'coverage': <Object>[
        <String, Object>{
          'source': 'package:foo/foo.dart',
          'script': <String, Object>{
            'type': '@Script',
            'fixedId': true,
            'id': 'libraries/1/scripts/package%3Afoo%2Ffoo.dart',
            'uri': 'package:foo/foo.dart',
            '_kind': 'library',
          },
          'hits': <Object>[1, 1, 3, 1, 2, 0],
        },
      ],
    });
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  });

  testWithoutContext('Coverage collector with branch coverage', () async {
    final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
      requests: <VmServiceExpectation>[
        FakeVmServiceRequest(
          method: 'getVM',
          jsonResponse: (VM.parse(<String, Object>{})!
            ..isolates = <IsolateRef>[
              IsolateRef.parse(<String, Object>{
                'id': '1',
              })!,
            ]
          ).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getVersion',
          jsonResponse: Version(major: 3, minor: 56).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getScripts',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: ScriptList(scripts: <ScriptRef>[
            ScriptRef(uri: 'package:foo/foo.dart', id: '1'),
            ScriptRef(uri: 'package:bar/bar.dart', id: '2'),
          ]).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getSourceReport',
          args: <String, Object>{
            'isolateId': '1',
            'reports': <Object>['Coverage', 'BranchCoverage'],
            'scriptId': '1',
            'forceCompile': true,
            'reportLines': true,
          },
          jsonResponse: SourceReport(
            ranges: <SourceReportRange>[
              SourceReportRange(
                scriptIndex: 0,
                startPos: 0,
                endPos: 0,
                compiled: true,
                coverage: SourceReportCoverage(
                  hits: <int>[1, 3],
                  misses: <int>[2],
                ),
                branchCoverage: SourceReportCoverage(
                  hits: <int>[4, 6],
                  misses: <int>[5],
                ),
              ),
            ],
            scripts: <ScriptRef>[
              ScriptRef(
                uri: 'package:foo/foo.dart',
                id: '1',
              ),
            ],
          ).toJson(),
        ),
      ],
    );

    final Map<String, Object?> result = await collect(
      Uri(),
      <String>{'foo'},
      serviceOverride: fakeVmServiceHost.vmService,
      branchCoverage: true,
      coverableLineCache: <String, Set<int>>{},
    );

    expect(result, <String, Object>{
      'type': 'CodeCoverage',
      'coverage': <Object>[
        <String, Object>{
          'source': 'package:foo/foo.dart',
          'script': <String, Object>{
            'type': '@Script',
            'fixedId': true,
            'id': 'libraries/1/scripts/package%3Afoo%2Ffoo.dart',
            'uri': 'package:foo/foo.dart',
            '_kind': 'library',
          },
          'hits': <Object>[1, 1, 3, 1, 2, 0],
          'branchHits': <Object>[4, 1, 6, 1, 5, 0],
        },
      ],
    });
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  });

  testWithoutContext('Coverage collector caches read files', () async {
    Directory? tempDir;
    try {
      tempDir = Directory.systemTemp.createTempSync('flutter_coverage_collector_test.');
      final File packagesFile = writeFooBarPackagesJson(tempDir);
      final Directory fooDir = Directory('${tempDir.path}/foo/');
      fooDir.createSync();
      final File fooFile = File('${fooDir.path}/foo.dart');
      fooFile.writeAsStringSync('hit\nnohit but ignored // coverage:ignore-line\nhit\n');

      final String packagesPath = packagesFile.path;
      final CoverageCollector collector = CoverageCollector(
          libraryNames: <String>{'foo', 'bar'},
          verbose: false,
          packagesPath: packagesPath,
          resolver: await CoverageCollector.getResolver(packagesPath)
        );
      await collector.collectCoverage(
          TestTestDevice(),
          serviceOverride: createFakeVmServiceHostWithFooAndBar(libraryFilters: <String>['package:foo/', 'package:bar/']).vmService,
        );

      Future<void> getHitMapAndVerify() async {
        final Map<String, HitMap> gottenHitmap = <String, HitMap>{};
        await collector.finalizeCoverage(formatter: (Map<String, HitMap> hitmap) {
          gottenHitmap.addAll(hitmap);
          return '';
        });
        expect(gottenHitmap.keys.toList()..sort(), <String>['package:bar/bar.dart', 'package:foo/foo.dart']);
        expect(gottenHitmap['package:foo/foo.dart']!.lineHits, <int, int>{1: 1, /* 2: 0, is ignored in file */ 3: 1});
        expect(gottenHitmap['package:bar/bar.dart']!.lineHits, <int, int>{21: 1, 32: 0, 47: 1, 86: 0});
      }

      Future<void> verifyHitmapEmpty() async {
        final Map<String, HitMap> gottenHitmap = <String, HitMap>{};
        await collector.finalizeCoverage(formatter: (Map<String, HitMap> hitmap) {
          gottenHitmap.addAll(hitmap);
          return '';
        });
        expect(gottenHitmap.isEmpty, isTrue);
      }

      // Get hit map the first time.
      await getHitMapAndVerify();

      // Getting the hitmap clears it so we now doesn't get any data.
      await verifyHitmapEmpty();

      // Collecting again gets us the same data even though the foo file has been deleted.
      // This means that the fact that line 2 was ignored has been cached.
      fooFile.deleteSync();
      await collector.collectCoverage(
          TestTestDevice(),
          serviceOverride: createFakeVmServiceHostWithFooAndBar(libraryFilters: <String>['package:foo/', 'package:bar/']).vmService,
        );
      await getHitMapAndVerify();
    } finally {
      tempDir?.deleteSync(recursive: true);
    }
  });

  testWithoutContext('Coverage collector respects ignore whole file', () async {
    Directory? tempDir;
    try {
      tempDir = Directory.systemTemp.createTempSync('flutter_coverage_collector_test.');
      final File packagesFile = writeFooBarPackagesJson(tempDir);
      final Directory fooDir = Directory('${tempDir.path}/foo/');
      fooDir.createSync();
      final File fooFile = File('${fooDir.path}/foo.dart');
      fooFile.writeAsStringSync('hit\nnohit but ignored // coverage:ignore-file\nhit\n');

      final String packagesPath = packagesFile.path;
      final CoverageCollector collector = CoverageCollector(
          libraryNames: <String>{'foo', 'bar'},
          verbose: false,
          packagesPath: packagesPath,
          resolver: await CoverageCollector.getResolver(packagesPath)
        );
      await collector.collectCoverage(
          TestTestDevice(),
          serviceOverride: createFakeVmServiceHostWithFooAndBar(libraryFilters: <String>['package:foo/', 'package:bar/']).vmService,
        );

      final Map<String, HitMap> gottenHitmap = <String, HitMap>{};
      await collector.finalizeCoverage(formatter: (Map<String, HitMap> hitmap) {
        gottenHitmap.addAll(hitmap);
        return '';
      });
      expect(gottenHitmap.keys.toList()..sort(), <String>['package:bar/bar.dart']);
      expect(gottenHitmap['package:bar/bar.dart']!.lineHits, <int, int>{21: 1, 32: 0, 47: 1, 86: 0});
    } finally {
      tempDir?.deleteSync(recursive: true);
    }
  });

  testUsingContext('Coverage collector respects libraryNames in finalized report', () async {
    Directory? tempDir;
    try {
      tempDir = Directory.systemTemp.createTempSync('flutter_coverage_collector_test.');
      final File packagesFile = writeFooBarPackagesJson(tempDir);
      File('${tempDir.path}/foo/foo.dart').createSync(recursive: true);
      File('${tempDir.path}/bar/bar.dart').createSync(recursive: true);

      final String packagesPath = packagesFile.path;
      CoverageCollector collector = CoverageCollector(
          libraryNames: <String>{'foo', 'bar'},
          verbose: false,
          packagesPath: packagesPath,
          resolver: await CoverageCollector.getResolver(packagesPath)
      );
      await collector.collectCoverage(
        TestTestDevice(),
        serviceOverride: createFakeVmServiceHostWithFooAndBar(libraryFilters: <String>['package:foo/', 'package:bar/']).vmService,
      );

      String? report = await collector.finalizeCoverage();
      expect(report, contains('foo.dart'));
      expect(report, contains('bar.dart'));

      collector = CoverageCollector(
          libraryNames: <String>{'foo'},
          verbose: false,
          packagesPath: packagesPath,
          resolver: await CoverageCollector.getResolver(packagesPath)
      );
      await collector.collectCoverage(
        TestTestDevice(),
        serviceOverride: createFakeVmServiceHostWithFooAndBar(libraryFilters: <String>['package:foo/']).vmService,
      );

      report = await collector.finalizeCoverage();
      expect(report, contains('foo.dart'));
      expect(report, isNot(contains('bar.dart')));
    } finally {
      tempDir?.deleteSync(recursive: true);
    }
  }, overrides: <Type, Generator>{
    FileSystem: () => MemoryFileSystem.test(),
    ProcessManager: () => FakeProcessManager.any(),
  });

  testWithoutContext('Coverage collector records test timings when provided TestTimeRecorder', () async {
    Directory? tempDir;
    try {
      tempDir = Directory.systemTemp.createTempSync('flutter_coverage_collector_test.');
      final File packagesFile = writeFooBarPackagesJson(tempDir);
      final Directory fooDir = Directory('${tempDir.path}/foo/');
      fooDir.createSync();
      final File fooFile = File('${fooDir.path}/foo.dart');
      fooFile.writeAsStringSync('hit\nnohit but ignored // coverage:ignore-line\nhit\n');

      final String packagesPath = packagesFile.path;
      final LoggingLogger logger = LoggingLogger();
      final TestTimeRecorder testTimeRecorder = TestTimeRecorder(logger);
      final CoverageCollector collector = CoverageCollector(
          libraryNames: <String>{'foo', 'bar'},
          verbose: false,
          packagesPath: packagesPath,
          resolver: await CoverageCollector.getResolver(packagesPath),
          testTimeRecorder: testTimeRecorder
        );
      await collector.collectCoverage(
          TestTestDevice(),
          serviceOverride: createFakeVmServiceHostWithFooAndBar(libraryFilters: <String>['package:foo/', 'package:bar/']).vmService,
        );

      // Expect one message for each phase.
      final List<String> logPhaseMessages = testTimeRecorder.getPrintAsListForTesting().where((String m) => m.startsWith('Runtime for phase ')).toList();
      expect(logPhaseMessages, hasLength(TestTimePhases.values.length));

      // Several phases actually does something, but here we just expect at
      // least one phase to take a non-zero amount of time.
      final List<String> logPhaseMessagesNonZero = logPhaseMessages.where((String m) => !m.contains(Duration.zero.toString())).toList();
      expect(logPhaseMessagesNonZero, isNotEmpty);
    } finally {
      tempDir?.deleteSync(recursive: true);
    }
  });

  testWithoutContext('Coverage collector fills coverableLineCache', () async {
    final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
      requests: <VmServiceExpectation>[
        FakeVmServiceRequest(
          method: 'getVM',
          jsonResponse: (VM.parse(<String, Object>{})!
            ..isolates = <IsolateRef>[
              IsolateRef.parse(<String, Object>{
                'id': '1',
              })!,
            ]
          ).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getVersion',
          jsonResponse: Version(major: 4, minor: 13).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getSourceReport',
          args: <String, Object>{
            'isolateId': '1',
            'reports': <Object>['Coverage'],
            'forceCompile': true,
            'reportLines': true,
            'libraryFilters': <String>['package:foo/'],
            'librariesAlreadyCompiled': <String>[],
          },
          jsonResponse: SourceReport(
            ranges: <SourceReportRange>[
              SourceReportRange(
                scriptIndex: 0,
                startPos: 0,
                endPos: 0,
                compiled: true,
                coverage: SourceReportCoverage(
                  hits: <int>[1, 3],
                  misses: <int>[2],
                ),
              ),
            ],
            scripts: <ScriptRef>[
              ScriptRef(
                uri: 'package:foo/foo.dart',
                id: '1',
              ),
            ],
          ).toJson(),
        ),
      ],
    );

    final Map<String, Set<int>> coverableLineCache = <String, Set<int>>{};
    final Map<String, Object?> result = await collect(
      Uri(),
      <String>{'foo'},
      serviceOverride: fakeVmServiceHost.vmService,
      coverableLineCache: coverableLineCache,
    );

    expect(result, <String, Object>{
      'type': 'CodeCoverage',
      'coverage': <Object>[
        <String, Object>{
          'source': 'package:foo/foo.dart',
          'script': <String, Object>{
            'type': '@Script',
            'fixedId': true,
            'id': 'libraries/1/scripts/package%3Afoo%2Ffoo.dart',
            'uri': 'package:foo/foo.dart',
            '_kind': 'library',
          },
          'hits': <Object>[1, 1, 3, 1, 2, 0],
        },
      ],
    });

    // coverableLineCache should contain every line mentioned in the report.
    expect(coverableLineCache, <String, Set<int>>{
      'package:foo/foo.dart': <int>{1, 2, 3},
    });

    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  });

  testWithoutContext('Coverage collector avoids recompiling libraries in coverableLineCache', () async {
    final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
      requests: <VmServiceExpectation>[
        FakeVmServiceRequest(
          method: 'getVM',
          jsonResponse: (VM.parse(<String, Object>{})!
            ..isolates = <IsolateRef>[
              IsolateRef.parse(<String, Object>{
                'id': '1',
              })!,
            ]
          ).toJson(),
        ),
        FakeVmServiceRequest(
          method: 'getVersion',
          jsonResponse: Version(major: 4, minor: 13).toJson(),
        ),

        // This collection sets librariesAlreadyCompiled. The response doesn't
        // include any misses.
        FakeVmServiceRequest(
          method: 'getSourceReport',
          args: <String, Object>{
            'isolateId': '1',
            'reports': <Object>['Coverage'],
            'forceCompile': true,
            'reportLines': true,
            'libraryFilters': <String>['package:foo/'],
            'librariesAlreadyCompiled': <String>['package:foo/foo.dart'],
          },
          jsonResponse: SourceReport(
            ranges: <SourceReportRange>[
              SourceReportRange(
                scriptIndex: 0,
                startPos: 0,
                endPos: 0,
                compiled: true,
                coverage: SourceReportCoverage(
                  hits: <int>[1, 3],
                  misses: <int>[],
                ),
              ),
            ],
            scripts: <ScriptRef>[
              ScriptRef(
                uri: 'package:foo/foo.dart',
                id: '1',
              ),
            ],
          ).toJson(),
        ),
      ],
    );

    final Map<String, Set<int>> coverableLineCache = <String, Set<int>>{
      'package:foo/foo.dart': <int>{1, 2, 3},
    };
    final Map<String, Object?> result2 = await collect(
      Uri(),
      <String>{'foo'},
      serviceOverride: fakeVmServiceHost.vmService,
      coverableLineCache: coverableLineCache,
    );

    // Expect that line 2 is marked as missed, even though it wasn't mentioned
    // in the getSourceReport response.
    expect(result2, <String, Object>{
      'type': 'CodeCoverage',
      'coverage': <Object>[
        <String, Object>{
          'source': 'package:foo/foo.dart',
          'script': <String, Object>{
            'type': '@Script',
            'fixedId': true,
            'id': 'libraries/1/scripts/package%3Afoo%2Ffoo.dart',
            'uri': 'package:foo/foo.dart',
            '_kind': 'library',
          },
          'hits': <Object>[1, 1, 2, 0, 3, 1],
        },
      ],
    });
    expect(coverableLineCache, <String, Set<int>>{
      'package:foo/foo.dart': <int>{1, 2, 3},
    });

    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  });
}

File writeFooBarPackagesJson(Directory tempDir) {
  final File file = File('${tempDir.path}/packages.json');
  file.writeAsStringSync(jsonEncode(<String, dynamic>{
    'configVersion': 2,
    'packages': <Map<String, String>>[
      <String, String>{
        'name': 'foo',
        'rootUri': 'foo',
      },
      <String, String>{
        'name': 'bar',
        'rootUri': 'bar',
      },
    ],
  }));
  return file;
}

FakeVmServiceHost createFakeVmServiceHostWithFooAndBar({
    List<String>? libraryFilters,
  }) {
  return FakeVmServiceHost(
    requests: <VmServiceExpectation>[
      FakeVmServiceRequest(
        method: 'getVM',
        jsonResponse: (VM.parse(<String, Object>{})!
          ..isolates = <IsolateRef>[
            IsolateRef.parse(<String, Object>{
              'id': '1',
            })!,
          ]
        ).toJson(),
      ),
      FakeVmServiceRequest(
        method: 'getVersion',
        jsonResponse: Version(major: 3, minor: 61).toJson(),
      ),
      FakeVmServiceRequest(
        method: 'getSourceReport',
        args: <String, Object>{
          'isolateId': '1',
          'reports': <Object>['Coverage'],
          'forceCompile': true,
          'reportLines': true,
          if (libraryFilters != null) 'libraryFilters': libraryFilters,
        },
        jsonResponse: SourceReport(
          ranges: <SourceReportRange>[
            SourceReportRange(
              scriptIndex: 0,
              startPos: 0,
              endPos: 0,
              compiled: true,
              coverage: SourceReportCoverage(
                hits: <int>[1, 3],
                misses: <int>[2],
              ),
            ),
            SourceReportRange(
              scriptIndex: 1,
              startPos: 0,
              endPos: 0,
              compiled: true,
              coverage: SourceReportCoverage(
                hits: <int>[47, 21],
                misses: <int>[32, 86],
              ),
            ),
          ],
          scripts: <ScriptRef>[
            ScriptRef(
              uri: 'package:foo/foo.dart',
              id: '1',
            ),
            ScriptRef(
              uri: 'package:bar/bar.dart',
              id: '2',
            ),
          ],
        ).toJson(),
      ),
    ],
  );
}

class TestTestDevice extends TestDevice {
  @override
  Future<void> get finished => Future<void>.delayed(const Duration(seconds: 1));

  @override
  Future<void> kill() => Future<void>.value();

  @override
  Future<Uri?> get vmServiceUri => Future<Uri?>.value(Uri());

  @override
  Future<StreamChannel<String>> start(String entrypointPath) {
    throw UnimplementedError();
  }
}
