1<?php
2/* Copyright 2012-present Facebook, Inc.
3 * Licensed under the Apache License, Version 2.0 */
4
5class WatchmanTapEngine {
6  private $projectRoot;
7
8  public function setProjectRoot($root) {
9    $this->projectRoot = $root;
10  }
11
12  protected function getProjectRoot() {
13    return $this->projectRoot;
14  }
15
16  public function run($tests) {
17    return $this->runUnitTests($tests);
18  }
19
20  public function getEnableCoverage() {
21    return false;
22  }
23
24  public function runUnitTests($tests) {
25    // Now find all the test programs
26    $root = $this->getProjectRoot();
27    $test_dir = $root . "/tests/";
28    $futures = array();
29
30    if (!$tests) {
31      $paths = glob($test_dir . "*.t");
32    } else {
33      $paths = array();
34      foreach ($tests as $path) {
35        $tpath = preg_replace('/\.c$/', '.t', $path);
36        if (preg_match("/\.c$/", $path) && file_exists($tpath)) {
37          $paths[] = realpath($tpath);
38        }
39      }
40    }
41
42    foreach ($paths as $test) {
43      $relname = substr($test, strlen($test_dir));
44      $futures[$relname] = new ExecFuture($test);
45    }
46
47    $results = array();
48    $futures = new FutureIterator($futures);
49    foreach ($futures->limit(4) as $test => $future) {
50      list($err, $stdout, $stderr) = $future->resolve();
51
52      $results[] = $this->parseTestResults(
53        $test, $err, $stdout, $stderr);
54    }
55
56    return $results;
57  }
58
59  private function parseTestResults($test, $err, $stdout, $stderr) {
60    $result = new ArcanistUnitTestResult();
61    $result->setName($test);
62    $result->setUserData($stdout . $stderr);
63    $result->setResult($err == 0 ?
64      ArcanistUnitTestResult::RESULT_PASS :
65      ArcanistUnitTestResult::RESULT_FAIL
66    );
67    if (preg_match("/# ELAPSED: (\d+)ms/", $stderr, $M)) {
68      $result->setDuration($M[1] / 1000);
69    }
70
71    return $result;
72  }
73
74  protected function supportsRunAllTests() {
75    return true;
76  }
77}
78
79// vim:ts=2:sw=2:et:
80