<?php
/**
 * PHPUnit
 *
 * Copyright (c) 2002-2008, Sebastian Bergmann <sb@sebastian-bergmann.de>.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *   * Neither the name of Sebastian Bergmann nor the names of his
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @category   Testing
 * @package    PHPUnit
 * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
 * @copyright  2002-2008 Sebastian Bergmann <sb@sebastian-bergmann.de>
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
 * @version    SVN: $Id: CodeCoverage.php 1985 2007-12-26 18:11:55Z sb $
 * @link       http://www.phpunit.de/
 * @since      File available since Release 3.1.0
 */

require_once 'PHPUnit/Util/Filter.php';

PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');

/**
 * Code Coverage helpers.
 *
 * @category   Testing
 * @package    PHPUnit
 * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
 * @copyright  2002-2008 Sebastian Bergmann <sb@sebastian-bergmann.de>
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
 * @version    Release: 3.2.9
 * @link       http://www.phpunit.de/
 * @since      Class available since Release 3.1.0
 * @abstract
 */
abstract class PHPUnit_Util_CodeCoverage {
  protected static $lineToTestMap = array();
  protected static $summary = array();

  /**
   * Returns the names of the covered files.
   *
   * @param  array $data
   * @return array
   * @access public
   * @static
   */
  public static function getCoveredFiles(array &$data) {
    $files = array();
    
    foreach ($data as $test) {
      $_files = array_keys($test['files']);
      
      foreach ($_files as $file) {
        if (self::isFile($file) && ! in_array($file, $files)) {
          $files[] = $file;
        }
      }
    }
    
    return $files;
  }

  /**
   * Returns the tests that cover a given line.
   *
   * @param  array   $data
   * @param  string  $file
   * @param  string  $line
   * @param  boolean $clear
   * @return array
   * @access public
   * @static
   */
  public static function getCoveringTests(array &$data, $file, $line, $clear = FALSE) {
    if (empty(self::$lineToTestMap) || $clear) {
      foreach ($data as $test) {
        foreach ($test['files'] as $_file => $lines) {
          foreach ($lines as $_line => $flag) {
            if ($flag > 0) {
              if (! isset(self::$lineToTestMap[$_file][$_line])) {
                self::$lineToTestMap[$_file][$_line] = array(
                    $test['test']);
              } else {
                self::$lineToTestMap[$_file][$_line][] = $test['test'];
              }
            }
          }
        }
      }
    }
    
    if (isset(self::$lineToTestMap[$file][$line])) {
      return self::$lineToTestMap[$file][$line];
    } else {
      return FALSE;
    }
  }

  /**
   * Returns summarized code coverage data.
   *
   * Format of the result array:
   *
   * <code>
   * array(
   *   "/tested/code.php" => array(
   *     linenumber => number of tests that executed the line
   *   )
   * )
   * </code>
   *
   * @param  array $data
   * @param  boolean $clear
   * @return array
   * @access public
   * @static
   */
  public static function getSummary(array &$data, $clear = FALSE) {
    if (empty(self::$summary) || $clear) {
      $isFileCache = array();
      
      foreach ($data as $test) {
        foreach ($test['files'] as $file => $lines) {
          if (! isset($isFileCache[$file])) {
            $isFileCache[$file] = self::isFile($file);
          }
          
          if (! $isFileCache[$file]) {
            continue;
          }
          
          $fileSummary = &self::$summary[$file];
          
          foreach ($lines as $line => $flag) {
            // +1: Line is executable and was executed.
            if ($flag == 1) {
              if (isset($fileSummary[$line][0])) {
                $fileSummary[$line][] = $test['test'];
              } else {
                $fileSummary[$line] = array(
                    $test['test']);
              }
            } 

            // -1: Line is executable and was not executed.
            // -2: Line is dead code.
            else if (! isset($fileSummary[$line])) {
              $fileSummary[$line] = $flag;
            }
          }
          
          unset($fileSummary);
        }
      }
    }
    
    return self::$summary;
  }

  /**
   * Returns the coverage statistics for a section of a file.
   *
   * @param  array   $data
   * @param  string  $filename
   * @param  integer $startLine
   * @param  integer $endLine
   * @return array
   * @access public
   * @static
   * @since  Method available since Release 3.2.0
   */
  public static function getStatistics(array &$data, $filename, $startLine = 1, $endLine = FALSE) {
    $coverage = 0;
    $locExecutable = 0;
    $locExecuted = 0;
    
    if (isset($data[$filename])) {
      if ($endLine == FALSE) {
        $endLine = count(file($filename));
      }
      
      foreach ($data[$filename] as $line => $_data) {
        if ($line >= $startLine && $line <= $endLine) {
          if (is_array($_data)) {
            $locExecutable ++;
            $locExecuted ++;
          } 

          else if ($_data == - 1) {
            $locExecutable ++;
          }
        }
      }
      
      if ($locExecutable > 0) {
        $coverage = ($locExecuted / $locExecutable) * 100;
      }
    }
    
    return array('coverage' => $coverage, 'loc' => $endLine - $startLine + 1, 
        'locExecutable' => $locExecutable, 'locExecuted' => $locExecuted);
  }

  /**
   * @param  string $file
   * @return boolean
   * @access protected
   * @static
   */
  protected static function isFile($file) {
    if (strpos($file, 'eval()\'d code') || strpos($file, 'runtime-created function') || strpos($file, 'assert code')) {
      return FALSE;
    }
    
    return TRUE;
  }
}
?>
