Prepending exception frame list with previous exception's topmost part that matters for #43

This commit is contained in:
Aleksandr Bogdanov
2014-02-04 12:32:04 +01:00
parent 5d7acac270
commit d294a7e9ad
5 changed files with 76 additions and 6 deletions
+4
View File
@@ -225,4 +225,8 @@ class Frame implements Serializable
$this->frame = $frame;
}
public function equals(Frame $frame){
return $frame->getFile() == $this->getFile() && $frame->getLine() === $this->getLine();
}
}
+32
View File
@@ -119,4 +119,36 @@ class FrameCollection implements IteratorAggregate, Serializable, Countable
{
$this->frames = unserialize($serializedFrames);
}
/**
* @param Frame[] $frames Array of Frame instances, usually from $e->getPrevious()
*/
public function prependFrames(array $frames)
{
$this->frames = array_merge($frames, $this->frames);
}
/**
* Gets the innermost part of stack trace that is not the same as that of outer exception
*
* @param FrameCollection $parentFrames Outer exception frames to compare tail against
* @return Frame[]
*/
public function topDiff(FrameCollection $parentFrames)
{
$diff = $this->frames;
$parentFrames = $parentFrames->getArray();
$p = count($parentFrames)-1;
for($i = count($diff)-1; $i >= 0 && $p >= 0; $i--) {
/** @var Frame $tailFrame */
$tailFrame = $diff[$i];
if($tailFrame->equals($parentFrames[$p])) {
unset($diff[$i]);
}
$p--;
}
return $diff;
}
}
+9 -6
View File
@@ -5,8 +5,6 @@
*/
namespace Whoops\Exception;
use Whoops\Exception\FrameCollection;
use Whoops\Exception\ErrorException;
use Exception;
class Inspector
@@ -17,12 +15,12 @@ class Inspector
private $exception;
/**
* @var Whoops\Exception\FrameCollection
* @var \Whoops\Exception\FrameCollection
*/
private $frames;
/**
* @var Whoops\Exception\Inspector
* @var \Whoops\Exception\Inspector
*/
private $previousExceptionInspector;
@@ -70,7 +68,7 @@ class Inspector
/**
* Returns an inspector for a previous inspector, if any.
* @todo Clean this up a bit, cache stuff a bit better.
* @return Whoops\Exception\Inspector|null
* @return \Whoops\Exception\Inspector|null
*/
public function getPreviousExceptionInspector()
{
@@ -88,7 +86,7 @@ class Inspector
/**
* Returns an iterator for the inspected exception's
* frames.
* @return Whoops\Exception\FrameCollection
* @return \Whoops\Exception\FrameCollection
*/
public function getFrames()
{
@@ -107,11 +105,16 @@ class Inspector
array_unshift($frames, $firstFrame);
}
$this->frames = new FrameCollection($frames);
if ($previousInspector = $this->getPreviousExceptionInspector()) {
$this->frames->prependFrames($previousInspector->getFrames()->topDiff($this->frames));
}
}
return $this->frames;
}
/**
* Given an exception, generates an array in the format
* generated by Exception::getTrace()
@@ -147,4 +147,26 @@ class FrameCollectionTest extends TestCase
$this->assertInstanceOf('Whoops\\Exception\\Frame', $frame);
}
}
/**
* @covers Whoops\Exception\FrameCollection::topDiff
*/
public function testTopDiff(){
$commonFrameTail = $this->getFrameDataList(3);
$diffFrame = array('line' => $this->frameIdCounter) + $this->getFrameData();
$frameCollection1 = new FrameCollection(array_merge(array(
$diffFrame
), $commonFrameTail));
$frameCollection2 = new FrameCollection(array_merge(array(
$this->getFrameData()
), $commonFrameTail));
$diff = $frameCollection1->topDiff($frameCollection2);
$this->assertCount(1, $diff);
}
}
+9
View File
@@ -206,4 +206,13 @@ class FrameTest extends TestCase
$this->assertEquals($comments[0]["comment"], $commentText);
$this->assertEquals($comments[0]["context"], $commentContext);
}
/**
* @covers Whoops\Exception\Frame::equals
*/
public function testEquals(){
$frame1 = $this->getFrameInstance(array('line' => 1, 'file' => 'test-file.php'));
$frame2 = $this->getFrameInstance(array('line' => 1, 'file' => 'test-file.php'));
$this->assertTrue ($frame1->equals($frame2));
}
}