cvs: php-gcov-web /cron cron.sh find_tested.php /www config.php tested_functions.php viewer.php

From: Date: Wed, 14 Jan 2009 20:07:12 +0000
Subject: cvs: php-gcov-web /cron cron.sh find_tested.php /www config.php tested_functions.php viewer.php
Groups: php.webmaster 
Request: Send a blank email to php-webmaster+get-3563@lists.php.net to get a copy of this message
nlopess Wed Jan 14 20:07:12 2009 UTC Added files: /php-gcov-web/cron find_tested.php /php-gcov-web/www tested_functions.php Modified files: /php-gcov-web/cron cron.sh /php-gcov-web/www config.php viewer.php Log: add list of tested functions. patch by Steve Seear

http://cvs.php.net/viewvc.cgi/php-gcov-web/cron/cron.sh?r1=1.10&r2=1.11&diff_format=u Index: php-gcov-web/cron/cron.sh diff -u php-gcov-web/cron/cron.sh:1.10 php-gcov-web/cron/cron.sh:1.11 --- php-gcov-web/cron/cron.sh:1.10 Wed Jun 11 17:58:20 2008 +++ php-gcov-web/cron/cron.sh Wed Jan 14 20:07:11 2009 @@ -17,7 +17,7 @@ # | Nuno Lopes <nlopess@php.net> | # +----------------------------------------------------------------------+ -# $Id: cron.sh,v 1.10 2008/06/11 17:58:20 nlopess Exp $ +# $Id: cron.sh,v 1.11 2009/01/14 20:07:11 nlopess Exp $ source ./config.sh export LC_ALL=C @@ -155,6 +155,11 @@ php ${WORKDIR}/cron.php ${TMPDIR} ${OUTDIR} ${PHPSRC} ${MAKESTATUS} ${PHPTAG} ${BUILD_TIME} + # run find_tested script from source dir to give relative paths in output + cd ${PHPSRC} + php ${WORKDIR}/find_tested.php . > "${TMPDIR}/tested_functions.${PHPTAG}.tmp" + mv "${TMPDIR}/tested_functions.${PHPTAG}.tmp" ${OUTDIR}/tested_functions.inc + rm -f "$PIDFILE" fi # End verify build PHP version http://cvs.php.net/viewvc.cgi/php-gcov-web/www/config.php?r1=1.3&r2=1.4&diff_format=u Index: php-gcov-web/www/config.php diff -u php-gcov-web/www/config.php:1.3 php-gcov-web/www/config.php:1.4 --- php-gcov-web/www/config.php:1.3 Thu Dec 21 18:58:49 2006 +++ php-gcov-web/www/config.php Wed Jan 14 20:07:12 2009 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: config.php,v 1.3 2006/12/21 18:58:49 nlopess Exp $ */ +/* $Id: config.php,v 1.4 2009/01/14 20:07:12 nlopess Exp $ */ // File: Core Site Configuration File // Desc: contains core site settings, this file is essential and always included by the API. @@ -42,9 +42,10 @@ 'compile-results' => 'compile_results', 'graphs' => 'graph', 'parameter-parsing' => 'params', - 'skipped-tests' => 'skip', 'test-failures' => 'tests', 'valgrind' => 'valgrind', + 'skipped-tests' => 'skip', + 'tested-functions' => 'tested_functions', 'system' => 'system', ); http://cvs.php.net/viewvc.cgi/php-gcov-web/www/viewer.php?r1=1.6&r2=1.7&diff_format=u Index: php-gcov-web/www/viewer.php diff -u php-gcov-web/www/viewer.php:1.6 php-gcov-web/www/viewer.php:1.7 --- php-gcov-web/www/viewer.php:1.6 Fri Dec 29 23:01:04 2006 +++ php-gcov-web/www/viewer.php Wed Jan 14 20:07:12 2009 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: viewer.php,v 1.6 2006/12/29 23:01:04 nlopess Exp $ */ +/* $Id: viewer.php,v 1.7 2009/01/14 20:07:12 nlopess Exp $ */ // Name: GCOV Viewer page // Desc: page for view PHP version information such as code coverage @@ -88,6 +88,11 @@ 'pagetitle' => 'PHP: System Info', 'pagehead' => 'System Info' ), + 'tested_functions' => + array( + 'pagetitle' => 'PHP: Tested Funtions for '.$version, + 'pagehead' => 'Tested Functions' + ), 'tests' => array( 'pagetitle' => 'PHP: Test Failures for '.$version, http://cvs.php.net/viewvc.cgi/php-gcov-web/cron/find_tested.php?view=markup&rev=1.1 Index: php-gcov-web/cron/find_tested.php +++ php-gcov-web/cron/find_tested.php <?php /* +----------------------------------------------------------------------+ | PHP QA GCOV Website | +----------------------------------------------------------------------+ | Copyright (c) 2008-2009 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Steve Seear <stevseea@php.net> | +----------------------------------------------------------------------+ */ /* $Id: find_tested.php,v 1.1 2009/01/14 20:07:11 nlopess Exp $ */ $usage = <<<USAGE Usage: php find_tested.php [path_to_test_files] ([extension]) Outputs test coverage information for functions and methods in csv format. Supplying an optional extension name outputs only information for functions and methods from that extension. Output format: Extension, Class Name, Method/Function Name, Test Status, Test Files A test status of "verify" for a method means that there is at least one other method of the same name, so test coverage must be verified manually. USAGE; /* method record fields */ define("CLASS_NAME", "CLASS_NAME"); define("METHOD_NAME", "METHOD_NAME"); define("EXTENSION_NAME", "EXTENSION_NAME"); define("IS_DUPLICATE", "IS_DUPLICATE"); define("IS_TESTED", "IS_TESTED"); define("TESTS", "TESTS"); // process command line args $num_params = $argc; if ($num_params < 2 || $num_params > 3) { die($usage); } $extension_test_path = $argv[1]; if ($num_params == 3) { $extension_name = $argv[2]; // check extension exists $extensions = get_loaded_extensions(); if (!in_array($extension_name, $extensions)) { echo "Error: extension $extension_name is not loaded. Loaded extensions:\n"; foreach($extensions as $extension) { echo "$extension\n"; } die(); } } else { $extension_name = false; } $method_info = populate_method_info(); if ($extension_name != false) { // get only the methods from the extension we are querying $extension_method_info = array(); foreach($method_info as $method_record) { if (strcasecmp($extension_name, $method_record[EXTENSION_NAME]) == 0) { $extension_method_info[] = $method_record; } } } else { $extension_method_info = $method_info; } get_phpt_files($extension_test_path, $count, $phpt_files); $extension_method_info = mark_methods_as_tested($extension_method_info, $phpt_files); foreach($extension_method_info as $record) { echo $record[EXTENSION_NAME] . ","; echo $record[CLASS_NAME] . ","; echo $record[METHOD_NAME] . ","; echo $record[IS_TESTED] . ","; echo $record[TESTS] . "\n"; } /** * Marks the "tested" status of methods in $method_info according * to whether they are tested in $phpt_files */ function mark_methods_as_tested($method_info, $phpt_files) { foreach($phpt_files as $phpt_file) { $tested_functions = extract_tests($phpt_file); foreach($tested_functions as $tested_function) { // go through method info array marking this funtion as tested foreach($method_info as &$current_method_record) { if (strcasecmp($tested_function, $current_method_record[METHOD_NAME]) == 0) { // matched the method name if ($current_method_record[IS_DUPLICATE] == true) { // we cannot be sure which class this method corresponds to, // so mark method as needing to be verified $current_method_record[IS_TESTED] = "verify"; } else { $current_method_record[IS_TESTED] = "yes"; } $current_method_record[TESTS] .= $phpt_file . "; "; } } } } return $method_info; } /** * returns an array containing a record for each defined method. */ function populate_method_info() { $method_info = array(); // get functions $all_functions = get_defined_functions(); $internal_functions = $all_functions["internal"]; foreach ($internal_functions as $function) { // populate new method record $function_record = array(); $function_record[CLASS_NAME] = "Function"; $function_record[METHOD_NAME] = $function; $function_record[IS_TESTED] = "no"; $function_record[TESTS] = ""; $function_record[IS_DUPLICATE] = false; // record the extension that the function belongs to $reflectionFunction = new ReflectionFunction($function); $extension = $reflectionFunction->getExtension(); if ($extension != null) { $function_record[EXTENSION_NAME] = $extension->getName(); } else { $function_record[EXTENSION_NAME] = ""; } // insert new method record into info array $method_info[] = $function_record; } // get methods $all_classes = get_declared_classes(); foreach ($all_classes as $class) { $reflectionClass = new ReflectionClass($class); $methods = $reflectionClass->getMethods(); foreach ($methods as $method) { // populate new method record $new_method_record = array(); $new_method_record[CLASS_NAME] = $reflectionClass->getName(); $new_method_record[METHOD_NAME] = $method->getName(); $new_method_record[IS_TESTED] = "no"; $new_method_record[TESTS] = ""; $extension = $reflectionClass->getExtension(); if ($extension != null) { $new_method_record[EXTENSION_NAME] = $extension->getName(); } else { $new_method_record[EXTENSION_NAME] = ""; } // check for duplicate method names $new_method_record[IS_DUPLICATE] = false; foreach ($method_info as &$current_record) { if (strcmp($current_record[METHOD_NAME], $new_method_record[METHOD_NAME]) == 0) { $new_method_record[IS_DUPLICATE] = true; $current_record[IS_DUPLICATE] = true; } } // insert new method record into info array $method_info[] = $new_method_record; } } return $method_info; } function get_phpt_files($dir, &$phpt_file_count, &$all_phpt) { $thisdir = dir($dir.'/'); //include the trailing slash while(($file = $thisdir->read()) !== false) { if ($file != '.' && $file != '..') { $path = $thisdir->path.$file; if(is_dir($path) == true) { get_phpt_files($path , $phpt_file_count , $all_phpt); } else { if (preg_match("/\w+\.phpt$/", $file)) { $all_phpt[$phpt_file_count] = $path; $phpt_file_count++; } } } } } function extract_tests($file) { $code = file_get_contents($file); if (!preg_match('/--FILE--\s*(.*)\s*--(EXPECTF|EXPECTREGEX|EXPECT)?--/is', $code, $r)) { // print "Unable to get code in ".$file."\n"; return array(); } $tokens = token_get_all($r[1]); $functions = array_filter($tokens, 'filter_functions'); $functions = array_map( 'map_token_value',$functions); $functions = array_unique($functions); return $functions; } function filter_functions($x) { return $x[0] == 307; } function map_token_value($x) { return $x[1]; } http://cvs.php.net/viewvc.cgi/php-gcov-web/www/tested_functions.php?view=markup&rev=1.1 Index: php-gcov-web/www/tested_functions.php +++ php-gcov-web/www/tested_functions.php <?php /* +----------------------------------------------------------------------+ | PHP QA GCOV Website | +----------------------------------------------------------------------+ | Copyright (c) 2008-2009 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Steve Seear <stevseea@php.net> | +----------------------------------------------------------------------+ */ /* $Id: tested_functions.php,v 1.1 2009/01/14 20:07:12 nlopess Exp $ */ if (!defined('IN_GCOV_CODE')) exit; $inputfile = "./$version/tested_functions.inc"; $fd = @fopen($inputfile, 'r'); if (!$fd) { $content = "<p>This data isn't available at this time.</p>\n"; return; } $content = <<< HTML <script type="text/javascript"> function showHide(id){ var e = document.getElementById(id); if (e.style.display == "") { e.style.display = "none"; } else { e.style.display = ""; } } </script> <p>This table lists core PHP functions and methods and specifies whether or not they are called from a PHPT test. A "yes" in this table for a particular method is not an indication of good test coverage - it just means that that method is called from at least one PHPT test.</p> <p>The analysis used to generate this table does not differentiate between methods of the same name belonging to different classes. In cases where such a method call is detected, "verify" is listed in the Tested column, along with the list of test files containing calls to a method of that name.</p> HTML; // fields in the csv file define("EXTENSION", 0); define("CLASS_NAME", 1); define("METHOD_NAME", 2); define("TESTED", 3); define("TESTS", 4); // table header $content .= "<table border=\"0\">\n"; $content .= "<th align=\"left\">Extension</th>\n"; $content .= "<th align=\"left\">Class</th>\n"; $content .= "<th align=\"left\">Method</th>\n"; $content .= "<th align=\"left\">Tested</th>\n"; $content .= "<th align=\"left\">Test Files</th>\n"; $tests_id = 0; // print table rows while (true) { $line = fgetcsv($fd); if ($line === false) { break; } if (count($line) != 5) { continue; } $extension = $line[EXTENSION]; $class = $line[CLASS_NAME]; $method = $line[METHOD_NAME]; $tested = $line[TESTED]; $bgcolor = "red"; $test_files_exist = false; if ($tested === "yes") { $bgcolor = "green"; $test_files_exist = true; } else if ($tested === "no") { $bgcolor = "red"; } else if ($tested === "verify") { $bgcolor = "orange"; $test_files_exist = true; } $tests = $line[TESTS]; $content .= "<tr>"; $content .= "<td>$extension</td>"; $content .= "<td>$class</td>"; $content .= "<td>$method</td>"; $content .= "<td bgcolor='$bgcolor'>$tested</td>"; $content .= "<td>"; if ($test_files_exist) { $content .= "<a href=\"#\" onClick='showHide(\"$tests_id\"); return false;'>click to show/hide test files</a>"; $content .= "<div id='$tests_id' style='display:none'>$tests</div>"; } $content .= "</td>"; $content .= "</tr>\n"; ++$tests_id; } $content .= "</table>\n"; $content .= footer_timestamp(@filemtime($inputfile));
« previous php.webmaster (#3563) next »