// Copyright 2013 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:ffi';

import 'package:file/file.dart';
import 'package:meta/meta.dart';

import 'common/cmake.dart';
import 'common/core.dart';
import 'common/gradle.dart';
import 'common/output_utils.dart';
import 'common/package_looping_command.dart';
import 'common/plugin_utils.dart';
import 'common/repository_package.dart';
import 'common/xcode.dart';

const String _unitTestFlag = 'unit';
const String _integrationTestFlag = 'integration';

const String _iOSDestinationFlag = 'ios-destination';

const int _exitNoIOSSimulators = 3;

/// The error message logged when a FlutterTestRunner test is not annotated with
/// @DartIntegrationTest.
@visibleForTesting
const String misconfiguredJavaIntegrationTestErrorExplanation =
    'The following files use @RunWith(FlutterTestRunner.class) '
    'but not @DartIntegrationTest, which will cause hangs when run with '
    'this command. See '
    'https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#enabling-android-ui-tests '
    'for instructions.';

/// The command to run native tests for plugins:
/// - iOS and macOS: XCTests (XCUnitTest and XCUITest)
/// - Android: JUnit tests
/// - Windows and Linux: GoogleTest tests
class NativeTestCommand extends PackageLoopingCommand {
  /// Creates an instance of the test command.
  NativeTestCommand(
    super.packagesDir, {
    super.processRunner,
    super.platform,
    Abi? abi,
  })  : _abi = abi ?? Abi.current(),
        _xcode = Xcode(processRunner: processRunner, log: true) {
    argParser.addOption(
      _iOSDestinationFlag,
      help: 'Specify the destination when running iOS tests.\n'
          'This is passed to the `-destination` argument in the xcodebuild command.\n'
          'See https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-UNIT '
          'for details on how to specify the destination.',
    );
    argParser.addFlag(platformAndroid, help: 'Runs Android tests');
    argParser.addFlag(platformIOS, help: 'Runs iOS tests');
    argParser.addFlag(platformLinux, help: 'Runs Linux tests');
    argParser.addFlag(platformMacOS, help: 'Runs macOS tests');
    argParser.addFlag(platformWindows, help: 'Runs Windows tests');

    // By default, both unit tests and integration tests are run, but provide
    // flags to disable one or the other.
    argParser.addFlag(_unitTestFlag,
        help: 'Runs native unit tests', defaultsTo: true);
    argParser.addFlag(_integrationTestFlag,
        help: 'Runs native integration (UI) tests', defaultsTo: true);
  }

  // The ABI of the host.
  final Abi _abi;

  // The device destination flags for iOS tests.
  List<String> _iOSDestinationFlags = <String>[];

  final Xcode _xcode;

  @override
  final String name = 'native-test';

  @override
  List<String> get aliases => <String>['test-native'];

  @override
  final String description = '''
Runs native unit tests and native integration tests.

Currently supported platforms:
- Android
- iOS: requires 'xcrun' to be in your path.
- Linux (unit tests only)
- macOS: requires 'xcrun' to be in your path.
- Windows (unit tests only)

The example app(s) must be built for all targeted platforms before running
this command.
''';

  Map<String, _PlatformDetails> _platforms = <String, _PlatformDetails>{};

  List<String> _requestedPlatforms = <String>[];

  @override
  Future<void> initializeRun() async {
    _platforms = <String, _PlatformDetails>{
      platformAndroid: _PlatformDetails('Android', _testAndroid),
      platformIOS: _PlatformDetails('iOS', _testIOS),
      platformLinux: _PlatformDetails('Linux', _testLinux),
      platformMacOS: _PlatformDetails('macOS', _testMacOS),
      platformWindows: _PlatformDetails('Windows', _testWindows),
    };
    _requestedPlatforms = _platforms.keys
        .where((String platform) => getBoolArg(platform))
        .toList();
    _requestedPlatforms.sort();

    if (_requestedPlatforms.isEmpty) {
      printError('At least one platform flag must be provided.');
      throw ToolExit(exitInvalidArguments);
    }

    if (!(getBoolArg(_unitTestFlag) || getBoolArg(_integrationTestFlag))) {
      printError('At least one test type must be enabled.');
      throw ToolExit(exitInvalidArguments);
    }

    if (getBoolArg(platformWindows) && getBoolArg(_integrationTestFlag)) {
      logWarning('This command currently only supports unit tests for Windows. '
          'See https://github.com/flutter/flutter/issues/70233.');
    }

    if (getBoolArg(platformLinux) && getBoolArg(_integrationTestFlag)) {
      logWarning('This command currently only supports unit tests for Linux. '
          'See https://github.com/flutter/flutter/issues/70235.');
    }

    // iOS-specific run-level state.
    if (_requestedPlatforms.contains('ios')) {
      String destination = getStringArg(_iOSDestinationFlag);
      if (destination.isEmpty) {
        final String? simulatorId =
            await _xcode.findBestAvailableIphoneSimulator();
        if (simulatorId == null) {
          printError('Cannot find any available iOS simulators.');
          throw ToolExit(_exitNoIOSSimulators);
        }
        destination = 'id=$simulatorId';
      }
      _iOSDestinationFlags = <String>[
        '-destination',
        destination,
      ];
    }
  }

