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\EventListener\AST;
13 use Behat\Behat\EventDispatcher\Event\AfterOutlineTested;
14 use Behat\Behat\EventDispatcher\Event\AfterScenarioSetup;
15 use Behat\Behat\EventDispatcher\Event\AfterScenarioTested;
16 use Behat\Behat\EventDispatcher\Event\AfterStepSetup;
17 use Behat\Behat\EventDispatcher\Event\AfterStepTested;
18 use Behat\Behat\EventDispatcher\Event\BeforeOutlineTested;
19 use Behat\Behat\EventDispatcher\Event\ExampleTested;
20 use Behat\Behat\EventDispatcher\Event\OutlineTested;
21 use Behat\Behat\EventDispatcher\Event\StepTested;
22 use Behat\Behat\Output\Node\Printer\ExampleRowPrinter;
23 use Behat\Behat\Output\Node\Printer\OutlineTablePrinter;
24 use Behat\Behat\Output\Node\Printer\SetupPrinter;
25 use Behat\Behat\Tester\Result\StepResult;
26 use Behat\Gherkin\Node\OutlineNode;
27 use Behat\Testwork\Output\Formatter;
28 use Behat\Testwork\Output\Node\EventListener\EventListener;
29 use Behat\Testwork\Tester\Setup\Setup;
30 use Symfony\Component\EventDispatcher\Event;
33 * Listens to outline table events and calls appropriate printers.
35 * @author Konstantin Kudryashov <ever.zet@gmail.com>
37 final class OutlineTableListener implements EventListener
40 * @var OutlineTablePrinter
42 private $tablePrinter;
44 * @var ExampleRowPrinter
46 private $exampleRowPrinter;
50 private $stepSetupPrinter;
54 private $exampleSetupPrinter;
62 private $exampleSetup;
66 private $headerPrinted = false;
68 * @var AfterStepSetup[]
70 private $stepBeforeTestedEvents = array();
72 * @var AfterStepTested[]
74 private $stepAfterTestedEvents = array();
77 * Initializes listener.
79 * @param OutlineTablePrinter $tablePrinter
80 * @param ExampleRowPrinter $exampleRowPrinter
81 * @param SetupPrinter $exampleSetupPrinter
82 * @param SetupPrinter $stepSetupPrinter
84 public function __construct(
85 OutlineTablePrinter $tablePrinter,
86 ExampleRowPrinter $exampleRowPrinter,
87 SetupPrinter $exampleSetupPrinter,
88 SetupPrinter $stepSetupPrinter
90 $this->tablePrinter = $tablePrinter;
91 $this->exampleRowPrinter = $exampleRowPrinter;
92 $this->exampleSetupPrinter = $exampleSetupPrinter;
93 $this->stepSetupPrinter = $stepSetupPrinter;
99 public function listenEvent(Formatter $formatter, Event $event, $eventName)
101 if ($event instanceof StepTested) {
102 $this->captureStepEvent($event);
107 $this->captureOutlineOnBeforeOutlineEvent($event);
108 $this->forgetOutlineOnAfterOutlineEvent($eventName);
109 $this->captureExampleSetupOnBeforeEvent($event);
111 $this->printHeaderOnAfterExampleEvent($formatter, $event, $eventName);
112 $this->printExampleRowOnAfterExampleEvent($formatter, $event, $eventName);
113 $this->printFooterOnAfterEvent($formatter, $event);
117 * Captures step tested event.
119 * @param StepTested $event
121 private function captureStepEvent(StepTested $event)
123 if ($event instanceof AfterStepSetup) {
124 $this->stepBeforeTestedEvents[$event->getStep()->getLine()] = $event;
126 $this->stepAfterTestedEvents[$event->getStep()->getLine()] = $event;
131 * Captures outline into the ivar on outline BEFORE event.
133 * @param Event $event
135 private function captureOutlineOnBeforeOutlineEvent(Event $event)
137 if (!$event instanceof BeforeOutlineTested) {
141 $this->outline = $event->getOutline();
142 $this->headerPrinted = false;
146 * Captures example setup on example BEFORE event.
148 * @param Event $event
150 private function captureExampleSetupOnBeforeEvent(Event $event)
152 if (!$event instanceof AfterScenarioSetup) {
156 $this->exampleSetup = $event->getSetup();
160 * Removes outline from the ivar on outline AFTER event.
162 * @param string $eventName
164 private function forgetOutlineOnAfterOutlineEvent($eventName)
166 if (OutlineTested::AFTER !== $eventName) {
170 $this->outline = null;
174 * Prints outline header (if has not been printed yet) on example AFTER event.
176 * @param Formatter $formatter
177 * @param Event $event
178 * @param string $eventName
180 private function printHeaderOnAfterExampleEvent(Formatter $formatter, Event $event, $eventName)
182 if (!$event instanceof AfterScenarioTested || ExampleTested::AFTER !== $eventName) {
186 if ($this->headerPrinted) {
190 $feature = $event->getFeature();
191 $stepTestResults = $this->getStepTestResults();
193 $this->tablePrinter->printHeader($formatter, $feature, $this->outline, $stepTestResults);
194 $this->headerPrinted = true;
198 * Prints example row on example AFTER event.
200 * @param Formatter $formatter
201 * @param Event $event
202 * @param string $eventName
204 private function printExampleRowOnAfterExampleEvent(Formatter $formatter, Event $event, $eventName)
206 if (!$event instanceof AfterScenarioTested || ExampleTested::AFTER !== $eventName) {
210 $example = $event->getScenario();
212 $this->exampleSetupPrinter->printSetup($formatter, $this->exampleSetup);
214 foreach ($this->stepBeforeTestedEvents as $beforeEvent) {
215 $this->stepSetupPrinter->printSetup($formatter, $beforeEvent->getSetup());
218 $this->exampleRowPrinter->printExampleRow($formatter, $this->outline, $example, $this->stepAfterTestedEvents);
220 foreach ($this->stepAfterTestedEvents as $afterEvent) {
221 $this->stepSetupPrinter->printTeardown($formatter, $afterEvent->getTeardown());
224 $this->exampleSetupPrinter->printTeardown($formatter, $event->getTeardown());
226 $this->exampleSetup = null;
227 $this->stepBeforeTestedEvents = array();
228 $this->stepAfterTestedEvents = array();
232 * Prints outline footer on outline AFTER event.
234 * @param Formatter $formatter
235 * @param Event $event
237 private function printFooterOnAfterEvent(Formatter $formatter, Event $event)
239 if (!$event instanceof AfterOutlineTested) {
243 $this->tablePrinter->printFooter($formatter, $event->getTestResult());
247 * Returns currently captured step events results.
249 * @return StepResult[]
251 private function getStepTestResults()
254 function (AfterStepTested $event) {
255 return $event->getTestResult();
257 $this->stepAfterTestedEvents