4 * This file is part of the Behat.
5 * (c) Konstantin Kudryashov <ever.zet@gmail.com>
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
11 namespace Behat\Behat\Output\Node\Printer\Pretty;
13 use Behat\Behat\EventDispatcher\Event\AfterStepTested;
14 use Behat\Behat\Output\Node\Printer\ExampleRowPrinter;
15 use Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter;
16 use Behat\Behat\Tester\Result\ExecutedStepResult;
17 use Behat\Behat\Tester\Result\StepResult;
18 use Behat\Gherkin\Node\ExampleNode;
19 use Behat\Gherkin\Node\OutlineNode;
20 use Behat\Testwork\EventDispatcher\Event\AfterTested;
21 use Behat\Testwork\Exception\ExceptionPresenter;
22 use Behat\Testwork\Output\Formatter;
23 use Behat\Testwork\Output\Printer\OutputPrinter;
24 use Behat\Testwork\Tester\Result\ExceptionResult;
25 use Behat\Testwork\Tester\Result\TestResults;
28 * Prints example results in form of a table row.
30 * @author Konstantin Kudryashov <ever.zet@gmail.com>
32 final class PrettyExampleRowPrinter implements ExampleRowPrinter
35 * @var ResultToStringConverter
37 private $resultConverter;
39 * @var ExceptionPresenter
41 private $exceptionPresenter;
49 private $subIndentText;
52 * Initializes printer.
54 * @param ResultToStringConverter $resultConverter
55 * @param ExceptionPresenter $exceptionPresenter
56 * @param integer $indentation
57 * @param integer $subIndentation
59 public function __construct(
60 ResultToStringConverter $resultConverter,
61 ExceptionPresenter $exceptionPresenter,
65 $this->resultConverter = $resultConverter;
66 $this->exceptionPresenter = $exceptionPresenter;
67 $this->indentText = str_repeat(' ', intval($indentation));
68 $this->subIndentText = $this->indentText . str_repeat(' ', intval($subIndentation));
74 public function printExampleRow(Formatter $formatter, OutlineNode $outline, ExampleNode $example, array $events)
76 $rowNum = array_search($example, $outline->getExamples()) + 1;
77 $wrapper = $this->getWrapperClosure($outline, $example, $events);
78 $row = $outline->getExampleTable()->getRowAsStringWithWrappedValues($rowNum, $wrapper);
80 $formatter->getOutputPrinter()->writeln(sprintf('%s%s', $this->indentText, $row));
81 $this->printStepExceptionsAndStdOut($formatter->getOutputPrinter(), $events);
85 * Creates wrapper-closure for the example table.
87 * @param OutlineNode $outline
88 * @param ExampleNode $example
89 * @param AfterStepTested[] $stepEvents
93 private function getWrapperClosure(OutlineNode $outline, ExampleNode $example, array $stepEvents)
95 $resultConverter = $this->resultConverter;
97 return function ($value, $column) use ($outline, $example, $stepEvents, $resultConverter) {
99 foreach ($stepEvents as $event) {
100 $index = array_search($event->getStep(), $example->getSteps());
101 $header = $outline->getExampleTable()->getRow(0);
102 $steps = $outline->getSteps();
103 $outlineStepText = $steps[$index]->getText();
105 if (false !== strpos($outlineStepText, '<' . $header[$column] . '>')) {
106 $results[] = $event->getTestResult();
110 $result = new TestResults($results);
111 $style = $resultConverter->convertResultToString($result);
113 return sprintf('{+%s}%s{-%s}', $style, $value, $style);
118 * Prints step events exceptions (if has some).
120 * @param OutputPrinter $printer
121 * @param AfterTested[] $events
123 private function printStepExceptionsAndStdOut(OutputPrinter $printer, array $events)
125 foreach ($events as $event) {
126 $this->printStepStdOut($printer, $event->getTestResult());
127 $this->printStepException($printer, $event->getTestResult());
132 * Prints step exception (if has one).
134 * @param OutputPrinter $printer
135 * @param StepResult $result
137 private function printStepException(OutputPrinter $printer, StepResult $result)
139 $style = $this->resultConverter->convertResultToString($result);
141 if (!$result instanceof ExceptionResult || !$result->hasException()) {
145 $text = $this->exceptionPresenter->presentException($result->getException());
146 $indentedText = implode("\n", array_map(array($this, 'subIndent'), explode("\n", $text)));
147 $printer->writeln(sprintf('{+%s}%s{-%s}', $style, $indentedText, $style));
151 * Prints step output (if has one).
153 * @param OutputPrinter $printer
154 * @param StepResult $result
156 private function printStepStdOut(OutputPrinter $printer, StepResult $result)
158 if (!$result instanceof ExecutedStepResult || null === $result->getCallResult()->getStdOut()) {
162 $callResult = $result->getCallResult();
163 $indentedText = $this->subIndentText;
165 $pad = function ($line) use ($indentedText) {
167 '%s│ {+stdout}%s{-stdout}', $indentedText, $line
171 $printer->writeln(implode("\n", array_map($pad, explode("\n", $callResult->getStdOut()))));
175 * Indents text to the subIndentation level.
177 * @param string $text
181 private function subIndent($text)
183 return $this->subIndentText . $text;