  @override
  Future<PackageResult> runForPackage(RepositoryPackage package) async {
    final List<String> testPlatforms = <String>[];
    for (final String platform in _requestedPlatforms) {
      if (!pluginSupportsPlatform(platform, package,
          requiredMode: PlatformSupport.inline)) {
        print('No implementation for ${_platforms[platform]!.label}.');
        continue;
      }
      if (!pluginHasNativeCodeForPlatform(platform, package)) {
        print('No native code for ${_platforms[platform]!.label}.');
        continue;
      }
      testPlatforms.add(platform);
    }

    if (testPlatforms.isEmpty) {
      return PackageResult.skip('Nothing to test for target platform(s).');
    }

    final _TestMode mode = _TestMode(
      unit: getBoolArg(_unitTestFlag),
      integration: getBoolArg(_integrationTestFlag),
    );

    bool ranTests = false;
    bool failed = false;
    final List<String> failureMessages = <String>[];
    for (final String platform in testPlatforms) {
      final _PlatformDetails platformInfo = _platforms[platform]!;
      print('Running tests for ${platformInfo.label}...');
      print('----------------------------------------');
      final _PlatformResult result =
          await platformInfo.testFunction(package, mode);
      ranTests |= result.state != RunState.skipped;
      if (result.state == RunState.failed) {
        failed = true;

        final String? error = result.error;
        // Only provide the failing platforms in the failure details if testing
        // multiple platforms, otherwise it's just noise.
        if (_requestedPlatforms.length > 1) {
          failureMessages.add(error != null
              ? '${platformInfo.label}: $error'
              : platformInfo.label);
        } else if (error != null) {
          // If there's only one platform, only provide error details in the
          // summary if the platform returned a message.
          failureMessages.add(error);
        }
      }
    }

    if (!ranTests) {
      return PackageResult.skip('No tests found.');
    }
    return failed
        ? PackageResult.fail(failureMessages)
        : PackageResult.success();
  }

