findTest method

Future<PackageToTest?> findTest(
  1. Iterable<PackageToTest> packagesToTest,
  2. String modifiedFile, {
  3. required bool returnTestFile,
})

Implementation

Future<PackageToTest?> findTest(
  Iterable<PackageToTest> packagesToTest,
  String modifiedFile, {
  required bool returnTestFile,
}) async {
  PackageToTest? testResult;

  final sorted = [...packagesToTest]
    ..sort((a, b) => b.packagePath.length.compareTo(a.packagePath.length));

  for (final packageToTest in sorted) {
    if (modifiedFile.startsWith(packageToTest.packagePath)) {
      final libSegments = path.split(packageToTest.packagePath);
      final modifiedSegments = path.split(modifiedFile);

      if (libSegments.length > modifiedSegments.length) {
        continue;
      }

      final segments = modifiedSegments.skip(libSegments.length).toList();

      final libIndex = segments.indexOf('lib');
      final testIndex = segments.indexOf('test');
      if ((libIndex != 0) & (testIndex != 0)) {
        continue;
      }

      testResult = packageToTest;
      break;
    }
  }

  if (testResult == null) {
    return null;
  }

  if (!returnTestFile) {
    return testResult;
  }

  // check for the test file associated with the modified file
  final base = path.basenameWithoutExtension(modifiedFile);
  final nameOfTest =
      base.endsWith('_test') ? '$base.dart' : '${base}_test.dart';
  final possibleFiles = await findFile.childrenOf(
    nameOfTest,
    directoryPath: path.join(testResult.packagePath, 'test'),
  );

  if (possibleFiles.isEmpty) {
    return null;
  }

  if (possibleFiles.length == 1) {
    testResult.optimizedPath = possibleFiles.first;
    return testResult;
  }

  final libPath = path.join(testResult.packagePath, 'lib');
  final modifiedFileInLib = modifiedFile
      .replaceAll(libPath, path.join(testResult.packagePath, 'test'))
      .replaceAll(path.basename(modifiedFile), nameOfTest);
  final segments = path.split(modifiedFileInLib);

  for (final test in possibleFiles) {
    final segmentsInTestFile = path.split(test);
    if (segmentsInTestFile.length != segments.length) {
      continue;
    }

    for (var i = 0; i < segments.length; i++) {
      if (segments[i] != segmentsInTestFile[i]) {
        break;
      }

      if (i == segments.length - 1) {
        testResult.optimizedPath = test;
        return testResult;
      }
    }
  }

  return null;
}