Development

Changeset 19521

You must first sign up to be able to contribute.

Changeset 19521

Show
Ignore:
Timestamp:
06/24/09 21:56:52 (8 months ago)
Author:
fabien
Message:

[lime] added XML output support (JUnit compatible XML format)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • tools/lime/trunk/lib/lime.php

    r19488 r19521  
    2020  const EPSILON = 0.0000000001; 
    2121 
    22   public $plan    = null; 
    23   public $test_nb = 0; 
    24   public $failed  = 0; 
    25   public $passed  = 0; 
    26   public $skipped = 0; 
    27   public $output  = null; 
     22  protected $test_nb = 0; 
     23  protected $output  = null; 
     24  protected $results = array(); 
     25 
     26  static protected $all_results = array(); 
    2827 
    2928  public function __construct($plan = null, $output_instance = null) 
    3029  { 
    31     $this->plan   = $plan; 
    3230    $this->output = $output_instance ? $output_instance : new lime_output(); 
    3331 
    34     null !== $this->plan and $this->output->echoln(sprintf("1..%d", $this->plan)); 
     32    $d = debug_backtrace(); 
     33    self::$all_results[] = array( 
     34      'file'  => isset($d[0]) ? $d[0]['file'] : '', 
     35      'tests' => array(), 
     36      'stats' => array('plan' => $plan, 'total' => 0, 'failed' => array(), 'passed' => array(), 'skipped' => array()), 
     37    ); 
     38    $this->results = &self::$all_results[count(self::$all_results) - 1]; 
     39 
     40    null !== $plan and $this->output->echoln(sprintf("1..%d", $plan)); 
     41  } 
     42 
     43  static public function reset() 
     44  { 
     45    self::$all_results = array(); 
     46  } 
     47 
     48  static public function to_array() 
     49  { 
     50    return self::$all_results; 
     51  } 
     52 
     53  static public function to_xml($results = null) 
     54  { 
     55    if (is_null($results)) 
     56    { 
     57      $results = self::$all_results; 
     58    } 
     59 
     60    $dom = new DOMDocument('1.0', 'UTF-8'); 
     61    $dom->formatOutput = true; 
     62    $dom->appendChild($testsuites = $dom->createElement('testsuites')); 
     63 
     64    $errors = 0; 
     65    $failures = 0; 
     66    $errors = 0; 
     67    $skipped = 0; 
     68    $assertions = 0; 
     69 
     70    foreach ($results as $result) 
     71    { 
     72      $testsuites->appendChild($testsuite = $dom->createElement('testsuite')); 
     73      $testsuite->setAttribute('name', basename($result['file'], '.php')); 
     74      $testsuite->setAttribute('file', $result['file']); 
     75      $testsuite->setAttribute('failures', count($result['stats']['failed'])); 
     76      $testsuite->setAttribute('errors', 0); 
     77      $testsuite->setAttribute('skipped', count($result['stats']['skipped'])); 
     78      $testsuite->setAttribute('tests', $result['stats']['plan']); 
     79      $testsuite->setAttribute('assertions', $result['stats']['plan']); 
     80 
     81      $failures += count($result['stats']['failed']); 
     82      $skipped += count($result['stats']['skipped']); 
     83      $assertions += $result['stats']['plan']; 
     84 
     85      foreach ($result['tests'] as $test) 
     86      { 
     87        $testsuite->appendChild($testcase = $dom->createElement('testcase')); 
     88        $testcase->setAttribute('name', $test['message']); 
     89        $testcase->setAttribute('file', $test['file']); 
     90        $testcase->setAttribute('line', $test['line']); 
     91        $testcase->setAttribute('assertions', 1); 
     92        if (!$test['status']) 
     93        { 
     94          $testcase->appendChild($failure = $dom->createElement('failure')); 
     95          $failure->setAttribute('type', 'lime'); 
     96          if ($test['error']) 
     97          { 
     98            $failure->appendChild($dom->createTextNode($test['error'])); 
     99          } 
     100        } 
     101      } 
     102    } 
     103 
     104    $testsuites->setAttribute('failures', $failures); 
     105    $testsuites->setAttribute('errors', $errors); 
     106    $testsuites->setAttribute('tests', $assertions); 
     107    $testsuites->setAttribute('assertions', $assertions); 
     108    $testsuites->setAttribute('skipped', $skipped); 
     109 
     110    return $dom->saveXml(); 
    35111  } 
    36112 
    37113  public function __destruct() 
    38114  { 
    39     $total = $this->passed + $this->failed + $this->skipped; 
    40  
    41     null === $this->plan and $this->plan = $total and $this->output->echoln(sprintf("1..%d", $this->plan)); 
    42  
    43     if ($total > $this->plan) 
    44     { 
    45       $this->output->red_bar(sprintf(" Looks like you planned %d tests but ran %d extra.", $this->plan, $total - $this->plan)); 
    46     } 
    47     elseif ($total < $this->plan) 
    48     { 
    49       $this->output->red_bar(sprintf(" Looks like you planned %d tests but only ran %d.", $this->plan, $total)); 
    50     } 
    51  
    52     if ($this->failed) 
    53     { 
    54       $this->output->red_bar(sprintf(" Looks like you failed %d tests of %d.", $this->failed, $this->passed + $this->failed)); 
    55     } 
    56     else if ($total == $this->plan) 
     115    $plan = $this->results['stats']['plan']; 
     116    $passed = count($this->results['stats']['passed']); 
     117    $failed = count($this->results['stats']['failed']); 
     118    $total = $this->results['stats']['total']; 
     119    is_null($plan) and $plan = $total and $this->output->echoln(sprintf("1..%d", $plan)); 
     120 
     121    if ($total > $plan) 
     122    { 
     123      $this->output->red_bar(sprintf(" Looks like you planned %d tests but ran %d extra.", $plan, $total - $plan)); 
     124    } 
     125    elseif ($total < $plan) 
     126    { 
     127      $this->output->red_bar(sprintf(" Looks like you planned %d tests but only ran %d.", $plan, $total)); 
     128    } 
     129 
     130    if ($failed) 
     131    { 
     132      $this->output->red_bar(sprintf(" Looks like you failed %d tests of %d.", $failed, $passed + $failed)); 
     133    } 
     134    else if ($total == $plan) 
    57135    { 
    58136      $this->output->green_bar(" Looks like everything went fine."); 
     
    72150  public function ok($exp, $message = '') 
    73151  { 
     152    $this->update_stats(); 
     153 
    74154    if ($result = (boolean) $exp) 
    75155    { 
    76       ++$this->passed
     156      $this->results['stats']['passed'][] = $this->test_nb
    77157    } 
    78158    else 
    79159    { 
    80       ++$this->failed; 
    81     } 
    82     $this->output->echoln(sprintf("%s %d%s", $result ? 'ok' : 'not ok', ++$this->test_nb, $message = $message ? sprintf('%s %s', 0 === strpos($message, '#') ? '' : ' -', $message) : '')); 
     160      $this->results['stats']['failed'][] = $this->test_nb; 
     161    } 
     162    $this->results['tests'][$this->test_nb]['message'] = $message; 
     163    $this->results['tests'][$this->test_nb]['status'] = $result; 
     164    $this->output->echoln(sprintf("%s %d%s", $result ? 'ok' : 'not ok', $this->test_nb, $message = $message ? sprintf('%s %s', 0 === strpos($message, '#') ? '' : ' -', $message) : '')); 
    83165 
    84166    if (!$result) 
    85167    { 
    86       $traces = debug_backtrace(); 
    87       if (!empty($_SERVER['PHP_SELF']))  
    88       { 
    89         $i = strstr($traces[0]['file'], $_SERVER['PHP_SELF']) ? 0 : (isset($traces[1]['file']) ? 1 : 0); 
    90       } 
    91       else 
    92       { 
    93         $i = 0; 
    94       } 
    95       $this->output->diag(sprintf('    Failed test (%s at line %d)', str_replace(getcwd(), '.', $traces[$i]['file']), $traces[$i]['line'])); 
     168      $this->output->diag(sprintf('    Failed test (%s at line %d)', str_replace(getcwd(), '.', $this->results['tests'][$this->test_nb]['file']), $this->results['tests'][$this->test_nb]['line'])); 
    96169    } 
    97170 
     
    125198    if (!$result = $this->ok($value, $message)) 
    126199    { 
    127       $this->output->diag(sprintf("           got: %s", var_export($exp1, true)), sprintf("      expected: %s", var_export($exp2, true))); 
     200      $this->set_last_test_errors(array(sprintf("           got: %s", var_export($exp1, true)), sprintf("      expected: %s", var_export($exp2, true)))); 
    128201    } 
    129202 
     
    144217    if (!$result = $this->ok($exp1 != $exp2, $message)) 
    145218    { 
    146       $this->output->diag(sprintf("      %s", var_export($exp2, true)), '          ne', sprintf("      %s", var_export($exp2, true))); 
     219      $this->set_last_test_errors(array(sprintf("      %s", var_export($exp2, true)), '          ne', sprintf("      %s", var_export($exp2, true)))); 
    147220    } 
    148221 
     
    163236    if (!$result = $this->ok(preg_match($regex, $exp), $message)) 
    164237    { 
    165       $this->output->diag(sprintf("                    '%s'", $exp), sprintf("      doesn't match '%s'", $regex)); 
     238      $this->set_last_test_errors(array(sprintf("                    '%s'", $exp), sprintf("      doesn't match '%s'", $regex))); 
    166239    } 
    167240 
     
    182255    if (!$result = $this->ok(!preg_match($regex, $exp), $message)) 
    183256    { 
    184       $this->output->diag(sprintf("               '%s'", $exp), sprintf("      matches '%s'", $regex)); 
     257      $this->set_last_test_errors(array(sprintf("               '%s'", $exp), sprintf("      matches '%s'", $regex))); 
    185258    } 
    186259 
     
    203276    if (!$this->ok($result, $message)) 
    204277    { 
    205       $this->output->diag(sprintf("      %s", str_replace("\n", '', var_export($exp1, true))), sprintf("          %s", $op), sprintf("      %s", str_replace("\n", '', var_export($exp2, true)))); 
     278      $this->set_last_test_errors(array(sprintf("      %s", str_replace("\n", '', var_export($exp1, true))), sprintf("          %s", $op), sprintf("      %s", str_replace("\n", '', var_export($exp2, true))))); 
    206279    } 
    207280 
     
    233306    !$this->ok($result, $message); 
    234307 
    235     !$result and $this->output->diag($failed_messages); 
     308    !$result and $this->set_last_test_errors($failed_messages); 
    236309 
    237310    return $result; 
     
    252325    if (!$result = $this->ok($type == $class, $message)) 
    253326    { 
    254       $this->output->diag(sprintf("      variable isn't a '%s' it's a '%s'", $class, $type)); 
     327      $this->set_last_test_errors(array(sprintf("      variable isn't a '%s' it's a '%s'", $class, $type))); 
    255328    } 
    256329 
     
    271344    if (!$result = $this->ok($this->test_is_deeply($exp1, $exp2), $message)) 
    272345    { 
    273       $this->output->diag(sprintf("           got: %s", str_replace("\n", '', var_export($exp1, true))), sprintf("      expected: %s", str_replace("\n", '', var_export($exp2, true)))); 
     346      $this->set_last_test_errors(array(sprintf("           got: %s", str_replace("\n", '', var_export($exp1, true))), sprintf("      expected: %s", str_replace("\n", '', var_export($exp2, true))))); 
    274347    } 
    275348 
     
    325398    for ($i = 0; $i < $nb_tests; $i++) 
    326399    { 
    327       ++$this->skipped and --$this->passed; 
    328400      $this->pass(sprintf("# SKIP%s", $message ? ' '.$message : '')); 
     401      $this->results['stats']['skipped'][] = $this->test_nb; 
     402      array_pop($this->results['stats']['passed']); 
    329403    } 
    330404  } 
     
    339413  public function todo($message = '') 
    340414  { 
    341     ++$this->skipped and --$this->passed; 
    342415    $this->pass(sprintf("# TODO%s", $message ? ' '.$message : '')); 
     416    $this->results['stats']['skipped'][] = $this->test_nb; 
     417    array_pop($this->results['stats']['passed']); 
    343418  } 
    344419 
     
    355430    if (!$result = $this->ok((@include($file)) == 1, $message)) 
    356431    { 
    357       $this->output->diag(sprintf("      Tried to include '%s'", $file)); 
     432      $this->set_last_test_errors(array(sprintf("      Tried to include '%s'", $file))); 
    358433    } 
    359434 
     
    410485  { 
    411486    $this->output->error($message); 
     487  } 
     488 
     489  protected function update_stats() 
     490  { 
     491    ++$this->test_nb; 
     492    ++$this->results['stats']['total']; 
     493 
     494    $this->results['tests'][$this->test_nb]['file'] = 'n/a'; 
     495    $this->results['tests'][$this->test_nb]['line'] = '0'; 
     496    $test_file = self::$all_results[count(self::$all_results) - 1]['file']; 
     497    foreach (debug_backtrace() as $trace) 
     498    { 
     499      if (isset($trace['file']) && $test_file == $trace['file']) 
     500      { 
     501        $this->results['tests'][$this->test_nb]['file'] = $trace['file']; 
     502        $this->results['tests'][$this->test_nb]['line'] = $trace['line']; 
     503 
     504        break; 
     505      } 
     506    } 
     507  } 
     508 
     509  protected function set_last_test_errors(array $errors) 
     510  { 
     511    $this->output->diag($errors); 
     512 
     513    $this->results['tests'][$this->test_nb]['error'] = implode("\n", $errors); 
    412514  } 
    413515} 
     
    581683  } 
    582684 
     685  public function to_array() 
     686  { 
     687    $results = array(); 
     688    foreach ($this->stats['files'] as $file => $stat) 
     689    { 
     690      $results = array_merge($results, $stat['output']); 
     691    } 
     692 
     693    return $results; 
     694  } 
     695 
     696  public function to_xml() 
     697  { 
     698    return lime_test::to_xml($this->to_array()); 
     699  } 
     700 
    583701  public function run() 
    584702  { 
     
    592710 
    593711    $this->stats = array( 
    594       '_failed_files' => array(), 
    595       '_failed_tests' => 0, 
    596       '_nb_tests'     => 0, 
     712      'files'        => array(), 
     713      'failed_files' => array(), 
     714      'failed_tests' => 0, 
     715      'total'        => 0, 
    597716    ); 
    598717 
    599718    foreach ($this->files as $file) 
    600719    { 
    601       $this->stats[$file] = array( 
    602         'plan'     => null, 
    603         'nb_tests' => 0, 
    604         'failed'   => array(), 
    605         'passed'   => array(), 
     720      $this->stats['files'][$file] = array(); 
     721      $stats = &$this->stats['files'][$file]; 
     722 
     723      $relative_file = $this->get_relative_file($file); 
     724 
     725      $test_file = tempnam(sys_get_temp_dir(), 'lime'); 
     726      $result_file = tempnam(sys_get_temp_dir(), 'lime'); 
     727      file_put_contents($test_file, <<<EOF 
     728<?php 
     729include('$file'); 
     730file_put_contents('$result_file', serialize(lime_test::to_array())); 
     731EOF 
    606732      ); 
    607       $this->current_file = $file; 
    608       $this->current_test = 0; 
    609       $relative_file = $this->get_relative_file($file); 
    610  
    611       ob_start(array($this, 'process_test_output')); 
     733 
     734      ob_start(); 
    612735      // see http://trac.symfony-project.org/ticket/5437 for the explanation on the weird "cd" thing 
    613       passthru(sprintf('cd & %s %s 2>&1', escapeshellarg($this->php_cli), escapeshellarg($file)), $return); 
     736      passthru(sprintf('cd & %s %s 2>&1', escapeshellarg($this->php_cli), escapeshellarg($test_file)), $return); 
    614737      ob_end_clean(); 
    615  
     738      unlink($test_file); 
     739 
     740      $output = file_get_contents($result_file); 
     741      $stats['output'] = $output ? unserialize($output) : ''; 
     742      if (!$stats['output']) 
     743      { 
     744        $stats['output'] = array(array('file' => $file, 'tests' => array(), 'stats' => array('plan' => 1, 'total' => 1, 'failed' => array(0), 'passed' => array(), 'skipped' => array()))); 
     745      } 
     746      unlink($result_file); 
     747 
     748      $file_stats = &$stats['output'][0]['stats']; 
     749 
     750      $delta = 0; 
    616751      if ($return > 0) 
    617752      { 
    618         $this->stats[$file]['status'] = 'dubious'; 
    619         $this->stats[$file]['status_code'] = $return; 
     753        $stats['status'] = 'dubious'; 
     754        $stats['status_code'] = $return; 
    620755      } 
    621756      else 
    622757      { 
    623         $delta = $this->stats[$file]['plan'] - $this->stats[$file]['nb_tests']; 
    624         if ($delta > 0) 
    625         { 
    626           $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->output->comment(sprintf('# Looks like you planned %d tests but only ran %d.', $this->stats[$file]['plan'], $this->stats[$file]['nb_tests'])))); 
    627           $this->stats[$file]['status'] = 'dubious'; 
    628           $this->stats[$file]['status_code'] = 255; 
    629           $this->stats['_nb_tests'] += $delta; 
    630           for ($i = 1; $i <= $delta; $i++) 
    631           { 
    632             $this->stats[$file]['failed'][] = $this->stats[$file]['nb_tests'] + $i; 
    633           } 
    634         } 
    635         else if ($delta < 0) 
    636         { 
    637           $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->output->comment(sprintf('# Looks like you planned %s test but ran %s extra.', $this->stats[$file]['plan'], $this->stats[$file]['nb_tests'] - $this->stats[$file]['plan'])))); 
    638           $this->stats[$file]['status'] = 'dubious'; 
    639           $this->stats[$file]['status_code'] = 255; 
    640           for ($i = 1; $i <= -$delta; $i++) 
    641           { 
    642             $this->stats[$file]['failed'][] = $this->stats[$file]['plan'] + $i; 
    643           } 
     758        $this->stats['total'] += $file_stats['total']; 
     759 
     760        if (!$file_stats['plan']) 
     761        { 
     762          $file_stats['plan'] = $file_stats['total']; 
     763        } 
     764 
     765        $delta = $file_stats['plan'] - $file_stats['total']; 
     766        if (0 != $delta) 
     767        { 
     768          $stats['status'] = 'dubious'; 
     769          $stats['status_code'] = 255; 
    644770        } 
    645771        else 
    646772        { 
    647           $this->stats[$file]['status_code'] = 0; 
    648           $this->stats[$file]['status'] = $this->stats[$file]['failed'] ? 'not ok' : 'ok'; 
    649         } 
    650       } 
    651  
    652       $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->stats[$file]['status'])); 
    653       if (($nb = count($this->stats[$file]['failed'])) || $return > 0) 
    654       { 
    655         if ($nb) 
    656         { 
    657           $this->output->echoln(sprintf("    Failed tests: %s", implode(', ', $this->stats[$file]['failed']))); 
    658         } 
    659         $this->stats['_failed_files'][] = $file; 
    660         $this->stats['_failed_tests']  += $nb; 
    661       } 
    662  
    663       if ('dubious' == $this->stats[$file]['status']) 
    664       { 
    665         $this->output->echoln(sprintf('    Test returned status %s', $this->stats[$file]['status_code'])); 
    666       } 
    667     } 
    668  
    669     if (count($this->stats['_failed_files'])) 
     773          $stats['status'] = $file_stats['failed'] ? 'not ok' : 'ok'; 
     774          $stats['status_code'] = 0; 
     775        } 
     776      } 
     777 
     778      $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $stats['status'])); 
     779 
     780      if (0 != $stats['status_code']) 
     781      { 
     782        $this->output->echoln(sprintf('    Test returned status %s', $stats['status_code'])); 
     783      } 
     784 
     785      if ('ok' != $stats['status']) 
     786      { 
     787        $this->stats['failed_files'][] = $file; 
     788      } 
     789 
     790      if ($delta > 0) 
     791      { 
     792        $this->output->echoln(sprintf('    Looks like you planned %d tests but only ran %d.', $file_stats['plan'], $file_stats['total'])); 
     793 
     794        $this->stats['failed_tests'] += $delta; 
     795        $this->stats['total'] += $delta; 
     796      } 
     797      else if ($delta < 0) 
     798      { 
     799        $this->output->echoln(sprintf('    Looks like you planned %s test but ran %s extra.', $file_stats['plan'], $file_stats['total'] - $file_stats['plan'])); 
     800      } 
     801 
     802      if (false !== $file_stats && $file_stats['failed']) 
     803      { 
     804        $this->stats['failed_tests'] += count($file_stats['failed']); 
     805 
     806        $this->output->echoln(sprintf("    Failed tests: %s", implode(', ', $file_stats['failed']))); 
     807      } 
     808    } 
     809 
     810    if (count($this->stats['failed_files'])) 
    670811    { 
    671812      $format = "%-30s  %4s  %5s  %5s  %s"; 
    672813      $this->output->echoln(sprintf($format, 'Failed Test', 'Stat', 'Total', 'Fail', 'List of Failed')); 
    673814      $this->output->echoln("------------------------------------------------------------------"); 
    674       foreach ($this->stats as $file => $file_stat) 
    675       { 
    676         if (!in_array($file, $this->stats['_failed_files'])) continue; 
    677  
     815      foreach ($this->stats['files'] as $file => $stat) 
     816      { 
     817        if (!in_array($file, $this->stats['failed_files'])) 
     818        { 
     819          continue; 
     820        } 
    678821        $relative_file = $this->get_relative_file($file); 
    679         $this->output->echoln(sprintf($format, substr($relative_file, -min(30, strlen($relative_file))), $file_stat['status_code'], count($file_stat['failed']) + count($file_stat['passed']), count($file_stat['failed']), implode(' ', $file_stat['failed']))); 
     822 
     823        if (isset($stat['output'][0])) 
     824        { 
     825          $this->output->echoln(sprintf($format, substr($relative_file, -min(30, strlen($relative_file))), $stat['status_code'], count($stat['output'][0]['stats']['failed']) + count($stat['output'][0]['stats']['passed']), count($stat['output'][0]['stats']['failed']), implode(' ', $stat['output'][0]['stats']['failed']))); 
     826        } 
     827        else 
     828        { 
     829          $this->output->echoln(sprintf($format, substr($relative_file, -min(30, strlen($relative_file))), $stat['status_code'], '', '', '')); 
     830        } 
    680831      } 
    681832 
    682833      $this->output->red_bar(sprintf('Failed %d/%d test scripts, %.2f%% okay. %d/%d subtests failed, %.2f%% okay.', 
    683         $nb_failed_files = count($this->stats['_failed_files']), 
     834        $nb_failed_files = count($this->stats['failed_files']), 
    684835        $nb_files = count($this->files), 
    685836        ($nb_files - $nb_failed_files) * 100 / $nb_files, 
    686         $nb_failed_tests = $this->stats['_failed_tests'], 
    687         $nb_tests = $this->stats['_nb_tests'], 
     837        $nb_failed_tests = $this->stats['failed_tests'], 
     838        $nb_tests = $this->stats['total'], 
    688839        $nb_tests > 0 ? ($nb_tests - $nb_failed_tests) * 100 / $nb_tests : 0 
    689840      )); 
     
    692843    { 
    693844      $this->output->green_bar(' All tests successful.'); 
    694       $this->output->green_bar(sprintf(' Files=%d, Tests=%d', count($this->files), $this->stats['_nb_tests'])); 
    695     } 
    696  
    697     return $this->stats['_failed_files'] ? false : true; 
     845      $this->output->green_bar(sprintf(' Files=%d, Tests=%d', count($this->files), $this->stats['total'])); 
     846    } 
     847 
     848    return $this->stats['failed_files'] ? false : true; 
    698849  } 
    699850 
    700851  public function get_failed_files() 
    701852  { 
    702     return isset($this->stats['_failed_files']) ? $this->stats['_failed_files'] : array(); 
    703   } 
    704  
    705   private function process_test_output($lines) 
    706   { 
    707     foreach (explode("\n", $lines) as $text) 
    708     { 
    709       if (false !== strpos($text, 'not ok ')) 
    710       { 
    711         ++$this->current_test; 
    712         $test_number = (int) substr($text, 7); 
    713         $this->stats[$this->current_file]['failed'][] = $test_number; 
    714  
    715         ++$this->stats[$this->current_file]['nb_tests']; 
    716         ++$this->stats['_nb_tests']; 
    717       } 
    718       else if (false !== strpos($text, 'ok ')) 
    719       { 
    720         ++$this->stats[$this->current_file]['nb_tests']; 
    721         ++$this->stats['_nb_tests']; 
    722       } 
    723       else if (preg_match('/^1\.\.(\d+)/', $text, $match)) 
    724       { 
    725         $this->stats[$this->current_file]['plan'] = $match[1]; 
    726       } 
    727     } 
    728  
    729     return; 
     853    return isset($this->stats['failed_files']) ? $this->stats['failed_files'] : array(); 
    730854  } 
    731855} 

The Sensio Labs Network

Since 1998, Sensio Labs has been promoting the Open-Source software movement by providing quality web application development, training, consulting.
Sensio Labs also supports several large Open-Source projects.