  Future<_PlatformResult> _testAndroid(
      RepositoryPackage plugin, _TestMode mode) async {
    bool exampleHasUnitTests(RepositoryPackage example) {
      return example
              .platformDirectory(FlutterPlatform.android)
              .childDirectory('app')
              .childDirectory('src')
              .childDirectory('test')
              .existsSync() ||
          plugin
              .platformDirectory(FlutterPlatform.android)
              .childDirectory('src')
              .childDirectory('test')
              .existsSync();
    }

    _JavaTestInfo getJavaTestInfo(File testFile) {
      final List<String> contents = testFile.readAsLinesSync();
      return _JavaTestInfo(
          usesFlutterTestRunner: contents.any((String line) =>
              line.trimLeft().startsWith('@RunWith(FlutterTestRunner.class)')),
          hasDartIntegrationTestAnnotation: contents.any((String line) =>
              line.trimLeft().startsWith('@DartIntegrationTest')));
    }

    Map<File, _JavaTestInfo> findIntegrationTestFiles(
        RepositoryPackage example) {
      final Directory integrationTestDirectory = example
          .platformDirectory(FlutterPlatform.android)
          .childDirectory('app')
          .childDirectory('src')
          .childDirectory('androidTest');
      // There are two types of integration tests that can be in the androidTest
      // directory:
      // - FlutterTestRunner.class tests, which bridge to Dart integration tests
      // - Purely native integration tests
      // Only the latter is supported by this command; the former will hang if
      // run here because they will wait for a Dart call that will never come.
      //
      // Find all test files, and determine which kind of test they are based on
      // the annotations they use.
      //
      // Ignore DartIntegrationTest.java, which defines the annotation used
      // below for filtering the former out when running tests.
      if (!integrationTestDirectory.existsSync()) {
        return <File, _JavaTestInfo>{};
      }
      final Iterable<File> integrationTestFiles = integrationTestDirectory
          .listSync(recursive: true)
          .whereType<File>()
          .where((File file) {
        final String basename = file.basename;
        return basename != 'DartIntegrationTest.java' &&
            basename != 'DartIntegrationTest.kt';
      });
      return <File, _JavaTestInfo>{
        for (final File file in integrationTestFiles)
          file: getJavaTestInfo(file)
      };
    }

    final Iterable<RepositoryPackage> examples = plugin.getExamples();
    final String pluginName = plugin.directory.basename;

    bool ranUnitTests = false;
    bool ranAnyTests = false;
    bool failed = false;
    bool hasMisconfiguredIntegrationTest = false;
    // Iterate through all examples (in the rare case that there is more than
    // one example); running any tests found for each one. Requirements on what
    // tests are present are enforced at the overall package level, not a per-
    // example level. E.g., it's fine for only one example to have unit tests.
    for (final RepositoryPackage example in examples) {
      final bool hasUnitTests = exampleHasUnitTests(example);
      final Map<File, _JavaTestInfo> candidateIntegrationTestFiles =
          findIntegrationTestFiles(example);
      final bool hasIntegrationTests = candidateIntegrationTestFiles.values
          .any((_JavaTestInfo info) => !info.hasDartIntegrationTestAnnotation);

      if (mode.unit && !hasUnitTests) {
        _printNoExampleTestsMessage(example, 'Android unit');
      }
      if (mode.integration && !hasIntegrationTests) {
        _printNoExampleTestsMessage(example, 'Android integration');
      }

      final bool runUnitTests = mode.unit && hasUnitTests;
      final bool runIntegrationTests = mode.integration && hasIntegrationTests;
      if (!runUnitTests && !runIntegrationTests) {
        continue;
      }

      final String exampleName = example.displayName;
      _printRunningExampleTestsMessage(example, 'Android');

      final GradleProject project = GradleProject(
        example,
        processRunner: processRunner,
        platform: platform,
      );
      if (!project.isConfigured()) {
        final int exitCode = await processRunner.runAndStream(
          flutterCommand,
          <String>['build', 'apk', '--config-only'],
          workingDir: example.directory,
        );
        if (exitCode != 0) {
          printError('Unable to configure Gradle project.');
          failed = true;
          continue;
        }
      }

      if (runUnitTests) {
        print('Running unit tests...');
        const String taskName = 'testDebugUnitTest';
        // Target the unit tests in the app and plugin specifically, to avoid
        // transitively running tests in dependencies. If unit tests have
        // already run in an earlier example, only run any app-level unit tests.
        final List<String> pluginTestTask = <String>[
          if (!ranUnitTests) '$pluginName:$taskName'
        ];
        final int exitCode = await project.runCommand('app:$taskName',
            additionalTasks: pluginTestTask);
        if (exitCode != 0) {
          printError('$exampleName unit tests failed.');
          failed = true;
        }
        ranUnitTests = true;
        ranAnyTests = true;
      }

      if (runIntegrationTests) {
        // FlutterTestRunner-based tests will hang forever if run in a normal
        // app build, since they wait for a Dart call from integration_test
        // that will never come. Those tests have an extra annotation to allow
        // filtering them out.
        final List<File> misconfiguredTestFiles = candidateIntegrationTestFiles
            .entries
            .where((MapEntry<File, _JavaTestInfo> entry) =>
                entry.value.usesFlutterTestRunner &&
                !entry.value.hasDartIntegrationTestAnnotation)
            .map((MapEntry<File, _JavaTestInfo> entry) => entry.key)
            .toList();
        if (misconfiguredTestFiles.isEmpty) {
          // Ideally we would filter out @RunWith(FlutterTestRunner.class)
          // tests directly, but there doesn't seem to be a way to filter based
          // on annotation contents, so the DartIntegrationTest annotation was
          // created as a proxy for that.
          const String filter =
              'notAnnotation=io.flutter.plugins.DartIntegrationTest';

          print('Running integration tests...');
          final int exitCode = await project.runCommand(
            'app:connectedAndroidTest',
            arguments: <String>[
              '-Pandroid.testInstrumentationRunnerArguments.$filter',
            ],
          );
          if (exitCode != 0) {
            printError('$exampleName integration tests failed.');
            failed = true;
          }
          ranAnyTests = true;
        } else {
          hasMisconfiguredIntegrationTest = true;
          printError('$misconfiguredJavaIntegrationTestErrorExplanation\n'
              '${misconfiguredTestFiles.map((File f) => '  ${f.path}').join('\n')}');
        }
      }
    }

    if (failed) {
      return _PlatformResult(RunState.failed);
    }
    if (hasMisconfiguredIntegrationTest) {
      return _PlatformResult(RunState.failed,
          error: 'Misconfigured integration test.');
    }
    if (!mode.integrationOnly && !ranUnitTests) {
      printError('No unit tests ran. Plugins are required to have unit tests.');
      return _PlatformResult(RunState.failed,
          error: 'No unit tests ran (use --exclude if this is intentional).');
    }
    if (!ranAnyTests) {
      return _PlatformResult(RunState.skipped);
    }
    return _PlatformResult(RunState.succeeded);
  }

