Completed
Pull Request — master (#78)
by Christophe
03:11
created

SharedSessionStrategy   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 160
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 97.62%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 17
c 4
b 0
f 0
lcom 1
cbo 5
dl 0
loc 160
ccs 41
cts 42
cp 0.9762
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setEventDispatcher() 0 4 1
A _switchToMainWindow() 0 4 1
A _isEventForMe() 0 4 1
A stopSession() 0 9 2
A onTestFailed() 0 11 3
A getSubscribedEvents() 0 7 1
A session() 0 16 3
A onTestSuiteEnd() 0 12 4
1
<?php
2
/**
3
 * This file is part of the phpunit-mink library.
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 *
7
 * @copyright Alexander Obuhovich <[email protected]>
8
 * @link      https://github.com/aik099/phpunit-mink
9
 */
10
11
namespace aik099\PHPUnit\Session;
12
13
14
use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration;
15
use aik099\PHPUnit\BrowserTestCase;
16
use aik099\PHPUnit\Event\TestEvent;
17
use aik099\PHPUnit\Event\TestFailedEvent;
18
use Behat\Mink\Session;
19
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
20
21
/**
22
 * Keeps a Session object shared between test runs to save time.
23
 *
24
 * @method \Mockery\Expectation shouldReceive(string $name)
25
 */
26
class SharedSessionStrategy implements ISessionStrategy
27
{
28
29
	/**
30
	 * Original session strategy.
31
	 *
32
	 * @var ISessionStrategy
33
	 */
34
	private $_originalStrategy;
35
36
	/**
37
	 * Reference to created session.
38
	 *
39
	 * @var Session
40
	 */
41
	private $_session;
42
43
	/**
44
	 * Remembers if last test failed.
45
	 *
46
	 * @var boolean
47
	 */
48
	private $_lastTestFailed = false;
49
50
	/**
51
	 * Remembers original session strategy upon shared strategy creation.
52
	 *
53
	 * @param ISessionStrategy $original_strategy Original session strategy.
54
	 */
55 7
	public function __construct(ISessionStrategy $original_strategy)
56
	{
57 7
		$this->_originalStrategy = $original_strategy;
58 7
	}
59
60
	/**
61
	 * Returns an array of event names this subscriber wants to listen to.
62
	 *
63
	 * @return array The event names to listen to
64
	 */
65 7
	public static function getSubscribedEvents()
66
	{
67
		return array(
68 7
			BrowserTestCase::TEST_FAILED_EVENT => array('onTestFailed', 0),
69 7
			BrowserTestCase::TEST_SUITE_ENDED_EVENT => array('onTestSuiteEnd', 0),
70
		);
71
	}
72
73
	/**
74
	 * Sets event dispatcher.
75
	 *
76
	 * @param EventDispatcherInterface $event_dispatcher Event dispatcher.
77
	 *
78
	 * @return void
79
	 */
80 7
	public function setEventDispatcher(EventDispatcherInterface $event_dispatcher)
81
	{
82 7
		$event_dispatcher->addSubscriber($this);
83 7
	}
84
85
	/**
86
	 * Returns Mink session with given browser configuration.
87
	 *
88
	 * @param BrowserConfiguration $browser Browser configuration for a session.
89
	 *
90
	 * @return Session
91
	 */
92 5
	public function session(BrowserConfiguration $browser)
93
	{
94 5
		if ( $this->_lastTestFailed ) {
95 2
			$this->stopSession();
96 2
			$this->_lastTestFailed = false;
97
		}
98
99 5
		if ( $this->_session === null ) {
100 5
			$this->_session = $this->_originalStrategy->session($browser);
101
		}
102
		else {
103 4
			$this->_switchToMainWindow();
104
		}
105
106 5
		return $this->_session;
107
	}
108
109
	/**
110
	 * Stops session.
111
	 *
112
	 * @return void
113
	 */
114 2
	protected function stopSession()
115
	{
116 2
		if ( $this->_session === null ) {
117 1
			return;
118
		}
119
120 1
		$this->_session->stop();
121 1
		$this->_session = null;
122 1
	}
123
124
	/**
125
	 * Switches to window, that was created upon session creation.
126
	 *
127
	 * @return void
128
	 */
129 4
	private function _switchToMainWindow()
130
	{
131 4
		$this->_session->switchToWindow(null);
132 4
	}
133
134
	/**
135
	 * Called, when test fails.
136
	 *
137
	 * @param TestFailedEvent $event Test failed event.
138
	 *
139
	 * @return void
140
	 */
141 4
	public function onTestFailed(TestFailedEvent $event)
142
	{
143 4
		if ( $event->getException() instanceof \PHPUnit_Framework_IncompleteTestError ) {
144 1
			return;
145
		}
146 3
		elseif ( $event->getException() instanceof \PHPUnit_Framework_SkippedTestError ) {
147 1
			return;
148
		}
149
150 2
		$this->_lastTestFailed = true;
151 2
	}
152
153
	/**
154
	 * Called, when test case ends.
155
	 *
156
	 * @param TestEvent $event Test event.
157
	 *
158
	 * @return void
159
	 */
160 1
	public function onTestSuiteEnd(TestEvent $event)
161
	{
162 1
		if ( !$this->_isEventForMe($event) ) {
163
			return;
164
		}
165
166 1
		$session = $event->getSession();
167
168 1
		if ( $session !== null && $session->isStarted() ) {
169 1
			$session->stop();
170
		}
171 1
	}
172
173
	/**
174
	 * Checks, that event can be handled by this class.
175
	 *
176
	 * @param TestEvent $event Test event.
177
	 *
178
	 * @return boolean
179
	 */
180 1
	private function _isEventForMe(TestEvent $event)
181
	{
182 1
		return $event->getTestCase()->getSessionStrategy() instanceof self;
183
	}
184
185
}
186