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

Reply via email to