<?php

final class MochaUnitTestEngine extends ArcanistUnitTestEngine {

  public function run() {
    $test_future = $this->buildTestFuture();
    $this->runTests($test_future);
    return $this->parseXunitResults($test_future);
  }

  protected function supportsRunAllTests() {
    return true;
  }

  private function buildTestFuture() {
    $future = new ExecFuture(
      'npm --loglevel silent test -- -R xunit'
    );
    $future->setCWD($this->getWorkingCopy()->getProjectRoot());

    return $future;
  }

  private function runTests($test_future) {
    try {
      $test_future->resolvex();
    } catch (CommandException $exception) {
      if ($exception->getError() > 1) {
        // Mocha returns 1 if tests are failing
        throw $exception;
      }
    }
  }

  private function parseXunitResults($test_future) {
    $parser = new ArcanistXUnitTestResultParser();
    $results = $test_future->readStdout();
    try {
      return $parser->parseTestResults($results);
    } catch (Exception $exception) {
      throw new Exception(
        "Couldn't run tests. Most likely, `npm test` is failing, so run that ".
        "command directly for more details.\n\n".
        "Raw exception dump:\n".
        $exception
      );
    }
  }
}
