PHP >= 5.4.0 started taking advantage of $limit optimization of wfDebugBacktrace(),
authorPlatonides <platonides@gmail.com>
Thu, 31 May 2012 15:29:43 +0000 (17:29 +0200)
committerPlatonides <platonides@gmail.com>
Thu, 31 May 2012 15:32:33 +0000 (17:32 +0200)
which we weren't treating right.

* $limit in wfDebugBacktrace() is the number of returned frames,
we thus need to take into account the wfDebugBacktrace() frame, which
is sliced from debug_backtrace().

* wfGetCaller() needs to add a level for itself.

* MWDebug::warning() was logging itself as the warning issuer,
which is useless (the call a few lines before was right, though)
MWDebugTest.php changed accordingly.

* Removed double call to wfGetCaller( $callerOffset + 1 )

* Documented the meaning of wfGetCaller() parameter

* Added unit test

Change-Id: Ief50f4c810bad8b03bb2bf9dc6d945d9acb29851

includes/GlobalFunctions.php
includes/debug/Debug.php
tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php [new file with mode: 0644]
tests/phpunit/includes/debug/MWDebugTest.php

index 57ab64c..4cfd946 100644 (file)
@@ -1831,7 +1831,7 @@ function wfDebugBacktrace( $limit = 0 ) {
        }
 
        if ( $limit && version_compare( PHP_VERSION, '5.4.0', '>=' ) ) {
-               return array_slice( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT, $limit ), 1 );
+               return array_slice( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT, $limit + 1 ), 1 );
        } else {
                return array_slice( debug_backtrace(), 1 );
        }
@@ -1890,12 +1890,15 @@ function wfBacktrace() {
 
 /**
  * Get the name of the function which called this function
+ * wfGetCaller( 1 ) is the function with the wfGetCaller() call (ie. __FUNCTION__)
+ * wfGetCaller( 2 ) [default] is the caller of the function running wfGetCaller()
+ * wfGetCaller( 3 ) is the parent of that.
  *
  * @param $level Int
  * @return Bool|string
  */
 function wfGetCaller( $level = 2 ) {
-       $backtrace = wfDebugBacktrace( $level );
+       $backtrace = wfDebugBacktrace( $level + 1 );
        if ( isset( $backtrace[$level] ) ) {
                return wfFormatStackFrame( $backtrace[$level] );
        } else {
index 211f74a..0c0052f 100644 (file)
@@ -145,9 +145,10 @@ class MWDebug {
                // Check to see if there was already a deprecation notice, so not to
                // get a duplicate warning
                $logCount = count( self::$log );
+               $caller = wfGetCaller( $callerOffset + 1 );
                if ( $logCount ) {
                        $lastLog = self::$log[ $logCount - 1 ];
-                       if ( $lastLog['type'] == 'deprecated' && $lastLog['caller'] == wfGetCaller( $callerOffset + 1 ) ) {
+                       if ( $lastLog['type'] == 'deprecated' && $lastLog['caller'] == $caller ) {
                                return;
                        }
                }
@@ -155,7 +156,7 @@ class MWDebug {
                self::$log[] = array(
                        'msg' => htmlspecialchars( $msg ),
                        'type' => 'warn',
-                       'caller' => wfGetCaller( $callerOffset ),
+                       'caller' => $caller,
                );
        }
 
diff --git a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php
new file mode 100644 (file)
index 0000000..4c4c4c0
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+class wfGetCaller extends MediaWikiTestCase {
+
+       function testZero() {
+               $this->assertEquals( __METHOD__, wfGetCaller( 1 ) );
+       }
+
+       function callerOne() {
+               return wfGetCaller();
+       }
+
+       function testOne() {
+               $this->assertEquals( "wfGetCaller::testOne", self::callerOne() );
+       }
+
+       function intermediateFunction( $level = 2, $n = 0 ) {
+               if ( $n > 0 )
+                       return self::intermediateFunction( $level, $n - 1 );
+               return wfGetCaller( $level );
+       }
+
+       function testTwo() {
+               $this->assertEquals( "wfGetCaller::testTwo", self::intermediateFunction() );
+       }
+
+       function testN() {
+               $this->assertEquals( "wfGetCaller::testN", self::intermediateFunction( 2, 0 ) );
+               $this->assertEquals( "wfGetCaller::intermediateFunction", self::intermediateFunction( 1, 0 ) );
+
+               for ($i=0; $i < 10; $i++)
+                       $this->assertEquals( "wfGetCaller::intermediateFunction", self::intermediateFunction( $i + 1, $i ) );
+       }
+}
+
index 5a4e66d..1627c47 100644 (file)
@@ -30,7 +30,7 @@ class MWDebugTest extends MediaWikiTestCase {
                $this->assertEquals( array( array(
                        'msg' => 'Warning message',
                        'type' => 'warn',
-                       'caller' => 'MWDebug::warning',
+                       'caller' => 'MWDebugTest::testAddWarning',
                        ) ),
                        MWDebug::getLog()
                );