From 0f372119e689ff724e4df12e6a48b5b43f837191 Mon Sep 17 00:00:00 2001 From: Giulio De Donato Date: Mon, 24 Dec 2012 12:55:45 +0100 Subject: [PATCH 1/2] StringPresenter->ValuePresenter, TaggedPresenter->TaggedValuePresenter, created ExceptionPresenter --- .../Presenter/ExceptionPresenter.php | 79 ++++++ ...Presenter.php => TaggedValuePresenter.php} | 10 +- ...StringPresenter.php => ValuePresenter.php} | 19 +- spec/PHPSpec2/Matcher/ComparisonMatcher.php | 2 +- spec/PHPSpec2/Matcher/CountMatcher.php | 2 +- spec/PHPSpec2/Matcher/IdentityMatcher.php | 2 +- spec/PHPSpec2/Matcher/ObjectStateMatcher.php | 2 +- spec/PHPSpec2/Matcher/ScalarMatcher.php | 2 +- spec/PHPSpec2/Matcher/TypeMatcher.php | 2 +- src/PHPSpec2/Console/Application.php | 14 +- src/PHPSpec2/Exception/Exception.php | 14 +- src/PHPSpec2/Exception/ExceptionInterface.php | 9 + src/PHPSpec2/Formatter/FormatterInterface.php | 4 +- .../Presenter/Differ/ArrayEngine.php | 32 +++ .../Presenter/ExceptionPresenter.php | 180 ++++++++++++++ .../Presenter/ExceptionPresenterInterface.php | 14 ++ .../Presenter/PresenterInterface.php | 1 - .../Formatter/Presenter/StringPresenter.php | 227 ------------------ ...Presenter.php => TaggedValuePresenter.php} | 10 +- .../Formatter/Presenter/ValuePresenter.php | 93 +++++++ src/PHPSpec2/Formatter/PrettyFormatter.php | 13 +- src/PHPSpec2/Formatter/ProgressFormatter.php | 10 +- 22 files changed, 463 insertions(+), 278 deletions(-) create mode 100644 spec/PHPSpec2/Formatter/Presenter/ExceptionPresenter.php rename spec/PHPSpec2/Formatter/Presenter/{TaggedPresenter.php => TaggedValuePresenter.php} (63%) rename spec/PHPSpec2/Formatter/Presenter/{StringPresenter.php => ValuePresenter.php} (89%) create mode 100644 src/PHPSpec2/Exception/ExceptionInterface.php create mode 100644 src/PHPSpec2/Formatter/Presenter/Differ/ArrayEngine.php create mode 100644 src/PHPSpec2/Formatter/Presenter/ExceptionPresenter.php create mode 100644 src/PHPSpec2/Formatter/Presenter/ExceptionPresenterInterface.php delete mode 100644 src/PHPSpec2/Formatter/Presenter/StringPresenter.php rename src/PHPSpec2/Formatter/Presenter/{TaggedPresenter.php => TaggedValuePresenter.php} (80%) create mode 100644 src/PHPSpec2/Formatter/Presenter/ValuePresenter.php diff --git a/spec/PHPSpec2/Formatter/Presenter/ExceptionPresenter.php b/spec/PHPSpec2/Formatter/Presenter/ExceptionPresenter.php new file mode 100644 index 0000000..d94ea64 --- /dev/null +++ b/spec/PHPSpec2/Formatter/Presenter/ExceptionPresenter.php @@ -0,0 +1,79 @@ +beConstructedWith($valuePresenter, $differ); + } + + function it_should_show_the_stacktrace_of_an_exception($valuePresenter) + { + $exc = new Exception('personal Exception'); + $valuePresenter->presentValue->willReturn('personal Exception'); + $valuePresenter->presentValue->willReturn('"stacktrace"'); + + $this->presentExceptionStackTrace($exc)->shouldBeLike(' + 0 spec/PHPSpec2/Formatter/Presenter/ExceptionPresenter.php:23 + throw new PHPSpec2\Exception\Exception(personal Exception) + 1 [internal] + spec\PHPSpec2\Formatter\Presenter\ExceptionPresenter->it_should_show_the_stacktrace_of_an_exception("stacktrace") +'); + } + + function it_should_return_a_string_for_different_kind_of_exception($valuePresenter, $mockerException) + { + throw new \PHPSpec2\Exception\Example\PendingException('Error here, "PHP Fatal error: Call to undefined method Mockery\Exception::setCause() in Formatter/PrettyFormatter.php on line 129"'); + $mockerException->beAMockOf('\PHPSpec2\Exception\Example\MockerException'); + $mockerException->beConstructedWith('Message'); + + $mockerException->setCause('a'); + $mockerException->getCode->willReturn(array()); + $mockerException->getTrace->willReturn(array()); + $mockerException->getFile->willReturn('filename'); + $mockerException->getLine->willReturn(23); + + $valuePresenter->presentValue->willReturn($mockerException); + $this->presentException($mockerException, false)->shuldReturn('AA'); + } + + function it_should_compare_the_exception_with_diff($differ) + { + $actual = new Exception(); + $expected = new Exception(); + + $notEqualException = new NotEqualException('message', $actual, $expected); + + $differ->compare($actual, $expected)->shouldBeCalled(); + $this->presentExceptionDifference($notEqualException)->shouldReturn(null); + } + + + function it_should_show_the_trace_function($valuePresenter) + { + $valuePresenter->presentValue->willReturn('2'); + $this->presentExceptionTraceFunction('function', array('2'))->shouldBeLike(" function(2)\n"); + } + + + function it_should_show_the_trace_method($valuePresenter) + { + $valuePresenter->presentValue->willReturn('3'); + $this->presentExceptionTraceMethod('class', 'type', 'method', array('3'))->shouldBeLike(" classtypemethod(3)\n"); + } + + + + +} diff --git a/spec/PHPSpec2/Formatter/Presenter/TaggedPresenter.php b/spec/PHPSpec2/Formatter/Presenter/TaggedValuePresenter.php similarity index 63% rename from spec/PHPSpec2/Formatter/Presenter/TaggedPresenter.php rename to spec/PHPSpec2/Formatter/Presenter/TaggedValuePresenter.php index f5ca42c..6a5dee0 100644 --- a/spec/PHPSpec2/Formatter/Presenter/TaggedPresenter.php +++ b/spec/PHPSpec2/Formatter/Presenter/TaggedValuePresenter.php @@ -4,16 +4,8 @@ use PHPSpec2\ObjectBehavior; -class TaggedPresenter extends ObjectBehavior +class TaggedValuePresenter extends ObjectBehavior { - /** - * @param PHPSpec2\Formatter\Presenter\Differ\Differ $differ - */ - function let($differ) - { - $this->beConstructedWith($differ); - } - function it_should_wrap_value_into_tags() { $this->presentValue('string')->shouldReturn('"string"'); diff --git a/spec/PHPSpec2/Formatter/Presenter/StringPresenter.php b/spec/PHPSpec2/Formatter/Presenter/ValuePresenter.php similarity index 89% rename from spec/PHPSpec2/Formatter/Presenter/StringPresenter.php rename to spec/PHPSpec2/Formatter/Presenter/ValuePresenter.php index 8d9f79f..1d09ef3 100644 --- a/spec/PHPSpec2/Formatter/Presenter/StringPresenter.php +++ b/spec/PHPSpec2/Formatter/Presenter/ValuePresenter.php @@ -4,15 +4,8 @@ use PHPSpec2\ObjectBehavior; -class StringPresenter extends ObjectBehavior +class ValuePresenter extends ObjectBehavior { - /** - * @param PHPSpec2\Formatter\Presenter\Differ\Differ $differ - */ - function let($differ) - { - $this->beConstructedWith($differ); - } function it_should_present_short_string_in_quotes() { @@ -56,14 +49,14 @@ function it_should_present_closure_as_type() $this->presentValue(function(){})->shouldReturn('[closure]'); } - function it_should_present_exception_as_class_with_constructor() + function it_should_present_string_as_string() { - $this->presentValue(new \RuntimeException('message')) - ->shouldReturn('[exc:RuntimeException("message")]'); + $this->presentString('some string')->shouldReturn('some string'); } - function it_should_present_string_as_string() + function it_should_present_exception_as_class_with_constructor() { - $this->presentString('some string')->shouldReturn('some string'); + $this->presentValue(new \RuntimeException('message')) + ->shouldReturn('[exc:RuntimeException("message")]'); } } diff --git a/spec/PHPSpec2/Matcher/ComparisonMatcher.php b/spec/PHPSpec2/Matcher/ComparisonMatcher.php index f36a333..f70e5b3 100644 --- a/spec/PHPSpec2/Matcher/ComparisonMatcher.php +++ b/spec/PHPSpec2/Matcher/ComparisonMatcher.php @@ -8,7 +8,7 @@ class ComparisonMatcher extends ObjectBehavior { /** - * @param PHPSpec2\Formatter\Presenter\StringPresenter $presenter + * @param PHPSpec2\Formatter\Presenter\ValuePresenter $presenter */ function let($presenter) { diff --git a/spec/PHPSpec2/Matcher/CountMatcher.php b/spec/PHPSpec2/Matcher/CountMatcher.php index a6baf59..e8ca36e 100644 --- a/spec/PHPSpec2/Matcher/CountMatcher.php +++ b/spec/PHPSpec2/Matcher/CountMatcher.php @@ -8,7 +8,7 @@ class CountMatcher extends ObjectBehavior { /** - * @param PHPSpec2\Formatter\Presenter\StringPresenter $presenter + * @param PHPSpec2\Formatter\Presenter\ValuePresenter $presenter */ function let($presenter) { diff --git a/spec/PHPSpec2/Matcher/IdentityMatcher.php b/spec/PHPSpec2/Matcher/IdentityMatcher.php index e3818a2..2965559 100644 --- a/spec/PHPSpec2/Matcher/IdentityMatcher.php +++ b/spec/PHPSpec2/Matcher/IdentityMatcher.php @@ -8,7 +8,7 @@ class IdentityMatcher extends ObjectBehavior { /** - * @param PHPSpec2\Formatter\Presenter\StringPresenter $presenter + * @param PHPSpec2\Formatter\Presenter\ValuePresenter $presenter */ function let($presenter) { diff --git a/spec/PHPSpec2/Matcher/ObjectStateMatcher.php b/spec/PHPSpec2/Matcher/ObjectStateMatcher.php index 1915234..62742e4 100644 --- a/spec/PHPSpec2/Matcher/ObjectStateMatcher.php +++ b/spec/PHPSpec2/Matcher/ObjectStateMatcher.php @@ -7,7 +7,7 @@ class ObjectStateMatcher extends ObjectBehavior { /** - * @param PHPSpec2\Formatter\Presenter\StringPresenter $presenter + * @param PHPSpec2\Formatter\Presenter\ValuePresenter $presenter */ function let($presenter) { diff --git a/spec/PHPSpec2/Matcher/ScalarMatcher.php b/spec/PHPSpec2/Matcher/ScalarMatcher.php index f52289d..d934c3d 100644 --- a/spec/PHPSpec2/Matcher/ScalarMatcher.php +++ b/spec/PHPSpec2/Matcher/ScalarMatcher.php @@ -7,7 +7,7 @@ class ScalarMatcher extends ObjectBehavior { /** - * @param PHPSpec2\Formatter\Presenter\StringPresenter $presenter + * @param PHPSpec2\Formatter\Presenter\ValuePresenter $presenter */ public function let($presenter) { diff --git a/spec/PHPSpec2/Matcher/TypeMatcher.php b/spec/PHPSpec2/Matcher/TypeMatcher.php index 76d07e6..9a17b7d 100644 --- a/spec/PHPSpec2/Matcher/TypeMatcher.php +++ b/spec/PHPSpec2/Matcher/TypeMatcher.php @@ -8,7 +8,7 @@ class TypeMatcher extends ObjectBehavior { /** - * @param PHPSpec2\Formatter\Presenter\StringPresenter $presenter + * @param PHPSpec2\Formatter\Presenter\ValuePresenter $presenter */ function let($presenter) { diff --git a/src/PHPSpec2/Console/Application.php b/src/PHPSpec2/Console/Application.php index 234f188..5ff5fa9 100644 --- a/src/PHPSpec2/Console/Application.php +++ b/src/PHPSpec2/Console/Application.php @@ -76,8 +76,18 @@ public function __construct($version) })) ); + $c->extend('differ.engines', + $c->set('differ.engines.array', $c->share(function($c) { + return new Presenter\Differ\ArrayEngine(); + })) + ); + $c->set('value_presenter', $c->share(function($c) { - return new Presenter\TaggedPresenter($c('differ')); + return new Presenter\TaggedValuePresenter(); + })); + + $c->set('exception_presenter', $c->share(function($c) { + return new Presenter\ExceptionPresenter($c('value_presenter'), $c('differ')); })); $c->set('mocker', $c->share(function($c) { @@ -103,7 +113,7 @@ public function __construct($version) } $formatter->setIO($c('io')); - $formatter->setPresenter($c('value_presenter')); + $formatter->setExceptionPresenter($c('exception_presenter')); $formatter->setStatisticsCollector($c('statistics_collector')); return $formatter; diff --git a/src/PHPSpec2/Exception/Exception.php b/src/PHPSpec2/Exception/Exception.php index 34e6e24..6d32dfd 100644 --- a/src/PHPSpec2/Exception/Exception.php +++ b/src/PHPSpec2/Exception/Exception.php @@ -2,6 +2,18 @@ namespace PHPSpec2\Exception; -class Exception extends \Exception +class Exception extends \Exception implements ExceptionInterface { + private $cause; + + + public function setCause($cause) + { + $this->cause = $cause; + } + + public function getCause() + { + return $this->cause; + } } diff --git a/src/PHPSpec2/Exception/ExceptionInterface.php b/src/PHPSpec2/Exception/ExceptionInterface.php new file mode 100644 index 0000000..ec0f4ce --- /dev/null +++ b/src/PHPSpec2/Exception/ExceptionInterface.php @@ -0,0 +1,9 @@ +render($renderer); + + $lines = array(); + foreach (explode("\n", $text) as $line) { + if (0 === strpos($line, '-')) { + $lines[] = sprintf('%s', $line); + } elseif (0 === strpos($line, '+')) { + $lines[] = sprintf('%s', $line); + } else { + $lines[] = $line; + } + } + + return sprintf("\n%s", implode("\n", $lines)); + } +} diff --git a/src/PHPSpec2/Formatter/Presenter/ExceptionPresenter.php b/src/PHPSpec2/Formatter/Presenter/ExceptionPresenter.php new file mode 100644 index 0000000..ba487ce --- /dev/null +++ b/src/PHPSpec2/Formatter/Presenter/ExceptionPresenter.php @@ -0,0 +1,180 @@ +valuePresenter = $valuePresenter; + $this->differ = $differ; + } + + public function presentException(Exception $exception, $verbose = false) + { + $presentation = sprintf('Exception %s has been thrown.', $this->getValuePresenter()->presentValue($exception)); + + if ($exception instanceof Exception) { + $presentation = wordwrap($exception->getMessage(), 120); + } + + if (!$verbose || $exception instanceof PendingException) { + + return $presentation; + } + + if ($exception instanceof NotEqualException) { + if ($diff = $this->presentExceptionDifference($exception)) { + return $presentation . "\n" . $diff; + } + } + + if ($exception instanceof MockerException) { + return $exception->getMessage(); + } + + if ($exception instanceof Exception) { + list($file, $line) = $this->getExceptionExamplePosition($exception); + + return $presentation . "\n" . $this->getValuePresenter()->presentFileCode($file, $line); + } + + if (trim($trace = $this->presentExceptionStackTrace($exception))) { + return $presentation . "\n" . $trace; + } + return $presentation; + } + + + public function presentExceptionDifference(Exception $exception) + { + return $this->getDiffer()->compare($exception->getExpected(), $exception->getActual()); + } + + public function presentExceptionStackTrace(Exception $exception) + { + $phpspecPath = dirname(dirname(__DIR__)); + $runnerPath = $phpspecPath . DIRECTORY_SEPARATOR . 'Runner'; + + $offset = 0; + $text = "\n"; + + $text .= $this->presentExceptionTraceHeader(sprintf("%2d %s:%d", + $offset++, + str_replace(getcwd() . DIRECTORY_SEPARATOR, '', $exception->getFile()), + $exception->getLine() + )); + $text .= $this->presentExceptionTraceFunction( + 'throw new ' . get_class($exception), array($exception->getMessage()) + ); + + foreach ($exception->getTrace() as $call) { + // skip internal framework calls + if (isset($call['file']) && false !== strpos($call['file'], $runnerPath)) { + break; + } + if (isset($call['file']) && 0 === strpos($call['file'], $phpspecPath)) { + continue; + } + if (isset($call['class']) && 0 === strpos($call['class'], "PHPSpec2\\")) { + continue; + } + + if (isset($call['file'])) { + $text .= $this->presentExceptionTraceHeader(sprintf("%2d %s:%d", + $offset++, + str_replace(getcwd() . DIRECTORY_SEPARATOR, '', $call['file']), + $call['line'] + )); + } else { + $text .= $this->presentExceptionTraceHeader(sprintf("%2d [internal]", $offset++)); + } + + if (isset($call['class'])) { + $text .= $this->presentExceptionTraceMethod( + $call['class'], $call['type'], $call['function'], $call['args'] + ); + } elseif (isset($call['function'])) { + $args = array_map(array($this, 'presentValue'), $call['args']); + + $text .= $this->presentExceptionTraceFunction( + $call['function'], $call['args'] + ); + } + } + + return $text; + } + + protected function presentExceptionTraceHeader($header) + { + return $header . "\n"; + } + + public function presentExceptionTraceMethod($class, $type, $method, array $args) + { + $args = array_map(array($this, 'presentValue'), $args); + + return sprintf(" %s%s%s(%s)\n", $class, $type, $method, implode(', ', $args)); + } + + protected function presentValue($value) + { + return $this->getValuePresenter()->presentValue($value); + } + + public function presentExceptionTraceFunction($function, array $args) + { + $args = array_map(array($this, 'presentValue'), $args); + + return sprintf(" %s(%s)\n", $function, implode(', ', $args)); + } + + protected function getExceptionExamplePosition(Exception $exception) + { + $refl = $exception->getCode(); + foreach ($exception->getTrace() as $call) { + if (!isset($call['file'])) { + continue; + } + + if ($refl->getFilename() === $call['file']) { + return array($call['file'], $call['line']); + } + } + + return array($exception->getFile(), $exception->getLine()); + } + + public function setDiffer($differ) + { + $this->differ = $differ; + } + + public function getDiffer() + { + return $this->differ; + } + + public function setValuePresenter($valuePresenter) + { + $this->valuePresenter = $valuePresenter; + } + + public function getValuePresenter() + { + return $this->valuePresenter; + } + +} diff --git a/src/PHPSpec2/Formatter/Presenter/ExceptionPresenterInterface.php b/src/PHPSpec2/Formatter/Presenter/ExceptionPresenterInterface.php new file mode 100644 index 0000000..a811dc4 --- /dev/null +++ b/src/PHPSpec2/Formatter/Presenter/ExceptionPresenterInterface.php @@ -0,0 +1,14 @@ +differ = $differ; - } - - public function presentValue($value) - { - if (is_callable($value)) { - if (is_array($value)) { - return $this->presentString(sprintf( - '[%s::%s()]', get_class($value[0]), $value[1] - )); - } elseif ($value instanceof \Closure) { - return $this->presentString('[closure]'); - } else { - return $this->presentString(sprintf('[%s()]', $value)); - } - } - - if (is_object($value) && $value instanceof Exception) { - return $this->presentString(sprintf( - '[exc:%s("%s")]', get_class($value), $value->getMessage() - )); - } - - switch ($type = strtolower(gettype($value))) { - case 'null': - return $this->presentString('null'); - case 'boolean': - return $this->presentString(sprintf('%s', true === $value ? 'true' : 'false')); - case 'object': - return $this->presentString(sprintf('[obj:%s]', get_class($value))); - case 'array': - return $this->presentString(sprintf('[array:%d]', count($value))); - case 'string': - if (25 > strlen($value) && false === strpos($value, "\n")) { - return $this->presentString(sprintf('"%s"', $value)); - } - - $lines = explode("\n", $value); - return $this->presentString(sprintf('"%s"...', substr($lines[0], 0, 25))); - default: - return $this->presentString(sprintf('[%s:%s]', $type, $value)); - } - } - - public function presentException(Exception $exception, $verbose = false) - { - $presentation = sprintf('Exception %s has been thrown.', $this->presentValue($exception)); - if ($exception instanceof PHPSpec2Exception) { - $presentation = wordwrap($exception->getMessage(), 120); - } - - if (!$verbose || $exception instanceof PendingException) { - return $presentation; - } - - if ($exception instanceof NotEqualException) { - if ($diff = $this->presentExceptionDifference($exception)) { - return $presentation."\n".$diff; - } - } - - if ($exception instanceof MockerException) { - return $exception->getMessage(); - } - - if ($exception instanceof PHPSpec2Exception) { - list($file, $line) = $this->getExceptionExamplePosition($exception); - - return $presentation."\n".$this->presentFileCode($file, $line); - } - - if (trim($trace = $this->presentExceptionStackTrace($exception))) { - return $presentation."\n".$trace; - } - - return $presentation; - } - - public function presentString($string) - { - return $string; - } - - protected function presentFileCode($file, $lineno, $context = 6) - { - $lines = explode("\n", file_get_contents($file)); - $offset = max(0, $lineno - ceil($context / 2)); - $lines = array_slice($lines, $offset, $context); - - $text = "\n"; - foreach ($lines as $line) { - $offset++; - - if ($offset == $lineno) { - $text .= $this->presentHighlight(sprintf('%4d', $offset).' '.$line); - } else { - $text .= $this->presentCodeLine(sprintf('%4d', $offset), $line); - } - - $text .= "\n"; - } - - return $text; - } - - protected function presentCodeLine($number, $line) - { - return $number.' '.$line; - } - - protected function presentHighlight($line) - { - return $line; - } - - protected function presentExceptionDifference(Exception $exception) - { - return $this->differ->compare($exception->getExpected(), $exception->getActual()); - } - - protected function presentExceptionStackTrace(Exception $exception) - { - $phpspecPath = dirname(dirname(__DIR__)); - $runnerPath = $phpspecPath.DIRECTORY_SEPARATOR.'Runner'; - - $offset = 0; - $text = "\n"; - - $text .= $this->presentExceptionTraceHeader(sprintf("%2d %s:%d", - $offset++, - str_replace(getcwd().DIRECTORY_SEPARATOR, '', $exception->getFile()), - $exception->getLine() - )); - $text .= $this->presentExceptionTraceFunction( - 'throw new '.get_class($exception), array($exception->getMessage()) - ); - - foreach ($exception->getTrace() as $call) { - // skip internal framework calls - if (isset($call['file']) && false !== strpos($call['file'], $runnerPath)) { - break; - } - if (isset($call['file']) && 0 === strpos($call['file'], $phpspecPath)) { - continue; - } - if (isset($call['class']) && 0 === strpos($call['class'], "PHPSpec2\\")) { - continue; - } - - if (isset($call['file'])) { - $text .= $this->presentExceptionTraceHeader(sprintf("%2d %s:%d", - $offset++, - str_replace(getcwd().DIRECTORY_SEPARATOR, '', $call['file']), - $call['line'] - )); - } else { - $text .= $this->presentExceptionTraceHeader(sprintf("%2d [internal]", $offset++)); - } - - if (isset($call['class'])) { - $text .= $this->presentExceptionTraceMethod( - $call['class'], $call['type'], $call['function'], $call['args'] - ); - } elseif (isset($call['function'])) { - $args = array_map(array($this, 'presentValue'), $call['args']); - - $text .= $this->presentExceptionTraceFunction( - $call['function'], $call['args'] - ); - } - } - - return $text; - } - - protected function presentExceptionTraceHeader($header) - { - return $header."\n"; - } - - protected function presentExceptionTraceMethod($class, $type, $method, array $args) - { - $args = array_map(array($this, 'presentValue'), $args); - - return sprintf(" %s%s%s(%s)\n", $class, $type, $method, implode(', ', $args)); - } - - protected function presentExceptionTraceFunction($function, array $args) - { - $args = array_map(array($this, 'presentValue'), $args); - - return sprintf(" %s(%s)\n", $function, implode(', ', $args)); - } - - protected function getExceptionExamplePosition(Exception $exception) - { - $refl = $exception->cause; - foreach ($exception->getTrace() as $call) { - if (!isset($call['file'])) { - continue; - } - - if ($refl->getFilename() === $call['file']) { - return array($call['file'], $call['line']); - } - } - - return array($exception->getFile(), $exception->getLine()); - } -} diff --git a/src/PHPSpec2/Formatter/Presenter/TaggedPresenter.php b/src/PHPSpec2/Formatter/Presenter/TaggedValuePresenter.php similarity index 80% rename from src/PHPSpec2/Formatter/Presenter/TaggedPresenter.php rename to src/PHPSpec2/Formatter/Presenter/TaggedValuePresenter.php index ac80828..740f2ab 100644 --- a/src/PHPSpec2/Formatter/Presenter/TaggedPresenter.php +++ b/src/PHPSpec2/Formatter/Presenter/TaggedValuePresenter.php @@ -2,11 +2,11 @@ namespace PHPSpec2\Formatter\Presenter; -class TaggedPresenter extends StringPresenter +class TaggedValuePresenter extends ValuePresenter { public function presentString($string) { - return ''.parent::presentString($string).''; + return '' . parent::presentString($string) . ''; } protected function presentCodeLine($number, $line) @@ -16,7 +16,7 @@ protected function presentCodeLine($number, $line) protected function presentHighlight($line) { - return ''.$line.''; + return '' . $line . ''; } protected function presentExceptionTraceHeader($header) @@ -29,8 +29,8 @@ protected function presentExceptionTraceMethod($class, $type, $method, array $ar $args = array_map(array($this, 'presentValue'), $args); return sprintf( - " %s%s". - "%s(%s)\n", + " %s%s" . + "%s(%s)\n", $class, $type, $method, implode(', ', $args) ); } diff --git a/src/PHPSpec2/Formatter/Presenter/ValuePresenter.php b/src/PHPSpec2/Formatter/Presenter/ValuePresenter.php new file mode 100644 index 0000000..07c4b17 --- /dev/null +++ b/src/PHPSpec2/Formatter/Presenter/ValuePresenter.php @@ -0,0 +1,93 @@ +presentString(sprintf( + '[%s::%s()]', get_class($value[0]), $value[1] + )); + } elseif ($value instanceof \Closure) { + return $this->presentString('[closure]'); + } else { + return $this->presentString(sprintf('[%s()]', $value)); + } + } + + if (is_object($value) && $value instanceof Exception) { + return $this->presentString(sprintf( + '[exc:%s("%s")]', get_class($value), $value->getMessage() + )); + } + + switch ($type = strtolower(gettype($value))) { + case 'null': + return $this->presentString('null'); + case 'boolean': + return $this->presentString(sprintf('%s', true === $value ? 'true' : 'false')); + case 'object': + return $this->presentString(sprintf('[obj:%s]', get_class($value))); + case 'array': + return $this->presentString(sprintf('[array:%d]', count($value))); + case 'string': + if (25 > strlen($value) && false === strpos($value, "\n")) { + return $this->presentString(sprintf('"%s"', $value)); + } + + $lines = explode("\n", $value); + return $this->presentString(sprintf('"%s"...', substr($lines[0], 0, 25))); + default: + return $this->presentString(sprintf('[%s:%s]', $type, $value)); + } + } + + public function presentFileCode($file, $lineno, $context = 6) + { + $lines = explode("\n", file_get_contents($file)); + $offset = max(0, $lineno - ceil($context / 2)); + $lines = array_slice($lines, $offset, $context); + + $text = "\n"; + foreach ($lines as $line) { + $offset++; + + if ($offset == $lineno) { + $text .= $this->presentHighlight(sprintf('%4d', $offset).' '.$line); + } else { + $text .= $this->presentCodeLine(sprintf('%4d', $offset), $line); + } + + $text .= "\n"; + } + + return $text; + } + + public function presentString($string) + { + return $string; + } + + protected function presentCodeLine($number, $line) + { + return $number.' '.$line; + } + + protected function presentHighlight($line) + { + return $line; + } + +} diff --git a/src/PHPSpec2/Formatter/PrettyFormatter.php b/src/PHPSpec2/Formatter/PrettyFormatter.php index 892c3cf..7317863 100644 --- a/src/PHPSpec2/Formatter/PrettyFormatter.php +++ b/src/PHPSpec2/Formatter/PrettyFormatter.php @@ -3,7 +3,7 @@ namespace PHPSpec2\Formatter; use PHPSpec2\Console\IO; -use PHPSpec2\Formatter\Presenter\PresenterInterface; +use PHPSpec2\Formatter\Presenter\ExceptionPresenterInterface; use PHPSpec2\Listener\StatisticsCollector; use PHPSpec2\Event\SuiteEvent; @@ -13,7 +13,7 @@ class PrettyFormatter implements FormatterInterface { private $io; - private $presenter; + private $exceptionPresenter; private $stats; public static function getSubscribedEvents() @@ -28,9 +28,9 @@ public function setIO(IO $io) $this->io = $io; } - public function setPresenter(PresenterInterface $presenter) + public function setExceptionPresenter(ExceptionPresenterInterface $exceptionPresenter) { - $this->presenter = $presenter; + $this->exceptionPresenter = $exceptionPresenter; } public function setStatisticsCollector(StatisticsCollector $stats) @@ -126,10 +126,9 @@ protected function printException(ExampleEvent $event, $depth = null) return; } - // TODO: add cause to exception interface - $exception->cause = $event->getExample()->getFunction(); + $exception->setCause($event->getExample()->getFunction()); $depth = $depth ?: (($event->getExample()->getDepth() * 2) + 6); - $message = $this->presenter->presentException($exception, $this->io->isVerbose()); + $message = $this->exceptionPresenter->presentException($exception, $this->io->isVerbose()); if (ExampleEvent::FAILED === $event->getResult()) { $this->io->writeln(sprintf('%s', lcfirst($message)), $depth); diff --git a/src/PHPSpec2/Formatter/ProgressFormatter.php b/src/PHPSpec2/Formatter/ProgressFormatter.php index 6a5b7e1..762e640 100644 --- a/src/PHPSpec2/Formatter/ProgressFormatter.php +++ b/src/PHPSpec2/Formatter/ProgressFormatter.php @@ -3,7 +3,7 @@ namespace PHPSpec2\Formatter; use PHPSpec2\Console\IO; -use PHPSpec2\Formatter\Presenter\PresenterInterface; +use PHPSpec2\Formatter\Presenter\ExceptionPresenterInterface; use PHPSpec2\Listener\StatisticsCollector; use PHPSpec2\Event\SuiteEvent; @@ -29,9 +29,9 @@ public function setIO(IO $io) $this->io = $io; } - public function setPresenter(PresenterInterface $presenter) + public function setExceptionPresenter(ExceptionPresenterInterface $presenter) { - $this->presenter = $presenter; + $this->exceptionPresenter = $exceptionPresenter; } public function setStatisticsCollector(StatisticsCollector $stats) @@ -112,8 +112,8 @@ protected function printException(ExampleEvent $event) $title = str_replace('\\', DIRECTORY_SEPARATOR, $event->getSpecification()->getTitle()); $title = str_pad($title, 50, ' ', STR_PAD_RIGHT); - $exception->cause = $event->getExample()->getFunction(); - $message = $this->presenter->presentException($exception, $this->io->isVerbose()); + $exception->setCause($event->getExample()->getFunction()); + $message = $this->exceptionPresenter->presentException($exception, $this->io->isVerbose()); if ($exception instanceof PendingException) { $this->io->writeln(sprintf('%s', $title)); From 40ccc43891fa4a6459d6999db4950197ecd8552f Mon Sep 17 00:00:00 2001 From: Giulio De Donato Date: Thu, 17 Jan 2013 14:54:14 +0100 Subject: [PATCH 2/2] fixed copy/paste problem --- src/PHPSpec2/Formatter/ProgressFormatter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PHPSpec2/Formatter/ProgressFormatter.php b/src/PHPSpec2/Formatter/ProgressFormatter.php index 762e640..a131d14 100644 --- a/src/PHPSpec2/Formatter/ProgressFormatter.php +++ b/src/PHPSpec2/Formatter/ProgressFormatter.php @@ -14,7 +14,7 @@ class ProgressFormatter implements FormatterInterface { private $io; - private $presenter; + private $exceptionPresenter; private $stats; public static function getSubscribedEvents() @@ -29,7 +29,7 @@ public function setIO(IO $io) $this->io = $io; } - public function setExceptionPresenter(ExceptionPresenterInterface $presenter) + public function setExceptionPresenter(ExceptionPresenterInterface $exceptionPresenter) { $this->exceptionPresenter = $exceptionPresenter; }