|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00027 if (!defined('MOODLE_INTERNAL')) { 00028 die('Direct access to this script is forbidden.'); 00029 } 00030 00031 require_once($CFG->libdir . '/simpletestlib/reporter.php'); 00032 00040 class ExHtmlReporter extends HtmlReporter { 00041 00042 // Options set when the class is created. 00043 var $showpasses; 00044 00045 // Lang strings. Set in the constructor. 00046 var $strrunonlyfolder; 00047 var $strrunonlyfile; 00048 00049 var $strseparator; 00050 00051 var $timestart; 00052 00058 function ExHtmlReporter($showpasses) { 00059 $this->HtmlReporter(); 00060 $this->showpasses = $showpasses; 00061 00062 $this->strrunonlyfolder = $this->get_string('runonlyfolder'); 00063 $this->strrunonlyfile = $this->get_string('runonlyfile'); 00064 $this->strseparator = get_separator(); 00065 } 00066 00070 function paintPass($message) { 00071 //(Implicitly call grandparent, as parent not implemented.) 00072 parent::paintPass($message); 00073 if ($this->showpasses) { 00074 $this->_paintPassFail('pass', $message); 00075 } 00076 } 00077 00081 function paintFail($message) { 00082 // Explicitly call grandparent, not parent::paintFail. 00083 SimpleScorer::paintFail($message); 00084 $this->_paintPassFail('fail', $message, debug_backtrace()); 00085 } 00086 00090 function paintSkip($message) { 00091 // Explicitly call grandparent, not parent::paintFail. 00092 SimpleScorer::paintSkip($message); 00093 $this->_paintPassFail('skip', $message); 00094 } 00095 00099 function paintError($message) { 00100 // Explicitly call grandparent, not parent::paintError. 00101 SimpleScorer::paintError($message); 00102 $this->_paintPassFail('exception', $message); 00103 } 00104 00108 function paintException($exception) { 00109 // Explicitly call grandparent, not parent::paintException. 00110 SimpleScorer::paintException($exception); 00111 00112 if (is_a($exception, 'moodle_exception') && 00113 !get_string_manager()->string_exists($exception->errorcode, $exception->module)) { 00114 $exceptionmessage = 'Exception with missing language string {' . 00115 $exception->errorcode . '} from language file {' . $exception->module . '}'; 00116 00117 if (!empty($exception->a)) { 00118 if (is_string($exception->a)) { 00119 $data = $exception->a; 00120 } else { 00121 $data = array(); 00122 foreach ((array)$exception->a as $name => $value) { 00123 $data[] = $name . ' => [' . $value . ']'; 00124 } 00125 $data = implode(', ', $data); 00126 } 00127 $exceptionmessage .= ' with data {' . $data . '}'; 00128 } 00129 00130 } else { 00131 $exceptionmessage = $exception->getMessage(); 00132 } 00133 $message = 'Unexpected exception of type [' . get_class($exception) . 00134 '] with message ['. $exceptionmessage . 00135 '] in ['. $exception->getFile() . 00136 ' line ' . $exception->getLine() . ']'; 00137 00138 $debuginfo = null; 00139 if (!empty($exception->debuginfo)) { 00140 $debuginfo = $exception->debuginfo; 00141 } 00142 00143 $this->_paintPassFail('exception', $message, $exception->getTrace(), $debuginfo); 00144 } 00145 00149 function _paintPassFail($passorfail, $message, $stacktrace = null, $debuginfo = null) { 00150 global $FULLME, $CFG, $OUTPUT; 00151 00152 echo $OUTPUT->box_start($passorfail . ' generalbox '); 00153 00154 $url = $this->_htmlEntities($this->_stripParameterFromUrl($FULLME, 'path')); 00155 echo '<b class="', $passorfail, '">', $this->get_string($passorfail), '</b>: '; 00156 $breadcrumb = $this->getTestList(); 00157 array_shift($breadcrumb); 00158 $file = array_shift($breadcrumb); 00159 $pathbits = preg_split('/\/|\\\\/', substr($file, strlen($CFG->dirroot) + 1)); 00160 $file = array_pop($pathbits); 00161 $folder = ''; 00162 foreach ($pathbits as $pathbit) { 00163 $folder .= $pathbit . '/'; 00164 echo "<a href=\"{$url}path=$folder\" title=\"$this->strrunonlyfolder\">$pathbit</a>/"; 00165 } 00166 echo "<a href=\"{$url}path=$folder$file\" title=\"$this->strrunonlyfile\">$file</a>"; 00167 echo $this->strseparator, implode($this->strseparator, $breadcrumb); 00168 00169 echo '<br />', $this->_htmlEntities($message), "\n\n"; 00170 00171 if (!empty($debuginfo)) { 00172 print_object('Debug info:'); 00173 print_object($debuginfo); 00174 } 00175 00176 if ($stacktrace) { 00177 $dotsadded = false; 00178 $interestinglines = 0; 00179 $filteredstacktrace = array(); 00180 foreach ($stacktrace as $frame) { 00181 if (empty($frame['file']) || (strpos($frame['file'], 'simpletestlib') === false && 00182 strpos($frame['file'], 'simpletestcoveragelib') === false 00183 && strpos($frame['file'], 'tool/unittest') === false)) { 00184 $filteredstacktrace[] = $frame; 00185 $interestinglines += 1; 00186 $dotsadded = false; 00187 } else if (!$dotsadded) { 00188 $filteredstacktrace[] = array('line' => '...', 'file' => '...'); 00189 $dotsadded = true; 00190 } 00191 } 00192 if ($interestinglines > 1 || ($passorfail == 'exception' && $interestinglines > 0)) { 00193 echo '<div class="notifytiny">' . format_backtrace($filteredstacktrace) . "</div>\n\n"; 00194 } 00195 } 00196 00197 echo $OUTPUT->box_end(); 00198 flush(); 00199 } 00200 00204 function paintNotice($message) { 00205 $this->paintMessage($this->_htmlEntities($message)); 00206 } 00207 00212 function paintMessage($message) { 00213 global $OUTPUT; 00214 if ($this->showpasses) { 00215 echo $OUTPUT->box_start(); 00216 echo '<span class="notice">', $this->get_string('notice'), '</span>: '; 00217 $breadcrumb = $this->getTestList(); 00218 array_shift($breadcrumb); 00219 echo implode($this->strseparator, $breadcrumb); 00220 echo $this->strseparator, '<br />', $message, "\n"; 00221 echo $OUTPUT->box_end(); 00222 flush(); 00223 } 00224 } 00225 00229 function paintHeader($test_name) { 00230 $this->timestart = time(); 00231 // We do this the moodle way instead. 00232 } 00233 00237 function paintFooter($test_name) { 00238 $summarydata = new stdClass; 00239 $summarydata->run = $this->getTestCaseProgress(); 00240 $summarydata->total = $this->getTestCaseCount(); 00241 $summarydata->passes = $this->getPassCount(); 00242 $summarydata->fails = $this->getFailCount(); 00243 $summarydata->exceptions = $this->getExceptionCount(); 00244 00245 if ($summarydata->fails == 0 && $summarydata->exceptions == 0) { 00246 $status = "passed"; 00247 } else { 00248 $status = "failed"; 00249 } 00250 echo '<div class="unittestsummary ', $status, '">'; 00251 echo $this->get_string('summary', $summarydata); 00252 echo '</div>'; 00253 00254 echo '<div class="performanceinfo">', 00255 $this->get_string('runat', userdate($this->timestart)), ' ', 00256 $this->get_string('timetakes', format_time(time() - $this->timestart)), ' ', 00257 $this->get_string('version', SimpleTestOptions::getVersion()), 00258 '</div>'; 00259 } 00260 00276 function _stripParameterFromUrl($url, $param) { 00277 $url = preg_replace('/(\?|&)' . $param . '=[^&]*&?/', '$1', $url); 00278 if (strpos($url, '?') === false) { 00279 $url = $url . '?'; 00280 } else { 00281 $url = $url . '&'; 00282 } 00283 return $url; 00284 } 00285 00289 function get_string($identifier, $a = NULL) { 00290 return get_string($identifier, 'tool_unittest', $a); 00291 } 00292 00293 function _htmlEntities($message) { 00294 // Override subclass message that breaks UTF8. 00295 return s($message); 00296 } 00297 }