Author: ts Date: Fri Feb 15 14:05:08 2008 New Revision: 7384 Log: - Added ezcDebugStacktraceIterator interface and ezcDebugPhpStacktraceIterator.
Added: trunk/Debug/src/exceptions/ trunk/Debug/src/exceptions/exception.php (with props) trunk/Debug/src/interfaces/stacktrace_iterator.php (with props) trunk/Debug/src/stacktrace/ trunk/Debug/src/stacktrace/php_iterator.php (with props) trunk/Debug/tests/php_stacktrace_iterator_test.php (with props) Modified: trunk/Debug/design/class_diagram.png trunk/Debug/src/debug.php trunk/Debug/src/debug_autoload.php trunk/Debug/tests/suite.php Modified: trunk/Debug/design/class_diagram.png ============================================================================== Binary files - no diff available. Modified: trunk/Debug/src/debug.php ============================================================================== --- trunk/Debug/src/debug.php [iso-8859-1] (original) +++ trunk/Debug/src/debug.php [iso-8859-1] Fri Feb 15 14:05:08 2008 @@ -316,11 +316,32 @@ * @param array(string=>string) $extraInfo * @return void */ - public function log( $message, $verbosity, array $extraInfo = array() ) + public function log( $message, $verbosity, array $extraInfo = array(), $stackTrace = false ) { // Add the verbosity $extraInfo = array_merge( array( "verbosity" => $verbosity ), $extraInfo ); + if ( $this->options->stackTrace === true || $stackTrace === true ) + { + $extraInfo['stackTrace'] = $this->getStackTrace(); + } $this->log->log( $message, ezcLog::DEBUG, $extraInfo ); + } + + private function getStackTrace() + { + $stackTrace = array(); + if ( extension_loaded( 'xdebug' ) ) + { + return new ezcDebugXdebugStacktraceIterator( + xdebug_get_function_stack() + ); + } + else + { + return new ezcDebugPhpStacktraceIterator( + debug_backtrace() + ); + } } /** Modified: trunk/Debug/src/debug_autoload.php ============================================================================== --- trunk/Debug/src/debug_autoload.php [iso-8859-1] (original) +++ trunk/Debug/src/debug_autoload.php [iso-8859-1] Fri Feb 15 14:05:08 2008 @@ -10,15 +10,18 @@ */ return array( - 'ezcDebugOutputFormatter' => 'Debug/interfaces/formatter.php', - 'ezcDebug' => 'Debug/debug.php', - 'ezcDebugHtmlFormatter' => 'Debug/formatters/html_formatter.php', - 'ezcDebugMemoryWriter' => 'Debug/writers/memory_writer.php', - 'ezcDebugMessage' => 'Debug/debug_message.php', - 'ezcDebugOptions' => 'Debug/options.php', - 'ezcDebugStructure' => 'Debug/structs/debug_structure.php', - 'ezcDebugSwitchTimerStruct' => 'Debug/structs/switch_timer.php', - 'ezcDebugTimer' => 'Debug/debug_timer.php', - 'ezcDebugTimerStruct' => 'Debug/structs/timer.php', + 'ezcDebugException' => 'Debug/exceptions/exception.php', + 'ezcDebugOutputFormatter' => 'Debug/interfaces/formatter.php', + 'ezcDebug' => 'Debug/debug.php', + 'ezcDebugHtmlFormatter' => 'Debug/formatters/html_formatter.php', + 'ezcDebugMemoryWriter' => 'Debug/writers/memory_writer.php', + 'ezcDebugMessage' => 'Debug/debug_message.php', + 'ezcDebugOptions' => 'Debug/options.php', + 'ezcDebugPhpStacktraceIterator' => 'Debug/stacktrace/php_iterator.php', + 'ezcDebugStacktraceIterator' => 'Debug/interfaces/stacktrace_iterator.php', + 'ezcDebugStructure' => 'Debug/structs/debug_structure.php', + 'ezcDebugSwitchTimerStruct' => 'Debug/structs/switch_timer.php', + 'ezcDebugTimer' => 'Debug/debug_timer.php', + 'ezcDebugTimerStruct' => 'Debug/structs/timer.php', ); ?> Added: trunk/Debug/src/exceptions/exception.php ============================================================================== --- trunk/Debug/src/exceptions/exception.php (added) +++ trunk/Debug/src/exceptions/exception.php [iso-8859-1] Fri Feb 15 14:05:08 2008 @@ -1,0 +1,26 @@ +<?php +/** + * File containing the ezcDebugException class. + * + * @package Debug + * @version //autogentag// + * @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ + +/** + * General exception class for the Debug component. + * + * This exception is thrown whenever something goes wrong in the Debug + * component internally. + * + * @package Debug + * @version //autogen// + * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ +class ezcDebugException extends ezcBaseException +{ +} + +?> Propchange: trunk/Debug/src/exceptions/exception.php ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/Debug/src/interfaces/stacktrace_iterator.php ============================================================================== --- trunk/Debug/src/interfaces/stacktrace_iterator.php (added) +++ trunk/Debug/src/interfaces/stacktrace_iterator.php [iso-8859-1] Fri Feb 15 14:05:08 2008 @@ -1,0 +1,244 @@ +<?php +/** + * File containing the ezcDebug class. + * + * @package Debug + * @version //autogentag// + * @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ + +/** + * Base iterator class to wrap stack traces. + * + * This class provides a basis for stack trace iterators that are stored for + * each call to [EMAIL PROTECTED] ezcDebug::log()} if [EMAIL PROTECTED] ezcDebugOptions::$stackTrace} + * is switched on or the specific parameter is set. The stack trace iterator + * needs to ensure, that the created stack trace is converted to the format + * understandable by the [EMAIL PROTECTED] ezcDebugFormatter} as defined in [EMAIL PROTECTED] + * ezcDebugStacktraceIterator::unifyStackElement()}. + * + * @package Debug + * @version //autogen// + * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ +abstract class ezcDebugStacktraceIterator implements Iterator, ArrayAccess, Countable +{ + + /** + * Raw stack trace as an array. + * + * @var array + */ + private $stackTrace; + + /** + * Options. + * + * @var ezcDebugOptions + */ + protected $options; + + /** + * Unifies a stack element for being returned to the formatter. + * + * This method ensures that an element of the stack trace conforms to the + * format expected by a [EMAIL PROTECTED] ezcDebugOutputFormatter}. The format is + * defined as follows: + * + * <code> + * array( + * 'file' => '<fullpathtofile>', + * 'line' => <lineno>, + * 'function' => '<functionname>', + * 'class' => '<classname>', + * 'params' => array( + * <param_no> => '<paramvalueinfo>', + * <param_no> => '<paramvalueinfo>', + * <param_no> => '<paramvalueinfo>', + * ... + * ) + * ) + * </code> + * + * @param mixed $stackElement + * @return array As described above. + */ + protected abstract function unifyStackElement( $stackElement ); + + /** + * Prepares the stack trace for being stored in the iterator instance. + * + * This method is called by [EMAIL PROTECTED] + * ezcDebugStacktraceIterator::__construct()} before the stack trace is + * stored in the corresponding property. The given array can be manipulated + * as needed to prepare the trace and the array to store internally must be + * returned. + * + * @param mixed $stackTrace + * @return array The stack trace to store. + */ + protected function prepare( $stackTrace ) + { + if ( $this->options->stackTraceDepth !== 0 ) + { + return array_slice( $stackTrace, 0, $this->options->stackTraceDepth ); + } + } + + /** + * Creates a new stack trace iterator. + * + * Calls [EMAIL PROTECTED] ezcDebugStacktraceIterator::prepare()} internally to + * prepare the stack trace before storing it. + * + * @param mixed $stackTrace + * @param ezcDebugOptions $options + * @return void + */ + public final function __construct( array $stackTrace, ezcDebugOptions $options ) + { + $this->options = $options; + $this->stackTrace = $this->prepare( $stackTrace, $options ); + } + + /** + * Returns the currently selected element of the iterator. + * + * This method is part of the Iterator interface. + * + * @return mixed + */ + public final function current() + { + return $this->unifyStackElement( + current( $this->stackTrace ) + ); + } + + /** + * Returns the key of the currently selected element of the iterator. + * + * This method is part of the Iterator interface. + * + * @return mixed + */ + public final function key() + { + return key( $this->stackTrace ); + } + + /** + * Advances the iterator to the next element. + * + * This method is part of the Iterator interface. + * + * @return mixed + */ + public final function next() + { + return next( $this->stackTrace ); + } + + /** + * Resets the iterator to the first element. + * + * This method is part of the Iterator interface. + * + * @return mixed + */ + public final function rewind() + { + return reset( $this->stackTrace ); + } + + /** + * Returns if the iterator is on a valid element or at the end. + * + * This method is part of the Iterator interface. + * + * @return bool + */ + public final function valid() + { + return ( current( $this->stackTrace ) !== false ); + } + + /** + * Returns if the given offset exists. + * + * This method is part of the ArrayAccess interface. + * + * @param mixed $offset + * @return bool + */ + public final function offsetExists( $offset ) + { + return array_key_exists( $offset, $this->stackTrace ); + } + + /** + * Returns the value assigned to the given offset. + * + * This method is part of the ArrayAccess interface. + * + * @param mixed $offset + * @return mixed + */ + public final function offsetGet( $offset ) + { + if ( !$this->offsetExists( $offset ) ) + { + throw new ezcBaseValueException( + 'offset', + $offset, + 'valid offset' + ); + } + return $this->unifyStackElement( $this->stackTrace[$offset] ); + } + + /** + * It is not allowed to use this method with this iterator. + * + * This method is part of the ArrayAccess interface. + * + * @throws ezcDebugException + * @param mixed $offset + * @param mixed $value + * @return void + */ + public final function offsetSet( $offset, $value ) + { + throw new ezcDebugException( 'Setting values on backtrace iterators is not allowed.' ); + } + + /** + * It is not allowed to use this method with this iterator. + * + * This method is part of the ArrayAccess interface. + * + * @throws ezcDebugException + * @param mixed $offset + * @return void + */ + public final function offsetUnset( $offset ) + { + throw new ezcDebugException( 'Unsetting values on backtrace iterators is not allowed.' ); + } + + /** + * Returns the number of elements in the iterator. + * + * This method is part of the Countable interface. + * + * @return int + */ + public final function count() + { + return count( $this->stackTrace ); + } +} + +?> Propchange: trunk/Debug/src/interfaces/stacktrace_iterator.php ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/Debug/src/stacktrace/php_iterator.php ============================================================================== --- trunk/Debug/src/stacktrace/php_iterator.php (added) +++ trunk/Debug/src/stacktrace/php_iterator.php [iso-8859-1] Fri Feb 15 14:05:08 2008 @@ -1,0 +1,292 @@ +<?php +/** + * File containing the ezcDebugPhpStacktraceIterator class. + * + * @package Debug + * @version //autogentag// + * @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ + +/** + * Iterator class to wrap around debug_backtrace() stack traces. + * + * This iterator class receives a stack trace generated by debug_backtrace() + * and unifies it as described in the [EMAIL PROTECTED] ezcDebugStacktraceIterator} + * interface. + * + * @package Debug + * @version //autogen// + * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + */ +class ezcDebugPhpStacktraceIterator +{ + const MAX_DATA = 512; + + const MAX_CHILDREN = 128; + + protected function prepare( $stackTrace ) + { + return parent::prepare( + // Pop first 2 elements to ignore log() and getStackTrace() calls + array_slice( $stackTrace, 2 ) + ); + } + + /** + * Unifies a stack element for being returned to the formatter. + * + * This method ensures that an element of the stack trace conforms to the + * format expected by a [EMAIL PROTECTED] ezcDebugOutputFormatter}. The format is + * defined as follows: + * + * <code> + * array( + * 'file' => '<fullpathtofile>', + * 'line' => <lineno>, + * 'function' => '<functionname>', + * 'class' => '<classname>', + * 'params' => array( + * <param_no> => '<paramvalueinfo>', + * <param_no> => '<paramvalueinfo>', + * <param_no> => '<paramvalueinfo>', + * ... + * ) + * ) + * </code> + * + * @param mixed $stackElement + * @return array As described above. + */ + protected function unifyStackElement( $stackElement ) + { + // Not to be set in the unified version + unset( $stackElement['type'] ); + + // Unify args -> params + $stackElement['params'] = self::dumpVariables( $stackElement['args'] ); + unset( $stackElement['args'] ); + + return $stackElement; + } + + /** + * Returns the arguments of a stack element as string dumps. + * + * Returns an array corresponding to the 'params' key of a unified stack + * element, created from the 'args' ($args) element from an unified one. + * + * @param array $args + * @return array + */ + private function convertArgsToParams( $args ) + { + $params = array(); + foreach ( $args as $arg ) + { + $params[] = self::dumpVariable( $arg ); + } + return $params; + } + + /** + * Returns the string representation of an variable. + * + * Returns the dump of the given variable, respecting the $maxData and + * $maxChildren paramaters when arrays or objects are dumped. + * + * @param mixed $arg + * @param int $maxData + * @param int $maxChildren + * @return string + */ + public static function dumpVariable( $arg, $maxData = self::MAX_DATA, $maxChildren = self::MAX_CHILDREN ) + { + switch ( gettype( $arg ) ) + { + case 'boolean': + return self::cutString( ( $arg ? 'TRUE' : 'FALSE' ), $maxData ); + case 'integer': + case 'double': + return self::cutString( (string) $arg, $maxData ); + case 'string': + return sprintf( + "'%s'", + self::cutString( (string) $arg, $maxData ) + ); + case 'array': + return self::dumpArray( $arg, $maxData, $maxChildren ); + case 'object': + return self::dumpObject( $arg, $maxData, $maxChildren ); + case 'resource': + return self::dumpResource( $arg, $maxData ); + case 'NULL': + return 'NULL'; + default: + return 'unknown type'; + } + } + + /** + * Returns the string representation of an array. + * + * Returns the dump of the given array, respecting the $maxData and + * $maxChildren paramaters. + * + * @param array $arg + * @param int $maxData + * @param int $maxChildren + * @return string + */ + private static function dumpArray( array $arg, $maxData, $maxChildren ) + { + $max = min( count( $arg ), $maxChildren ); + + $results = array(); + reset( $arg ); + for ( $i = 0; $i < $max; ++$i ) + { + $results[] = + self::dumpVariable( key( $arg ), $maxData, $maxChildren ) + . ' => ' + . self::dumpVariable( current( $arg ), $maxData, $maxChildren ); + next( $arg ); + } + + if ( $max < count( $arg ) ) + { + $results[] = '...'; + } + + return sprintf( + 'array (%s)', implode( ', ', $results ) + ); + } + + /** + * Returns the string representation of an object. + * + * Returns the dump of the given object, respecting the $maxData and + * $maxChildren paramaters. + * + * @param object $arg + * @param int $maxData + * @param int $maxChildren + * @return string + */ + private static function dumpObject( $arg, $maxData, $maxChildren ) + { + $refObj = new ReflectionObject( $arg ); + $refProps = $refObj->getProperties(); + + $max = min( + count( $refProps ), + $maxChildren + ); + + $results = array(); + reset( $refProps ); + for( $i = 0; $i < $max; $i++ ) + { + $refProp = current( $refProps ); + $results[] = sprintf( + '%s $%s = %s', + self::getPropertyVisibility( $refProp ), + $refProp->getName(), + self::getPropertyValue( $refProp, $arg ) + ); + next( $refProps ); + } + + return sprintf( + 'class %s { %s }', + $refObj->getName(), + implode( '; ', $results ) + ); + } + + private static function dumpResource( $res, $maxData ) + { + // resource(5) of type (stream) + preg_match( '(Resource id #(?P<id>\d+))', (string) $res, $matches ); + return sprintf( + 'resource(%s) of type (%s)', + $matches['id'], + get_resource_type( $res ) + ); + } + + /** + * Returns the $value cut to $length and padded with '...'. + * + * @param string $value + * @param int $length + * @return string + */ + private static function cutString( $value, $length ) + { + if ( strlen( $value ) > ( $length - 3 ) ) + { + return substr( $value, 0, ( $length - 3 ) ) . '...'; + } + return $value; + } + + /** + * Returns private, protected or public. + * + * Returns the visibility of the given relfected property $refProp as a + * readable string. + * + * @param ReflectionProperty $refProp + * @return string + */ + private static function getPropertyVisibility( ReflectionProperty $refProp ) + { + $info = '%s %s = %s'; + switch ( true ) + { + case $refProp->isPrivate(): + return 'private'; + case $refProp->isProtected(): + return 'protected'; + case $refProp->isPublic(): + default: + return 'public'; + } + } + + /** + * Returns the dumped property value. + * + * Returns the dumped value for the given reflected property ($refProp) on + * the given $obj. Makes use of the ugly array casting hack to determine + * values of private and protected properties. + * + * @param ReflectionProperty $refProp + * @param object $obj + * @return string + */ + private static function getPropertyValue( ReflectionProperty $refProp, $obj ) + { + $value = null; + // @TODO: If we switch to a PHP version where Reflection can access + // protected/private property values, we should change this to the + // correct way. + if ( !$refProp->isPublic() ) + { + $objArr = (array) $obj; + $className = ( $refProp->isProtected() ? '*' : $refProp->getDeclaringClass()->getName() ); + $propName = $refProp->getName(); + $value = $objArr["\0{$className}\0{$propName}"]; + } + else + { + $value = $refProp->getValue( $obj ); + } + return self::dumpVariable( $value ); + } +} + +?> Propchange: trunk/Debug/src/stacktrace/php_iterator.php ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/Debug/tests/php_stacktrace_iterator_test.php ============================================================================== --- trunk/Debug/tests/php_stacktrace_iterator_test.php (added) +++ trunk/Debug/tests/php_stacktrace_iterator_test.php [iso-8859-1] Fri Feb 15 14:05:08 2008 @@ -1,0 +1,259 @@ +<?php +/** + * @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + * @version //autogentag// + * @filesource + * @package Debug + * @subpackage Tests + */ + +class DebugTestDumpObject +{ + private $private; + + protected $protected; + + public $public; + + public function __construct( $private, $protected, $public ) + { + $this->private = $private; + $this->protected = $protected; + $this->public = $public; + } +} + +class DebugTestDumpObjectExtended extends DebugTestDumpObject +{ + private $extendedPrivate; + + protected $extendedProtected; + + public $extendedPublic; + + public function __construct( $private, $protected, $public, $extendedPrivate, $extendedProtected, $extendedPublic ) + { + $this->extendedPrivate = $extendedPrivate; + $this->extendedProtected = $extendedProtected; + $this->extendedPublic = $extendedPublic; + parent::__construct( $private, $protected, $public ); + } +} + + +/** + * Test suite for the ezcDebugOptions class. + * + * @package Debug + * @subpackage Tests + */ +class ezcDebugPhpStacktraceIteratorTest extends ezcTestCase +{ + public static function suite() + { + return new PHPUnit_Framework_TestSuite( __CLASS__ ); + } + + public function testDumpBoolean() + { + $true = true; + $false = false; + + $this->assertEquals( + 'TRUE', + ezcDebugPhpStacktraceIterator::dumpVariable( $true ) + ); + $this->assertEquals( + 'FALSE', + ezcDebugPhpStacktraceIterator::dumpVariable( $false ) + ); + } + + public function testDumpInteger() + { + $a = 0; + $b = 23; + $c = -42; + + $this->assertEquals( + '0', + ezcDebugPhpStacktraceIterator::dumpVariable( $a ) + ); + $this->assertEquals( + '23', + ezcDebugPhpStacktraceIterator::dumpVariable( $b ) + ); + $this->assertEquals( + '-42', + ezcDebugPhpStacktraceIterator::dumpVariable( $c ) + ); + } + + public function testDumpDouble() + { + $a = 0.0; + $b = 23.0; + $c = -42.0; + $d = 23.42; + $e = -42.23; + + $this->assertEquals( + '0', + ezcDebugPhpStacktraceIterator::dumpVariable( $a ) + ); + $this->assertEquals( + '23', + ezcDebugPhpStacktraceIterator::dumpVariable( $b ) + ); + $this->assertEquals( + '-42', + ezcDebugPhpStacktraceIterator::dumpVariable( $c ) + ); + $this->assertEquals( + '23.42', + ezcDebugPhpStacktraceIterator::dumpVariable( $d ) + ); + $this->assertEquals( + '-42.23', + ezcDebugPhpStacktraceIterator::dumpVariable( $e ) + ); + } + + public function testDumpString() + { + $a = 'foo'; + $b = ''; + + $this->assertEquals( + "'foo'", + ezcDebugPhpStacktraceIterator::dumpVariable( $a ) + ); + $this->assertEquals( + "''", + ezcDebugPhpStacktraceIterator::dumpVariable( $b ) + ); + } + + public function testDumpSimpleArray() + { + $arr = array( + 23, 42.23, true, false, 'test', 'foo bar baz' + ); + + $res = <<<EOT +array (0 => 23, 1 => 42.23, 2 => TRUE, 3 => FALSE, 4 => 'test', 5 => 'foo bar baz') +EOT; + $this->assertEquals( + $res, + ezcDebugPhpStacktraceIterator::dumpVariable( $arr ) + ); + } + + public function testDumpComplexArray() + { + $arr = array( + 23, + 'foo bar' => array( + 1 => '293', + 234223, + 'foo' => array( + 1, 2, 3, 4, 5, array(), 8 => 23, 'foo', array( 23, 42 ) + ), + ), + 42.23, + 'a' => true, + 'd' => false, + 23 => 'test', + 'foo bar baz', + ); + + $res = <<<EOT +array (0 => 23, 'foo bar' => array (1 => '293', 2 => 234223, 'foo' => array (0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => array (), 8 => 23, 9 => 'foo', 10 => array (0 => 23, 1 => 42))), 1 => 42.23, 'a' => TRUE, 'd' => FALSE, 23 => 'test', 24 => 'foo bar baz') +EOT; + $this->assertEquals( + $res, + ezcDebugPhpStacktraceIterator::dumpVariable( $arr ) + ); + } + + public function testDumpSimpleObject() + { + $obj = new DebugTestDumpObject( 23, 42.23, 'foo bar baz' ); + + $res = <<<EOT +class DebugTestDumpObject { private \$private = 23; protected \$protected = 42.23; public \$public = 'foo bar baz' } +EOT; + + $this->assertEquals( + $res, + ezcDebugPhpStacktraceIterator::dumpVariable( $obj ) + ); + } + + public function testDumpExtendedObject() + { + $obj = new DebugTestDumpObjectExtended( 23, 42.23, 'foo bar baz', 42, true, false ); + + $res = <<<EOT +class DebugTestDumpObjectExtended { private \$extendedPrivate = 42; protected \$extendedProtected = TRUE; public \$extendedPublic = FALSE; protected \$protected = 42.23; public \$public = 'foo bar baz' } +EOT; + + $this->assertEquals( + $res, + ezcDebugPhpStacktraceIterator::dumpVariable( $obj ) + ); + } + + public function testDumpExtendedObjectComplex() + { + $obj = new DebugTestDumpObjectExtended( + array(), + 42.23, + 'foo bar baz', + array( + 1, + 2, + array( + new stdClass(), + 'some text', + new stdClass(), + 23, + array( null, null, true, false, null, 23 ) + ), + 3, + 4, + ), + true, + array( + new DebugTestDumpObject( + new DebugTestDumpObjectExtended( 1, 2, 3, 4, 5, 6 ), + array( true, false, 'string' ), + new DebugTestDumpObject( 'a', 2, 'c' ) + ), + ) + ); + + $res = <<<EOT +class DebugTestDumpObjectExtended { private \$extendedPrivate = array (0 => 1, 1 => 2, 2 => array (0 => class stdClass { }, 1 => 'some text', 2 => class stdClass { }, 3 => 23, 4 => array (0 => NULL, 1 => NULL, 2 => TRUE, 3 => FALSE, 4 => NULL, 5 => 23)), 3 => 3, 4 => 4); protected \$extendedProtected = TRUE; public \$extendedPublic = array (0 => class DebugTestDumpObject { private \$private = class DebugTestDumpObjectExtended { private \$extendedPrivate = 4; protected \$extendedProtected = 5; public \$extendedPublic = 6; protected \$protected = 2; public \$public = 3 }; protected \$protected = array (0 => TRUE, 1 => FALSE, 2 => 'string'); public \$public = class DebugTestDumpObject { private \$private = 'a'; protected \$protected = 2; public \$public = 'c' } }); protected \$protected = 42.23; public \$public = 'foo bar baz' } +EOT; + + $this->assertEquals( + $res, + ezcDebugPhpStacktraceIterator::dumpVariable( $obj ) + ); + } + + public function testDumpResource() + { + $res = fopen( __FILE__, 'r' ); + + preg_match( '(Resource id #(?P<id>\d+))', (string) $res, $matches ); + + $this->assertEquals( + "resource({$matches['id']}) of type (stream)", + ezcDebugPhpStacktraceIterator::dumpVariable( $res ) + ); + } +} +?> Propchange: trunk/Debug/tests/php_stacktrace_iterator_test.php ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/Debug/tests/suite.php ============================================================================== --- trunk/Debug/tests/suite.php [iso-8859-1] (original) +++ trunk/Debug/tests/suite.php [iso-8859-1] Fri Feb 15 14:05:08 2008 @@ -18,6 +18,7 @@ require_once "debug_timer_test.php"; require_once "writers/memory_writer_test.php"; require_once "formatters/html_formatter_test.php"; +require_once "php_stacktrace_iterator_test.php"; /** * @package Debug @@ -36,6 +37,7 @@ $this->addTest( ezcDebugTest::suite() ); $this->addTest( ezcDebugOptionsTest::suite() ); $this->addTest( ezcDebugHtmlFormatterTest::suite() ); + $this->addTest( ezcDebugPhpStacktraceIteratorTest::suite() ); } public static function suite() -- svn-components mailing list svn-components@lists.ez.no http://lists.ez.no/mailman/listinfo/svn-components