From 790aa77cdf3f8a01c27ac2a1f2540e4e80f076f2 Mon Sep 17 00:00:00 2001 From: Ede Meijer Date: Thu, 28 Aug 2014 03:33:14 +0200 Subject: [PATCH] Seperated formatting from result --- src/EdeMeijer/SerializeDebugger/Debugger.php | 26 +++++++- .../Result/AbstractFormatter.php | 50 +++++++++++++++ .../Result/FormatterInterface.php | 13 ++++ .../Result/HTMLFormatter.php | 30 +++++++++ .../Result/PlainTextFormatter.php | 30 +++++++++ .../SerializeDebugger/{ => Result}/Result.php | 53 ++++------------ .../SerializeDebugger/Result/ResultItem.php | 51 ++++++++++++++++ .../Result/ResultItemCollection.php | 11 ++++ .../Result/SimpleResultItemCollection.php | 22 +++++++ .../Test/DebugResultTest.php | 45 ++++++-------- .../SerializeDebugger/Test/DebuggerTest.php | 8 +-- .../Test/PlainTextFormatterTest.php | 61 +++++++++++++++++++ 12 files changed, 326 insertions(+), 74 deletions(-) create mode 100644 src/EdeMeijer/SerializeDebugger/Result/AbstractFormatter.php create mode 100644 src/EdeMeijer/SerializeDebugger/Result/FormatterInterface.php create mode 100644 src/EdeMeijer/SerializeDebugger/Result/HTMLFormatter.php create mode 100644 src/EdeMeijer/SerializeDebugger/Result/PlainTextFormatter.php rename src/EdeMeijer/SerializeDebugger/{ => Result}/Result.php (65%) create mode 100644 src/EdeMeijer/SerializeDebugger/Result/ResultItem.php create mode 100644 src/EdeMeijer/SerializeDebugger/Result/ResultItemCollection.php create mode 100644 src/EdeMeijer/SerializeDebugger/Result/SimpleResultItemCollection.php create mode 100644 test/EdeMeijer/SerializeDebugger/Test/PlainTextFormatterTest.php diff --git a/src/EdeMeijer/SerializeDebugger/Debugger.php b/src/EdeMeijer/SerializeDebugger/Debugger.php index f41792b..88f6d08 100644 --- a/src/EdeMeijer/SerializeDebugger/Debugger.php +++ b/src/EdeMeijer/SerializeDebugger/Debugger.php @@ -2,16 +2,40 @@ namespace EdeMeijer\SerializeDebugger; +use EdeMeijer\SerializeDebugger\Result\HTMLFormatter; +use EdeMeijer\SerializeDebugger\Result\PlainTextFormatter; +use EdeMeijer\SerializeDebugger\Result\Result; + class Debugger { /** * @param mixed $data * @return Result */ - public function debug($data) + public function getDebugResult($data) { $tracker = new Tracker(); $tracker->getNodeForData($data)->resolve(); return new Result($tracker->getNodes()); } + + /** + * @param mixed $data + * @param bool $verbose + */ + public static function debugPlaintext($data, $verbose = false) + { + echo (new PlainTextFormatter()) + ->format((new Debugger())->getDebugResult($data), $verbose); + } + + /** + * @param mixed $data + * @param bool $verbose + */ + public static function debugHTML($data, $verbose = false) + { + echo (new HTMLFormatter()) + ->format((new Debugger())->getDebugResult($data), $verbose); + } } diff --git a/src/EdeMeijer/SerializeDebugger/Result/AbstractFormatter.php b/src/EdeMeijer/SerializeDebugger/Result/AbstractFormatter.php new file mode 100644 index 0000000..1bda187 --- /dev/null +++ b/src/EdeMeijer/SerializeDebugger/Result/AbstractFormatter.php @@ -0,0 +1,50 @@ +getItems() as $item) { + $type = $item->getType(); + $level = $type->getLevel(); + if ($verbose || $level > TypeInterface::LEVEL_SAFE) { + $visibleItems[] = $item; + } + } + return $this->doFormat($visibleItems); + } + + /** + * @param ResultItem[] $items + * @return string + */ + abstract protected function doFormat(array $items); + + /** + * @param int $level + * @throws Exception + * @return string + */ + protected function getLevelIndicator($level) + { + if ($level === TypeInterface::LEVEL_SAFE) { + return 'safe'; + } elseif ($level === TypeInterface::LEVEL_WARNING) { + return 'WARNING'; + } elseif ($level === TypeInterface::LEVEL_ERROR) { + return 'ERROR'; + } + throw new Exception('Invalid level'); + } +} \ No newline at end of file diff --git a/src/EdeMeijer/SerializeDebugger/Result/FormatterInterface.php b/src/EdeMeijer/SerializeDebugger/Result/FormatterInterface.php new file mode 100644 index 0000000..754c801 --- /dev/null +++ b/src/EdeMeijer/SerializeDebugger/Result/FormatterInterface.php @@ -0,0 +1,13 @@ +getType(); + $level = $type->getLevel(); + + $levelIndicator = $this->getLevelIndicator($level); + $res[] = sprintf( + '%s - %s', + $type->getName($item->getData()), + $levelIndicator + ); + foreach ($item->getReferencePaths() as $path) { + $res[] = str_repeat(' ', 4) . $path; + } + } + return implode('
', $res); + } +} \ No newline at end of file diff --git a/src/EdeMeijer/SerializeDebugger/Result/PlainTextFormatter.php b/src/EdeMeijer/SerializeDebugger/Result/PlainTextFormatter.php new file mode 100644 index 0000000..a43ae01 --- /dev/null +++ b/src/EdeMeijer/SerializeDebugger/Result/PlainTextFormatter.php @@ -0,0 +1,30 @@ +getType(); + $level = $type->getLevel(); + + $levelIndicator = $this->getLevelIndicator($level); + $res[] = sprintf( + '%s - %s', + $type->getName($item->getData()), + $levelIndicator + ); + foreach ($item->getReferencePaths() as $path) { + $res[] = "\t" . $path; + } + } + return implode(PHP_EOL, $res); + } +} \ No newline at end of file diff --git a/src/EdeMeijer/SerializeDebugger/Result.php b/src/EdeMeijer/SerializeDebugger/Result/Result.php similarity index 65% rename from src/EdeMeijer/SerializeDebugger/Result.php rename to src/EdeMeijer/SerializeDebugger/Result/Result.php index 0f7c266..fe9ddaa 100644 --- a/src/EdeMeijer/SerializeDebugger/Result.php +++ b/src/EdeMeijer/SerializeDebugger/Result/Result.php @@ -1,10 +1,10 @@ process(); return $this->nodes; @@ -47,50 +47,21 @@ private function process() } /** - * @param bool $verbose - * @return string[] + * @return ResultItem[] */ - public function getOutputLines($verbose = false) + public function getItems() { - $this->process(); $res = []; - foreach ($this->nodes as $node) { - $type = $node->getType(); - $level = $type->getLevel(); - if ($verbose || $level > TypeInterface::LEVEL_SAFE) { - $levelIndicator = $this->getLevelIndicator($level); - $res[] = sprintf( - '%s - %s', - $type->getName($node->getData()), - $levelIndicator - ); - - $referencePaths = $this->getReferencePaths($node); - foreach ($referencePaths as $path) { - $res[] = "\t" . $path; - } - } + foreach ($this->getRawNodes() as $node) { + $res[] = new ResultItem( + $node->getData(), + $node->getType(), + $this->getReferencePaths($node) + ); } return $res; } - /** - * @param int $level - * @throws Exception - * @return string - */ - private function getLevelIndicator($level) - { - if ($level === TypeInterface::LEVEL_SAFE) { - return 'safe'; - } elseif ($level === TypeInterface::LEVEL_WARNING) { - return 'WARNING'; - } elseif ($level === TypeInterface::LEVEL_ERROR) { - return 'ERROR'; - } - throw new Exception('Invalid level'); - } - /** * @param Node $node * @return string[] diff --git a/src/EdeMeijer/SerializeDebugger/Result/ResultItem.php b/src/EdeMeijer/SerializeDebugger/Result/ResultItem.php new file mode 100644 index 0000000..4f7f5ee --- /dev/null +++ b/src/EdeMeijer/SerializeDebugger/Result/ResultItem.php @@ -0,0 +1,51 @@ +data = $data; + $this->type = $type; + $this->referencePaths = $referencePaths; + } + + /** + * @return mixed + */ + public function getData() + { + return $this->data; + } + + /** + * @return TypeInterface + */ + public function getType() + { + return $this->type; + } + + /** + * @return string[] + */ + public function getReferencePaths() + { + return $this->referencePaths; + } +} \ No newline at end of file diff --git a/src/EdeMeijer/SerializeDebugger/Result/ResultItemCollection.php b/src/EdeMeijer/SerializeDebugger/Result/ResultItemCollection.php new file mode 100644 index 0000000..40b4c9d --- /dev/null +++ b/src/EdeMeijer/SerializeDebugger/Result/ResultItemCollection.php @@ -0,0 +1,11 @@ +items = $items; + } + + /** + * @return ResultItem[] + */ + public function getItems() + { + return $this->items; + } +} \ No newline at end of file diff --git a/test/EdeMeijer/SerializeDebugger/Test/DebugResultTest.php b/test/EdeMeijer/SerializeDebugger/Test/DebugResultTest.php index a013d4b..7bc18e0 100644 --- a/test/EdeMeijer/SerializeDebugger/Test/DebugResultTest.php +++ b/test/EdeMeijer/SerializeDebugger/Test/DebugResultTest.php @@ -3,6 +3,12 @@ namespace EdeMeijer\SerializeDebugger\Test; use EdeMeijer\SerializeDebugger\Debugger; +use EdeMeijer\SerializeDebugger\Result\ResultItem; +use EdeMeijer\SerializeDebugger\Type\ArrayType; +use EdeMeijer\SerializeDebugger\Type\ClosureType; +use EdeMeijer\SerializeDebugger\Type\ObjectType; +use EdeMeijer\SerializeDebugger\Type\PrimitiveType; +use EdeMeijer\SerializeDebugger\Type\ResourceType; class DebugResultTest extends \PHPUnit_Framework_TestCase { @@ -14,7 +20,7 @@ public function setUp() $this->debugger = new Debugger(); } - public function testNonVerboseOutput() + public function testDebugResult() { $data = (object)[ 'prop' => [ @@ -27,36 +33,19 @@ public function testNonVerboseOutput() 'closure' => function() {} ]; - $SUT = $this->debugger->debug($data); - $actual = $SUT->getOutputLines(false); + Debugger::debugHTML($data); - $expected = [ - 'Resource - WARNING', - "\t" . '{root}->prop[sub][resource]', - 'Closure - ERROR', - "\t" . '{root}->closure', - ]; - - $this->assertEquals($expected, $actual); - } - - public function testVerboseOutput() - { - $data = [1, 2, [true]]; - - $SUT = $this->debugger->debug($data); - $actual = $SUT->getOutputLines(true); + $SUT = $this->debugger->getDebugResult($data); + $actual = $SUT->getItems(); $expected = [ - 'Array - safe', - 'Primitive: integer - safe', - "\t" . '{root}[0]', - 'Primitive: integer - safe', - "\t" . '{root}[1]', - 'Array - safe', - "\t" . '{root}[2]', - 'Primitive: boolean - safe', - "\t" . '{root}[2][0]', + new ResultItem($data, new ObjectType()), + new ResultItem($data->prop, new ArrayType(), ['{root}->prop']), + new ResultItem($data->prop['sub'], new ArrayType(), ['{root}->prop[sub]']), + new ResultItem($data->prop['sub']['resource'], new ResourceType(), ['{root}->prop[sub][resource]']), + new ResultItem($data->prop['test'], new PrimitiveType(), ['{root}->prop[test]']), + new ResultItem($data->test, new PrimitiveType(), ['{root}->test']), + new ResultItem($data->closure, new ClosureType(), ['{root}->closure']), ]; $this->assertEquals($expected, $actual); diff --git a/test/EdeMeijer/SerializeDebugger/Test/DebuggerTest.php b/test/EdeMeijer/SerializeDebugger/Test/DebuggerTest.php index 97a1a7f..43d7279 100644 --- a/test/EdeMeijer/SerializeDebugger/Test/DebuggerTest.php +++ b/test/EdeMeijer/SerializeDebugger/Test/DebuggerTest.php @@ -22,14 +22,14 @@ public function setUp() */ public function testBasicClassification($data, $expectedClass) { - $nodes = $this->SUT->debug($data)->getNodes(); + $nodes = $this->SUT->getDebugResult($data)->getRawNodes(); $this->assertCount(1, $nodes); $this->assertInstanceOf($expectedClass, $nodes[0]->getType()); } public function testArrayItemHandling() { - $nodes = $this->SUT->debug(['aaa', 'bbb'])->getNodes(); + $nodes = $this->SUT->getDebugResult(['aaa', 'bbb'])->getRawNodes(); // We expect 3 nodes, the array and both the strings $this->assertCount(3, $nodes); $arrayNode = $nodes[0]; @@ -39,7 +39,7 @@ public function testArrayItemHandling() public function testSimpleObjectPropertyHandling() { - $nodes = $this->SUT->debug((object)['a' => 'aaa', 'b' => 'bbb'])->getNodes(); + $nodes = $this->SUT->getDebugResult((object)['a' => 'aaa', 'b' => 'bbb'])->getRawNodes(); // We expect 3 nodes, the object and both the strings $this->assertCount(3, $nodes); $objectNode = $nodes[0]; @@ -53,7 +53,7 @@ public function testItHandlesCircularReferencesCorrectly() $b = new stdClass(); $a->bRef = $b; $b->aRef = $a; - $nodes = $this->SUT->debug($a)->getNodes(); + $nodes = $this->SUT->getDebugResult($a)->getRawNodes(); $this->assertCount(2, $nodes); $this->assertCount(1, $nodes[0]->getChildNodes()); diff --git a/test/EdeMeijer/SerializeDebugger/Test/PlainTextFormatterTest.php b/test/EdeMeijer/SerializeDebugger/Test/PlainTextFormatterTest.php new file mode 100644 index 0000000..a8b1dbf --- /dev/null +++ b/test/EdeMeijer/SerializeDebugger/Test/PlainTextFormatterTest.php @@ -0,0 +1,61 @@ +givenResultWithValidAndInvalidItems(); + + $SUT = new PlainTextFormatter(); + $formatted = $SUT->format($result, true); + + $expected = <<<'TEXT' +Primitive: NULL - safe +Primitive: boolean - safe + a->b +Closure - ERROR + a->b + c[d] +TEXT; + $this->assertEquals($expected, $formatted); + } + + public function testItHidesSafeItemsWhenNonVerbose() + { + $result = $this->givenResultWithValidAndInvalidItems(); + + $SUT = new PlainTextFormatter(); + $formatted = $SUT->format($result, false); + + $expected = <<<'TEXT' +Closure - ERROR + a->b + c[d] +TEXT; + $this->assertEquals($expected, $formatted); + } + + /** + * @return SimpleResultItemCollection + */ + private function givenResultWithValidAndInvalidItems() + { + return new SimpleResultItemCollection( + [ + new ResultItem(null, new PrimitiveType()), + new ResultItem(true, new PrimitiveType(), ['a->b']), + new ResultItem(null, new ClosureType(), ['a->b', 'c[d]']), + ] + ); + } +} + \ No newline at end of file