in src/Runner/HackTestRunner.hack [26:81]
public static async function runAsync(
vec<string> $paths,
this::TFilters $filters,
(function(ProgressEvent): Awaitable<void>) $progress_callback,
): Awaitable<void> {
await $progress_callback(new TestRunStartedProgressEvent());
await using (
(new TestRunFinishedProgressEvent())->onScopeExit($progress_callback)
);
$files = keyset[];
foreach ($paths as $path) {
$files = Keyset\union($files, (new FileRetriever($path))->getTestFiles());
}
$classes_or_exceptions = ClassRetriever::forFiles($files);
$classes = vec[];
foreach ($classes_or_exceptions as $path => $coe) {
if ($coe is _Private\WrappedResult<_>) {
try {
$classes[] = tuple($path, $coe->getResult()->getTestClassName());
} catch (InvalidTestClassException $ex) {
await $progress_callback(new FileErrorProgressEvent($path, $ex));
}
continue;
}
$wex = $coe as _Private\WrappedException<_>;
await $progress_callback(new FileErrorProgressEvent(
$path,
$wex->getException() as InvalidTestFileException,
));
}
$class_filter = $filters['classes'];
$method_filter = $filters['methods'];
foreach ($classes as list($path, $classname)) {
if ($classname === null) {
continue;
}
if (!$class_filter($classname)) {
continue;
}
await $progress_callback(new StartingTestClassEvent($path, $classname));
await using (
(new FinishedTestClassEvent($path, $classname))->onScopeExit(
$progress_callback,
)
) {
$test_case = new $classname();
await $test_case->runTestsAsync(
$method ==> $method_filter($classname, $method),
$progress_callback,
);
}
}
}