findTest method

Future<(String, DetermineFlutterOrDart)?> findTest(
  1. Map<String, DetermineFlutterOrDart> tests,
  2. String modifiedFile, {
  3. required bool returnTestFile,
})

Implementation

Future<(String test, DetermineFlutterOrDart tool)?> findTest(
  Map<String, DetermineFlutterOrDart> tests,
  String modifiedFile, {
  required bool returnTestFile,
}) async {
  // {<directory>, <key>}
  final keys = <String, String>{};

  for (final test in tests.keys) {
    if (fs.isFileSync(test)) {
      keys[fs.file(test).parent.path] = test;
    } else {
      keys[test] = test;
    }
  }

  (String, DetermineFlutterOrDart)? testResult;

  for (final MapEntry(key: directory, value: test) in keys.entries) {
    // check if the modified file is in the test directory
    if (modifiedFile.startsWith(directory)) {
      testResult = (directory, tests[test]!);
      break;
    }

    // check if the modified file is in the lib directory
    // associated with the test directory
    // eg. lib/foo.dart -> test/foo_test.dart
    final libDir = directory.replaceAll(RegExp(r'test$'), 'lib');
    if (modifiedFile.startsWith(libDir)) {
      testResult = (directory, tests[test]!);
      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: testResult.$1);

  if (possibleFiles.isEmpty) {
    return null;
  }

  if (possibleFiles.length == 1) {
    return (possibleFiles.first, testResult.$2);
  }

  final libPath = testResult.$1.replaceAll(RegExp(r'.*.?test$'), 'lib');
  final modifiedFileInLib = modifiedFile
      .replaceAll(libPath, '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) {
        return (test, testResult.$2);
      }
    }
  }

  return null;
}