  Future<_PlatformResult> _testIOS(RepositoryPackage plugin, _TestMode mode) {
    return _runXcodeTests(plugin, 'iOS', mode,
        extraFlags: _iOSDestinationFlags);
  }

  Future<_PlatformResult> _testMacOS(RepositoryPackage plugin, _TestMode mode) {
    return _runXcodeTests(plugin, 'macOS', mode);
  }

  /// Runs all applicable tests for [plugin], printing status and returning
  /// the test result.
  ///
  /// The tests targets must be added to the Xcode project of the example app,
  /// usually at "example/{ios,macos}/Runner.xcworkspace".
  Future<_PlatformResult> _runXcodeTests(
    RepositoryPackage plugin,
    String platform,
    _TestMode mode, {
    List<String> extraFlags = const <String>[],
  }) async {
    String? testTarget;
    const String unitTestTarget = 'RunnerTests';
    if (mode.unitOnly) {
      testTarget = unitTestTarget;
    } else if (mode.integrationOnly) {
      testTarget = 'RunnerUITests';
    }

    bool ranUnitTests = false;
    // Assume skipped until at least one test has run.
    RunState overallResult = RunState.skipped;
    for (final RepositoryPackage example in plugin.getExamples()) {
      final String exampleName = example.displayName;

      // If running a specific target, check that. Otherwise, check if there
      // are unit tests, since having no unit tests for a plugin is fatal
      // (by repo policy) even if there are integration tests.
      bool exampleHasUnitTests = false;
      final String? targetToCheck =
          testTarget ?? (mode.unit ? unitTestTarget : null);
      final Directory xcodeProject = example.directory
          .childDirectory(platform.toLowerCase())
          .childDirectory('Runner.xcodeproj');
      if (targetToCheck != null) {
        final bool? hasTarget =
            await _xcode.projectHasTarget(xcodeProject, targetToCheck);
        if (hasTarget == null) {
          printError('Unable to check targets for $exampleName.');
          overallResult = RunState.failed;
          continue;
        } else if (!hasTarget) {
          print('No "$targetToCheck" target in $exampleName; skipping.');
          continue;
        } else if (targetToCheck == unitTestTarget) {
          exampleHasUnitTests = true;
        }
      }

      _printRunningExampleTestsMessage(example, platform);
      final int exitCode = await _xcode.runXcodeBuild(
        example.directory,
        platform,
        // Clean before testing to remove cached swiftmodules from previous
        // runs, which can cause conflicts.
        actions: <String>['clean', 'test'],
        workspace: '${platform.toLowerCase()}/Runner.xcworkspace',
        scheme: 'Runner',
        configuration: 'Debug',
        extraFlags: <String>[
          if (testTarget != null) '-only-testing:$testTarget',
          ...extraFlags,
          'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
        ],
      );

      // The exit code from 'xcodebuild test' when there are no tests.
      const int xcodebuildNoTestExitCode = 66;
      switch (exitCode) {
        case xcodebuildNoTestExitCode:
          _printNoExampleTestsMessage(example, platform);
        case 0:
          printSuccess('Successfully ran $platform xctest for $exampleName');
          // If this is the first test, assume success until something fails.
          if (overallResult == RunState.skipped) {
            overallResult = RunState.succeeded;
          }
          if (exampleHasUnitTests) {
            ranUnitTests = true;
          }
        default:
          // Any failure means a failure overall.
          overallResult = RunState.failed;
          // If unit tests ran, note that even if they failed.
          if (exampleHasUnitTests) {
            ranUnitTests = true;
          }
          break;
      }
    }

    if (!mode.integrationOnly && !ranUnitTests) {
      printError('No unit tests ran. Plugins are required to have unit tests.');
      // Only return a specific summary error message about the missing unit
      // tests if there weren't also failures, to avoid having a misleadingly
      // specific message.
      if (overallResult != RunState.failed) {
        return _PlatformResult(RunState.failed,
            error: 'No unit tests ran (use --exclude if this is intentional).');
      }
    }

    return _PlatformResult(overallResult);
  }

