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; $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); $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; namespace Whoops\Exception;
use Whoops\Exception\FrameCollection;
use Whoops\Exception\ErrorException;
use Exception; use Exception;
class Inspector class Inspector
@@ -17,12 +15,12 @@ class Inspector
private $exception; private $exception;
/** /**
* @var Whoops\Exception\FrameCollection * @var \Whoops\Exception\FrameCollection
*/ */
private $frames; private $frames;
/** /**
* @var Whoops\Exception\Inspector * @var \Whoops\Exception\Inspector
*/ */
private $previousExceptionInspector; private $previousExceptionInspector;
@@ -70,7 +68,7 @@ class Inspector
/** /**
* Returns an inspector for a previous inspector, if any. * Returns an inspector for a previous inspector, if any.
* @todo Clean this up a bit, cache stuff a bit better. * @todo Clean this up a bit, cache stuff a bit better.
* @return Whoops\Exception\Inspector|null * @return \Whoops\Exception\Inspector|null
*/ */
public function getPreviousExceptionInspector() public function getPreviousExceptionInspector()
{ {
@@ -88,7 +86,7 @@ class Inspector
/** /**
* Returns an iterator for the inspected exception's * Returns an iterator for the inspected exception's
* frames. * frames.
* @return Whoops\Exception\FrameCollection * @return \Whoops\Exception\FrameCollection
*/ */
public function getFrames() public function getFrames()
{ {
@@ -107,11 +105,16 @@ class Inspector
array_unshift($frames, $firstFrame); array_unshift($frames, $firstFrame);
} }
$this->frames = new FrameCollection($frames); $this->frames = new FrameCollection($frames);
if ($previousInspector = $this->getPreviousExceptionInspector()) {
$this->frames->prependFrames($previousInspector->getFrames()->topDiff($this->frames));
}
} }
return $this->frames; return $this->frames;
} }
/** /**
* Given an exception, generates an array in the format * Given an exception, generates an array in the format
* generated by Exception::getTrace() * generated by Exception::getTrace()
@@ -147,4 +147,26 @@ class FrameCollectionTest extends TestCase
$this->assertInstanceOf('Whoops\\Exception\\Frame', $frame); $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]["comment"], $commentText);
$this->assertEquals($comments[0]["context"], $commentContext); $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));
}
} }