Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Behat / Output / Node / EventListener / Flow / OnlyFirstBackgroundFiresListener.php
1 <?php
2
3 /*
4  * This file is part of the Behat.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Behat\Output\Node\EventListener\Flow;
12
13 use Behat\Behat\EventDispatcher\Event\AfterStepSetup;
14 use Behat\Behat\EventDispatcher\Event\AfterStepTested;
15 use Behat\Behat\EventDispatcher\Event\BackgroundTested;
16 use Behat\Behat\EventDispatcher\Event\FeatureTested;
17 use Behat\Testwork\Output\Formatter;
18 use Behat\Testwork\Output\Node\EventListener\EventListener;
19 use Symfony\Component\EventDispatcher\Event;
20
21 /**
22  * Behat only first background fires listener.
23  *
24  * This listener catches all in-background events and then proxies them further
25  * only if they meet one of two conditions:
26  *
27  *   1. It is a first background
28  *   2. It is a failing step
29  *
30  * @author Konstantin Kudryashov <ever.zet@gmail.com>
31  */
32 class OnlyFirstBackgroundFiresListener implements EventListener
33 {
34     /**
35      * @var EventListener
36      */
37     private $descendant;
38     /**
39      * @var Boolean
40      */
41     private $firstBackgroundEnded = false;
42     /**
43      * @var Boolean
44      */
45     private $inBackground = false;
46     /**
47      * @var Boolean
48      */
49     private $stepSetupHadOutput = false;
50
51     /**
52      * Initializes listener.
53      *
54      * @param EventListener $descendant
55      */
56     public function __construct(EventListener $descendant)
57     {
58         $this->descendant = $descendant;
59     }
60
61     /**
62      * {@inheritdoc}
63      */
64     public function listenEvent(Formatter $formatter, Event $event, $eventName)
65     {
66         $this->flushStatesIfBeginningOfTheFeature($eventName);
67         $this->markBeginningOrEndOfTheBackground($eventName);
68
69         if ($this->isSkippableEvent($event)) {
70             return;
71         }
72
73         $this->markFirstBackgroundPrintedAfterBackground($eventName);
74
75         $this->descendant->listenEvent($formatter, $event, $eventName);
76     }
77
78     /**
79      * Flushes state if the event is the BEFORE feature.
80      *
81      * @param string $eventName
82      */
83     private function flushStatesIfBeginningOfTheFeature($eventName)
84     {
85         if (FeatureTested::BEFORE !== $eventName) {
86             return;
87         }
88
89         $this->firstBackgroundEnded = false;
90         $this->inBackground = false;
91     }
92
93     /**
94      * Marks beginning or end of the background.
95      *
96      * @param string $eventName
97      */
98     private function markBeginningOrEndOfTheBackground($eventName)
99     {
100         if (BackgroundTested::BEFORE === $eventName) {
101             $this->inBackground = true;
102         }
103
104         if (BackgroundTested::AFTER === $eventName) {
105             $this->inBackground = false;
106         }
107     }
108
109     /**
110      * Marks first background printed.
111      *
112      * @param string $eventName
113      */
114     private function markFirstBackgroundPrintedAfterBackground($eventName)
115     {
116         if (BackgroundTested::AFTER !== $eventName) {
117             return;
118         }
119
120         $this->firstBackgroundEnded = true;
121     }
122
123     /**
124      * Checks if provided event is skippable.
125      *
126      * @param Event $event
127      *
128      * @return Boolean
129      */
130     private function isSkippableEvent(Event $event)
131     {
132         if (!$this->firstBackgroundEnded) {
133             return false;
134         }
135
136         return $event instanceof BackgroundTested || $this->isNonFailingConsequentBackgroundStep($event);
137     }
138
139     /**
140      * Checks if provided event is a non-failing step in consequent background.
141      *
142      * @param Event $event
143      *
144      * @return Boolean
145      */
146     private function isNonFailingConsequentBackgroundStep(Event $event)
147     {
148         if (!$this->inBackground) {
149             return false;
150         }
151
152         return !$this->isStepEventWithOutput($event);
153     }
154
155     /**
156      * Checks if provided event is a step event which setup or teardown produced any output.
157      *
158      * @param Event $event
159      *
160      * @return Boolean
161      */
162     private function isStepEventWithOutput(Event $event)
163     {
164         return $this->isBeforeStepEventWithOutput($event) || $this->isAfterStepWithOutput($event);
165     }
166
167     /**
168      * Checks if provided event is a BEFORE step with setup that produced output.
169      *
170      * @param Event $event
171      *
172      * @return Boolean
173      */
174     private function isBeforeStepEventWithOutput(Event $event)
175     {
176         if ($event instanceof AfterStepSetup && $event->hasOutput()) {
177             $this->stepSetupHadOutput = true;
178
179             return true;
180         }
181
182         return false;
183     }
184
185     /**
186      * Checks if provided event is an AFTER step with teardown that produced output.
187      *
188      * @param Event $event
189      *
190      * @return Boolean
191      */
192     private function isAfterStepWithOutput(Event $event)
193     {
194         if ($event instanceof AfterStepTested && ($this->stepSetupHadOutput || $event->hasOutput())) {
195             $this->stepSetupHadOutput = false;
196
197             return true;
198         }
199
200         return false;
201     }
202 }