  Future<_PlatformResult> _testWindows(
      RepositoryPackage plugin, _TestMode mode) async {
    if (mode.integrationOnly) {
      return _PlatformResult(RunState.skipped);
    }

    bool isTestBinary(File file) {
      return file.basename.endsWith('_test.exe') ||
          file.basename.endsWith('_tests.exe');
    }

    return _runGoogleTestTests(plugin, 'Windows', 'Debug',
        isTestBinary: isTestBinary);
  }

  Future<_PlatformResult> _testLinux(
      RepositoryPackage plugin, _TestMode mode) async {
    if (mode.integrationOnly) {
      return _PlatformResult(RunState.skipped);
    }

    bool isTestBinary(File file) {
      return file.basename.endsWith('_test') ||
          file.basename.endsWith('_tests');
    }

    // Since Linux uses a single-config generator, building-examples only
    // generates the build files for release, so the tests have to be run in
    // release mode as well.
    //
    // TODO(stuartmorgan): Consider adding a command to `flutter` that would
    // generate build files without doing a build, and using that instead of
    // relying on running build-examples. See
    // https://github.com/flutter/flutter/issues/93407.
    return _runGoogleTestTests(plugin, 'Linux', 'Release',
        isTestBinary: isTestBinary);
  }

  /// Finds every file in the relevant (based on [platformName], [buildMode],
  /// and [arch]) subdirectory of [plugin]'s build directory for which
  /// [isTestBinary] is true, and runs all of them, returning the overall
  /// result.
  ///
  /// The binaries are assumed to be Google Test test binaries, thus returning
  /// zero for success and non-zero for failure.
  Future<_PlatformResult> _runGoogleTestTests(
    RepositoryPackage plugin,
    String platformName,
    String buildMode, {
    required bool Function(File) isTestBinary,
  }) async {
    final List<File> testBinaries = <File>[];
    bool hasMissingBuild = false;
    bool buildFailed = false;
    String? arch;
    const String x64DirName = 'x64';
    const String arm64DirName = 'arm64';
    if (platform.isWindows) {
      arch = _abi == Abi.windowsX64 ? x64DirName : arm64DirName;
    } else if (platform.isLinux) {
      // TODO(stuartmorgan): Support arm64 if that ever becomes a supported
      // CI configuration for the repository.
      arch = 'x64';
    }
    for (final RepositoryPackage example in plugin.getExamples()) {
      CMakeProject project = CMakeProject(example.directory,
          buildMode: buildMode,
          processRunner: processRunner,
          platform: platform,
          arch: arch);
      if (platform.isWindows) {
        if (arch == arm64DirName && !project.isConfigured()) {
          // Check for x64, to handle builds newer than 3.13, but that don't yet
          // have https://github.com/flutter/flutter/issues/129807.
          // TODO(stuartmorgan): Remove this when CI no longer supports a
          // version of Flutter without the issue above fixed.
          project = CMakeProject(example.directory,
              buildMode: buildMode,
              processRunner: processRunner,
              platform: platform,
              arch: x64DirName);
        }
        if (!project.isConfigured()) {
          // Check again without the arch subdirectory, since 3.13 doesn't
          // have it yet.
          // TODO(stuartmorgan): Remove this when CI no longer supports Flutter
          // 3.13.
          project = CMakeProject(example.directory,
              buildMode: buildMode,
              processRunner: processRunner,
              platform: platform);
        }
      }
      if (!project.isConfigured()) {
        printError('ERROR: Run "flutter build" on ${example.displayName}, '
            'or run this tool\'s "build-examples" command, for the target '
            'platform before executing tests.');
        hasMissingBuild = true;
        continue;
      }

      // By repository convention, example projects create an aggregate target
      // called 'unit_tests' that builds all unit tests (usually just an alias
      // for a specific test target).
      final int exitCode = await project.runBuild('unit_tests');
      if (exitCode != 0) {
        printError('${example.displayName} unit tests failed to build.');
        buildFailed = true;
      }

      testBinaries.addAll(project.buildDirectory
          .listSync(recursive: true)
          .whereType<File>()
          .where(isTestBinary)
          .where((File file) {
        // Only run the `buildMode` build of the unit tests, to avoid running
        // the same tests multiple times.
        final List<String> components = path.split(file.path);
        return components.contains(buildMode) ||
            components.contains(buildMode.toLowerCase());
      }));
    }

    if (hasMissingBuild) {
      return _PlatformResult(RunState.failed,
          error: 'Examples must be built before testing.');
    }

    if (buildFailed) {
      return _PlatformResult(RunState.failed,
          error: 'Failed to build $platformName unit tests.');
    }

    if (testBinaries.isEmpty) {
      final String binaryExtension = platform.isWindows ? '.exe' : '';
      printError(
          'No test binaries found. At least one *_test(s)$binaryExtension '
          'binary should be built by the example(s)');
      return _PlatformResult(RunState.failed,
          error: 'No $platformName unit tests found');
    }

    bool passing = true;
    for (final File test in testBinaries) {
      print('Running ${test.basename}...');
      final int exitCode =
          await processRunner.runAndStream(test.path, <String>[]);
      passing &= exitCode == 0;
    }
    return _PlatformResult(passing ? RunState.succeeded : RunState.failed);
  }

