home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / PEAR / RunTest.php < prev    next >
Encoding:
PHP Script  |  2005-12-02  |  13.6 KB  |  390 lines

  1. <?php
  2. /**
  3.  * PEAR_RunTest
  4.  *
  5.  * PHP versions 4 and 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @category   pear
  14.  * @package    PEAR
  15.  * @author     Tomas V.V.Cox <cox@idecnet.com>
  16.  * @author     Greg Beaver <cellog@php.net>
  17.  * @copyright  1997-2005 The PHP Group
  18.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  19.  * @version    CVS: $Id: RunTest.php,v 1.15 2005/09/13 15:20:42 cellog Exp $
  20.  * @link       http://pear.php.net/package/PEAR
  21.  * @since      File available since Release 1.3.3
  22.  */
  23.  
  24. /**
  25.  * for error handling
  26.  */
  27. require_once 'PEAR.php';
  28. require_once 'PEAR/Config.php';
  29.  
  30. define('DETAILED', 1);
  31. putenv("PHP_PEAR_RUNTESTS=1");
  32.  
  33. /**
  34.  * Simplified version of PHP's test suite
  35.  *
  36.  * Try it with:
  37.  *
  38.  * $ php -r 'include "../PEAR/RunTest.php"; $t=new PEAR_RunTest; $o=$t->run("./pear_system.phpt");print_r($o);'
  39.  *
  40.  *
  41.  * @category   pear
  42.  * @package    PEAR
  43.  * @author     Tomas V.V.Cox <cox@idecnet.com>
  44.  * @author     Greg Beaver <cellog@php.net>
  45.  * @copyright  1997-2005 The PHP Group
  46.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  47.  * @version    Release: 1.4.5
  48.  * @link       http://pear.php.net/package/PEAR
  49.  * @since      Class available since Release 1.3.3
  50.  */
  51. class PEAR_RunTest
  52. {
  53.     var $_logger;
  54.     var $_options;
  55.  
  56.     /**
  57.      * An object that supports the PEAR_Common->log() signature, or null
  58.      * @param PEAR_Common|null
  59.      */
  60.     function PEAR_RunTest($logger = null, $options = array())
  61.     {
  62.         if (is_null($logger)) {
  63.             require_once 'PEAR/Common.php';
  64.             $logger = new PEAR_Common;
  65.         }
  66.         $this->_logger = $logger;
  67.         $this->_options = $options;
  68.     }
  69.  
  70.     //
  71.     //  Run an individual test case.
  72.     //
  73.  
  74.     function run($file, $ini_settings = '')
  75.     {
  76.         $cwd = getcwd();
  77.         $conf = &PEAR_Config::singleton();
  78.         $php = $conf->get('php_bin');
  79.         //var_dump($php);exit;
  80.         global $log_format, $info_params, $ini_overwrites;
  81.  
  82.         $info_params = '';
  83.         $log_format = 'LEOD';
  84.  
  85.         // Load the sections of the test file.
  86.         $section_text = array(
  87.             'TEST'    => '(unnamed test)',
  88.             'SKIPIF'  => '',
  89.             'GET'     => '',
  90.             'ARGS'    => '',
  91.         );
  92.  
  93.         $file = realpath($file);
  94.         if (!is_file($file) || !$fp = fopen($file, "r")) {
  95.             return PEAR::raiseError("Cannot open test file: $file");
  96.         }
  97.  
  98.         $section = '';
  99.         while (!feof($fp)) {
  100.             $line = fgets($fp);
  101.  
  102.             // Match the beginning of a section.
  103.             if (ereg('^--([A-Z]+)--',$line,$r)) {
  104.                 $section = $r[1];
  105.                 $section_text[$section] = '';
  106.                 continue;
  107.             } elseif (empty($section)) {
  108.                 fclose($fp);
  109.                 return PEAR::raiseError("Invalid sections formats in test file: $file");
  110.             }
  111.  
  112.             // Add to the section text.
  113.             $section_text[$section] .= $line;
  114.         }
  115.         fclose($fp);
  116.  
  117.         $shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file);
  118.         if (!isset($this->_options['simple'])) {
  119.             $tested = trim($section_text['TEST']) . "[$shortname]";
  120.         } else {
  121.             $tested = trim($section_text['TEST']) . ' ';
  122.         }
  123.  
  124.         $tmp = realpath(dirname($file));
  125.         $tmp_skipif = $tmp . uniqid('/phpt.');
  126.         $tmp_file   = ereg_replace('\.phpt$','.php',$file);
  127.         $tmp_post   = $tmp . uniqid('/phpt.');
  128.  
  129.         @unlink($tmp_skipif);
  130.         @unlink($tmp_file);
  131.         @unlink($tmp_post);
  132.  
  133.         // unlink old test results
  134.         @unlink(ereg_replace('\.phpt$','.diff',$file));
  135.         @unlink(ereg_replace('\.phpt$','.log',$file));
  136.         @unlink(ereg_replace('\.phpt$','.exp',$file));
  137.         @unlink(ereg_replace('\.phpt$','.out',$file));
  138.  
  139.         // Check if test should be skipped.
  140.         $info = '';
  141.         $warn = false;
  142.         if (array_key_exists('SKIPIF', $section_text)) {
  143.             if (trim($section_text['SKIPIF'])) {
  144.                 $this->save_text($tmp_skipif, $section_text['SKIPIF']);
  145.                 //$extra = substr(PHP_OS, 0, 3) !== "WIN" ?
  146.                 //    "unset REQUEST_METHOD;": "";
  147.  
  148.                 //$output = `$extra $php $info_params -f $tmp_skipif`;
  149.                 $output = `$php $info_params -f $tmp_skipif`;
  150.                 unlink($tmp_skipif);
  151.                 if (eregi("^skip", trim($output))) {
  152.                     $skipreason = "SKIP $tested";
  153.                     $reason = (eregi("^skip[[:space:]]*(.+)\$", trim($output))) ? eregi_replace("^skip[[:space:]]*(.+)\$", "\\1", trim($output)) : FALSE;
  154.                     if ($reason) {
  155.                         $skipreason .= " (reason: $reason)";
  156.                     }
  157.                     if (!isset($this->_options['quiet'])) {
  158.                         $this->_logger->log(0, $skipreason);
  159.                     }
  160.                     if (isset($old_php)) {
  161.                         $php = $old_php;
  162.                     }
  163.                     return 'SKIPPED';
  164.                 }
  165.                 if (eregi("^info", trim($output))) {
  166.                     $reason = (ereg("^info[[:space:]]*(.+)\$", trim($output))) ? ereg_replace("^info[[:space:]]*(.+)\$", "\\1", trim($output)) : FALSE;
  167.                     if ($reason) {
  168.                         $info = " (info: $reason)";
  169.                     }
  170.                 }
  171.                 if (eregi("^warn", trim($output))) {
  172.                     $reason = (ereg("^warn[[:space:]]*(.+)\$", trim($output))) ? ereg_replace("^warn[[:space:]]*(.+)\$", "\\1", trim($output)) : FALSE;
  173.                     if ($reason) {
  174.                         $warn = true; /* only if there is a reason */
  175.                         $info = " (warn: $reason)";
  176.                     }
  177.                 }
  178.             }
  179.         }
  180.  
  181.         // We've satisfied the preconditions - run the test!
  182.         $this->save_text($tmp_file,$section_text['FILE']);
  183.  
  184.         $args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : '';
  185.  
  186.         $cmd = "$php$ini_settings -f $tmp_file$args 2>&1";
  187.         if (isset($this->_logger)) {
  188.             $this->_logger->log(2, 'Running command "' . $cmd . '"');
  189.         }
  190.  
  191.         $savedir = getcwd(); // in case the test moves us around
  192.         if (isset($section_text['RETURNS'])) {
  193.             ob_start();
  194.             system($cmd, $return_value);
  195.             $out = ob_get_contents();
  196.             ob_end_clean();
  197.             @unlink($tmp_post);
  198.             $section_text['RETURNS'] = (int) trim($section_text['RETURNS']);
  199.             $returnfail = ($return_value != $section_text['RETURNS']);
  200.         } else {
  201.             $out = `$cmd`;
  202.             $returnfail = false;
  203.         }
  204.         chdir($savedir);
  205.         // Does the output match what is expected?
  206.         $output = trim($out);
  207.         $output = preg_replace('/\r\n/', "\n", $output);
  208.  
  209.         if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
  210.             if (isset($section_text['EXPECTF'])) {
  211.                 $wanted = trim($section_text['EXPECTF']);
  212.             } else {
  213.                 $wanted = trim($section_text['EXPECTREGEX']);
  214.             }
  215.             $wanted_re = preg_replace('/\r\n/',"\n",$wanted);
  216.             if (isset($section_text['EXPECTF'])) {
  217.                 $wanted_re = preg_quote($wanted_re, '/');
  218.                 // Stick to basics
  219.                 $wanted_re = str_replace("%s", ".+?", $wanted_re); //not greedy
  220.                 $wanted_re = str_replace("%i", "[+\-]?[0-9]+", $wanted_re);
  221.                 $wanted_re = str_replace("%d", "[0-9]+", $wanted_re);
  222.                 $wanted_re = str_replace("%x", "[0-9a-fA-F]+", $wanted_re);
  223.                 $wanted_re = str_replace("%f", "[+\-]?\.?[0-9]+\.?[0-9]*(E-?[0-9]+)?", $wanted_re);
  224.                 $wanted_re = str_replace("%c", ".", $wanted_re);
  225.                 // %f allows two points "-.0.0" but that is the best *simple* expression
  226.             }
  227.     /* DEBUG YOUR REGEX HERE
  228.             var_dump($wanted_re);
  229.             print(str_repeat('=', 80) . "\n");
  230.             var_dump($output);
  231.     */
  232.             if (!$returnfail && preg_match("/^$wanted_re\$/s", $output)) {
  233.                 @unlink($tmp_file);
  234.                 if (!isset($this->_options['quiet'])) {
  235.                     $this->_logger->log(0, "PASS $tested$info");
  236.                 }
  237.                 if (isset($old_php)) {
  238.                     $php = $old_php;
  239.                 }
  240.                 return 'PASSED';
  241.             }
  242.  
  243.         } else {
  244.             $wanted = trim($section_text['EXPECT']);
  245.             $wanted = preg_replace('/\r\n/',"\n",$wanted);
  246.         // compare and leave on success
  247.             $ok = (0 == strcmp($output,$wanted));
  248.             if (!$returnfail && $ok) {
  249.                 @unlink($tmp_file);
  250.                 if (!isset($this->_options['quiet'])) {
  251.                     $this->_logger->log(0, "PASS $tested$info");
  252.                 }
  253.                 if (isset($old_php)) {
  254.                     $php = $old_php;
  255.                 }
  256.                 return 'PASSED';
  257.             }
  258.         }
  259.  
  260.         // Test failed so we need to report details.
  261.         if ($warn) {
  262.             $this->_logger->log(0, "WARN $tested$info");
  263.         } else {
  264.             $this->_logger->log(0, "FAIL $tested$info");
  265.         }
  266.  
  267.         if (isset($section_text['RETURNS'])) {
  268.             $GLOBALS['__PHP_FAILED_TESTS__'][] = array(
  269.                             'name' => $file,
  270.                             'test_name' => $tested,
  271.                             'output' => ereg_replace('\.phpt$','.log', $file),
  272.                             'diff'   => ereg_replace('\.phpt$','.diff', $file),
  273.                             'info'   => $info,
  274.                             'return' => $return_value
  275.                             );
  276.         } else {
  277.             $GLOBALS['__PHP_FAILED_TESTS__'][] = array(
  278.                             'name' => $file,
  279.                             'test_name' => $tested,
  280.                             'output' => ereg_replace('\.phpt$','.log', $file),
  281.                             'diff'   => ereg_replace('\.phpt$','.diff', $file),
  282.                             'info'   => $info,
  283.                             );
  284.         }
  285.  
  286.         // write .exp
  287.         if (strpos($log_format,'E') !== FALSE) {
  288.             $logname = ereg_replace('\.phpt$','.exp',$file);
  289.             if (!$log = fopen($logname,'w')) {
  290.                 return PEAR::raiseError("Cannot create test log - $logname");
  291.             }
  292.             fwrite($log,$wanted);
  293.             fclose($log);
  294.         }
  295.  
  296.         // write .out
  297.         if (strpos($log_format,'O') !== FALSE) {
  298.             $logname = ereg_replace('\.phpt$','.out',$file);
  299.             if (!$log = fopen($logname,'w')) {
  300.                 return PEAR::raiseError("Cannot create test log - $logname");
  301.             }
  302.             fwrite($log,$output);
  303.             fclose($log);
  304.         }
  305.  
  306.         // write .diff
  307.         if (strpos($log_format,'D') !== FALSE) {
  308.             $logname = ereg_replace('\.phpt$','.diff',$file);
  309.             if (!$log = fopen($logname,'w')) {
  310.                 return PEAR::raiseError("Cannot create test log - $logname");
  311.             }
  312.             fwrite($log, $this->generate_diff($wanted, $output,
  313.                 isset($section_text['RETURNS']) ? array(trim($section_text['RETURNS']),
  314.                     $return_value) : null));
  315.             fclose($log);
  316.         }
  317.  
  318.         // write .log
  319.         if (strpos($log_format,'L') !== FALSE) {
  320.             $logname = ereg_replace('\.phpt$','.log',$file);
  321.             if (!$log = fopen($logname,'w')) {
  322.                 return PEAR::raiseError("Cannot create test log - $logname");
  323.             }
  324.             fwrite($log,"
  325. ---- EXPECTED OUTPUT
  326. $wanted
  327. ---- ACTUAL OUTPUT
  328. $output
  329. ---- FAILED
  330. ");
  331.             if ($returnfail) {
  332.                 fwrite($log,"
  333. ---- EXPECTED RETURN
  334. $section_text[RETURNS]
  335. ---- ACTUAL RETURN
  336. $return_value
  337. ");
  338.             }
  339.             fclose($log);
  340.             //error_report($file,$logname,$tested);
  341.         }
  342.  
  343.         if (isset($old_php)) {
  344.             $php = $old_php;
  345.         }
  346.  
  347.         return $warn ? 'WARNED' : 'FAILED';
  348.     }
  349.  
  350.     function generate_diff($wanted, $output, $return_value)
  351.     {
  352.         $w = explode("\n", $wanted);
  353.         $o = explode("\n", $output);
  354.         $w1 = array_diff_assoc($w,$o);
  355.         $o1 = array_diff_assoc($o,$w);
  356.         $w2 = array();
  357.         $o2 = array();
  358.         foreach($w1 as $idx => $val) $w2[sprintf("%03d<",$idx)] = sprintf("%03d- ", $idx+1).$val;
  359.         foreach($o1 as $idx => $val) $o2[sprintf("%03d>",$idx)] = sprintf("%03d+ ", $idx+1).$val;
  360.         $diff = array_merge($w2, $o2);
  361.         ksort($diff);
  362.         if ($return_value) {
  363.             $extra = "##EXPECTED: $return_value[0]\r\n##RETURNED: $return_value[1]";
  364.         } else {
  365.             $extra = '';
  366.         }
  367.         return implode("\r\n", $diff) . $extra;
  368.     }
  369.  
  370.     //
  371.     //  Write the given text to a temporary file, and return the filename.
  372.     //
  373.  
  374.     function save_text($filename, $text)
  375.     {
  376.         if (!$fp = fopen($filename, 'w')) {
  377.             return PEAR::raiseError("Cannot open file '" . $filename . "' (save_text)");
  378.         }
  379.         fwrite($fp,$text);
  380.         fclose($fp);
  381.     if (1 < DETAILED) echo "
  382. FILE $filename {{{
  383. $text
  384. }}}
  385. ";
  386.     }
  387.  
  388. }
  389. ?>
  390.