00001 <?php
00002
00003
00009 class SimpleErrorTrappingInvoker extends SimpleInvokerDecorator {
00014 function SimpleErrorTrappingInvoker(&$invoker) {
00015 $this->SimpleInvokerDecorator($invoker);
00016 }
00017
00025 function invoke($method) {
00026 $queue = &$this->_createErrorQueue();
00027 set_error_handler('SimpleTestErrorHandler');
00028 parent::invoke($method);
00029 restore_error_handler();
00030 $queue->tally();
00031 }
00032
00038 function & _createErrorQueue() {
00039 $context = &SimpleTest::getContext();
00040 $test = &$this->getTestCase();
00041 $queue = &$context->get('SimpleErrorQueue');
00042 $queue->setTestCase($test);
00043 return $queue;
00044 }
00045 }
00046
00053 class SimpleErrorQueue {
00054 var $_queue;
00055 var $_expectation_queue;
00056 var $_test;
00057 var $_using_expect_style = false;
00058
00062 function SimpleErrorQueue() {
00063 $this->clear();
00064 }
00065
00070 function clear() {
00071 $this->_queue = array();
00072 $this->_expectation_queue = array();
00073 }
00074
00080 function setTestCase(&$test) {
00081 $this->_test = &$test;
00082 }
00083
00093 function expectError($expected, $message) {
00094 $this->_using_expect_style = true;
00095 array_push($this->_expectation_queue, array($expected, $message));
00096 }
00097
00106 function add($severity, $content, $filename, $line) {
00107 $content = str_replace('%', '%%', $content);
00108 if ($this->_using_expect_style) {
00109 $this->_testLatestError($severity, $content, $filename, $line);
00110 }
00111 else {
00112 array_push($this->_queue, array($severity, $content, $filename, $line));
00113 }
00114 }
00115
00121 function tally() {
00122 while (list($severity, $message, $file, $line) = $this->extract()) {
00123 $severity = $this->getSeverityAsString($severity);
00124 $this->_test->error($severity, $message, $file, $line);
00125 }
00126 while (list($expected, $message) = $this->_extractExpectation()) {
00127 $this->_test->assert($expected, false, "%s -> Expected error not caught");
00128 }
00129 }
00130
00140 function _testLatestError($severity, $content, $filename, $line) {
00141 if ($expectation = $this->_extractExpectation()) {
00142 list($expected, $message) = $expectation;
00143 $this->_test->assert($expected, $content, sprintf(
00144 $message,
00145 "%s -> PHP error [$content] severity [".
00146 $this->getSeverityAsString($severity) .
00147 "] in [$filename] line [$line]"));
00148 }
00149 else {
00150 $this->_test->error($severity, $content, $filename, $line);
00151 }
00152 }
00153
00163 function extract() {
00164 if (count($this->_queue)) {
00165 return array_shift($this->_queue);
00166 }
00167 return false;
00168 }
00169
00175 function _extractExpectation() {
00176 if (count($this->_expectation_queue)) {
00177 return array_shift($this->_expectation_queue);
00178 }
00179 return false;
00180 }
00181
00190 function getSeverityAsString($severity) {
00191 static $map = array(
00192 E_STRICT => 'E_STRICT',
00193 E_ERROR => 'E_ERROR',
00194 E_WARNING => 'E_WARNING',
00195 E_PARSE => 'E_PARSE',
00196 E_NOTICE => 'E_NOTICE',
00197 E_CORE_ERROR => 'E_CORE_ERROR',
00198 E_CORE_WARNING => 'E_CORE_WARNING',
00199 E_COMPILE_ERROR => 'E_COMPILE_ERROR',
00200 E_COMPILE_WARNING => 'E_COMPILE_WARNING',
00201 E_USER_ERROR => 'E_USER_ERROR',
00202 E_USER_WARNING => 'E_USER_WARNING',
00203 E_USER_NOTICE => 'E_USER_NOTICE'
00204 );
00205 if (version_compare(phpversion(), '5.2.0', '>=')) {
00206 $map[E_RECOVERABLE_ERROR] = 'E_RECOVERABLE_ERROR';
00207 }
00208 return $map[$severity];
00209 }
00210 }
00211
00224 function SimpleTestErrorHandler($severity, $message, $filename = null, $line = null, $super_globals = null, $mask = null) {
00225 $severity = $severity & error_reporting();
00226 if ($severity) {
00227 restore_error_handler();
00228 if (ini_get('log_errors')) {
00229 $label = SimpleErrorQueue::getSeverityAsString($severity);
00230 error_log("$label: $message in $filename on line $line");
00231 }
00232 $context = &SimpleTest::getContext();
00233 $queue = &$context->get('SimpleErrorQueue');
00234 $queue->add($severity, $message, $filename, $line);
00235 set_error_handler('SimpleTestErrorHandler');
00236 }
00237 return true;
00238 }
00239
00240