  /// Prints a standard format message indicating that [platform] tests for
  /// [plugin]'s [example] are about to be run.
  void _printRunningExampleTestsMessage(
      RepositoryPackage example, String platform) {
    print('Running $platform tests for ${example.displayName}...');
  }

  /// Prints a standard format message indicating that no tests were found for
  /// [plugin]'s [example] for [platform].
  void _printNoExampleTestsMessage(RepositoryPackage example, String platform) {
    print('No $platform tests found for ${example.displayName}');
  }
}

// The type for a function that takes a plugin directory and runs its native
// tests for a specific platform.
typedef _TestFunction = Future<_PlatformResult> Function(
    RepositoryPackage, _TestMode);

/// A collection of information related to a specific platform.
class _PlatformDetails {
  const _PlatformDetails(
    this.label,
    this.testFunction,
  );

  /// The name to use in output.
  final String label;

  /// The function to call to run tests.
  final _TestFunction testFunction;
}

/// Enabled state for different test types.
class _TestMode {
  const _TestMode({required this.unit, required this.integration});

  final bool unit;
  final bool integration;

  bool get integrationOnly => integration && !unit;
  bool get unitOnly => unit && !integration;
}

/// The result of running a single platform's tests.
class _PlatformResult {
  _PlatformResult(this.state, {this.error});

  /// The overall state of the platform's tests. This should be:
  /// - failed if any tests failed.
  /// - succeeded if at least one test ran, and all tests passed.
  /// - skipped if no tests ran.
  final RunState state;

  /// An optional error string to include in the summary for this platform.
  ///
  /// Ignored unless [state] is `failed`.
  final String? error;
}

/// The state of a .java test file.
class _JavaTestInfo {
  const _JavaTestInfo(
      {required this.usesFlutterTestRunner,
      required this.hasDartIntegrationTestAnnotation});

  /// Whether the test class uses the FlutterTestRunner.
  final bool usesFlutterTestRunner;

  /// Whether the test class has the @DartIntegrationTest annotation.
  final bool hasDartIntegrationTestAnnotation;
}
