93% of 754OPs |
98% of 144Lines |
86% of 110Branches |
18% of 252Paths |
# | |
---|---|
1 |
<?php |
2 | |
3 |
namespace mageekguy\atoum\mock; |
4 | |
5 |
use |
6 |
mageekguy\atoum, |
7 |
mageekguy\atoum\mock, |
8 |
mageekguy\atoum\test, |
9 |
mageekguy\atoum\exceptions, |
10 |
mageekguy\atoum\test\adapter\call\decorators |
11 |
; |
12 | |
13 |
class controller extends test\adapter |
14 |
{ |
15 |
protected $mockClass = null; |
16 |
protected $mockMethods = array(); |
17 |
protected $iterator = null; |
18 |
protected $autoBind = true; |
19 | |
20 |
protected static $linker = null; |
21 |
protected static $controlNextNewMock = null; |
22 |
protected static $autoBindForNewMock = true; |
23 | |
24 |
private $disableMethodChecking = false; |
25 | |
26 |
public function __construct()100% |
27 |
{ |
28 |
parent::__construct(); |
29 | |
30 |
$this |
31 |
->setIterator() |
32 |
->controlNextNewMock() |
33 |
; |
34 | |
35 |
if (self::$autoBindForNewMock === true) |
36 |
{ |
37 |
$this->enableAutoBind(); |
38 |
} |
39 |
else |
40 |
{ |
41 |
$this->disableAutoBind(); |
42 |
} |
43 |
} |
44 | |
45 |
public function __set($method, $mixed)100% |
46 |
{ |
47 |
$this->checkMethod($method); |
48 | |
49 |
return parent::__set($method, $mixed); |
50 |
} |
51 | |
52 |
public function __get($method)100% |
53 |
{ |
54 |
$this->checkMethod($method); |
55 | |
56 |
return parent::__get($method); |
57 |
} |
58 | |
59 |
public function __isset($method)100% |
60 |
{ |
61 |
$this->checkMethod($method); |
62 | |
63 |
return parent::__isset($method); |
64 |
} |
65 | |
66 |
public function __unset($method)100% |
67 |
{ |
68 |
$this->checkMethod($method); |
69 | |
70 |
parent::__unset($method); |
71 | |
72 |
return $this->setInvoker($method); |
73 |
} |
74 | |
75 |
public function setIterator(controller\iterator $iterator = null)100% |
76 |
{ |
77 |
$this->iterator = $iterator ?: new controller\iterator(); |
78 | |
79 |
$this->iterator->setMockController($this); |
80 | |
81 |
return $this; |
82 |
} |
83 | |
84 |
public function getIterator()100% |
85 |
{ |
86 |
return $this->iterator; |
87 |
} |
88 | |
89 |
public function disableMethodChecking()100% |
90 |
{ |
91 |
$this->disableMethodChecking = true; |
92 | |
93 |
return $this; |
94 |
} |
95 | |
96 |
public function getMockClass()100% |
97 |
{ |
98 |
return $this->mockClass; |
99 |
} |
100 | |
101 |
public function getMethods()100% |
102 |
{ |
103 |
return $this->mockMethods; |
104 |
} |
105 | |
106 |
public function methods(\closure $filter = null)100% |
107 |
{ |
108 |
$this->iterator->resetFilters(); |
109 | |
110 |
if ($filter !== null) |
111 |
{ |
112 |
$this->iterator->addFilter($filter); |
113 |
} |
114 | |
115 |
return $this->iterator; |
116 |
} |
117 | |
118 |
public function methodsMatching($regex)100% |
119 |
{ |
120 |
return $this->iterator->resetFilters()->addFilter(function($name) use ($regex) { return preg_match($regex, $name); }); |
121 |
} |
122 | |
123 |
public function getCalls(test\adapter\call $call = null, $identical = false)100% |
124 |
{ |
125 |
if ($call !== null) |
126 |
{ |
127 |
$this->checkMethod($call->getFunction()); |
128 |
} |
129 | |
130 |
return parent::getCalls($call, $identical); |
131 |
} |
132 | |
133 |
public function control(mock\aggregator $mock)100% |
134 |
{ |
135 |
$currentMockController = self::$linker->getController($mock); |
136 | |
137 |
if ($currentMockController !== null && $currentMockController !== $this) |
138 |
{ |
139 |
$currentMockController->reset(); |
140 |
} |
141 | |
142 |
if ($currentMockController === null || $currentMockController !== $this) |
143 |
{ |
144 |
self::$linker->link($this, $mock); |
145 |
} |
146 | |
147 |
$this->mockClass = get_class($mock); |
148 |
$this->mockMethods = $mock->getMockedMethods(); |
149 | |
150 |
foreach (array_keys($this->invokers) as $method) |
151 |
{ |
152 |
$this->checkMethod($method); |
153 |
} |
154 | |
155 |
foreach ($this->mockMethods as $method) |
156 |
{ |
157 |
$this->{$method}->setMock($mock); |
158 | |
159 |
if ($this->autoBind === true) |
160 |
{ |
161 |
$this->{$method}->bindTo($mock); |
162 |
} |
163 |
} |
164 | |
165 |
return $this |
166 |
->resetCalls() |
167 |
->notControlNextNewMock() |
168 |
; |
169 |
} |
170 | |
171 |
public function controlNextNewMock()100% |
172 |
{ |
173 |
self::$controlNextNewMock = $this; |
174 | |
175 |
return $this; |
176 |
} |
177 | |
178 |
public function notControlNextNewMock()100% |
179 |
{ |
180 |
if (self::$controlNextNewMock === $this) |
181 |
{ |
182 |
self::$controlNextNewMock = null; |
183 |
} |
184 | |
185 |
return $this; |
186 |
} |
187 | |
188 |
public function enableAutoBind()100% |
189 |
{ |
190 |
$this->autoBind = true; |
191 | |
192 |
foreach ($this->invokers as $invoker) |
193 |
{ |
194 |
$invoker->bindTo($this->getMock()); |
195 |
} |
196 | |
197 |
return $this; |
198 |
} |
199 | |
200 |
public function disableAutoBind()100% |
201 |
{ |
202 |
$this->autoBind = false; |
203 | |
204 |
return $this->reset(); |
205 |
} |
206 | |
207 |
public function autoBindIsEnabled()100% |
208 |
{ |
209 |
return ($this->autoBind === true); |
210 |
} |
211 | |
212 |
public function reset()100% |
213 |
{ |
214 |
self::$linker->unlink($this); |
215 | |
216 |
$this->mockClass = null; |
217 |
$this->mockMethods = array(); |
218 | |
219 |
return parent::reset(); |
220 |
} |
221 | |
222 |
public function getMock()100% |
223 |
{ |
224 |
return self::$linker->getMock($this); |
225 |
} |
226 | |
227 |
public function invoke($method, array $arguments = array())100% |
228 |
{ |
229 |
$this->checkMethod($method); |
230 | |
231 |
if (isset($this->{$method}) === false) |
232 |
{ |
233 |
throw new exceptions\logic('Method ' . $method . '() is not under control'); |
234 |
} |
235 | |
236 |
return parent::invoke($method, $arguments); |
237 |
} |
238 | |
239 |
public static function enableAutoBindForNewMock()100% |
240 |
{ |
241 |
self::$autoBindForNewMock = true; |
242 |
} |
243 | |
244 |
public static function disableAutoBindForNewMock()100% |
245 |
{ |
246 |
self::$autoBindForNewMock = false; |
247 |
} |
248 | |
249 |
public static function get($unset = true)100% |
250 |
{ |
251 |
$instance = self::$controlNextNewMock; |
252 | |
253 |
if ($instance !== null && $unset === true) |
254 |
{ |
255 |
self::$controlNextNewMock = null; |
256 |
} |
257 | |
258 |
return $instance; |
259 |
} |
260 | |
261 |
public static function setLinker(controller\linker $linker = null)0% |
262 |
{ |
263 |
self::$linker = $linker ?: new controller\linker(); |
264 |
} |
265 | |
266 |
public static function getForMock(aggregator $mock)100% |
267 |
{ |
268 |
return self::$linker->getController($mock); |
269 |
} |
270 | |
271 |
protected function checkMethod($method)93% |
272 |
{ |
273 |
if ($this->mockClass !== null && $this->disableMethodChecking === false && in_array(strtolower($method), $this->mockMethods) === false) |
274 |
{ |
275 |
if (in_array('__call', $this->mockMethods) === false) |
276 |
{ |
277 |
throw new exceptions\logic('Method \'' . $this->getMockClass() . '::' . $method . '()\' does not exist'); |
278 |
} |
279 | |
280 |
if (isset($this->__call) === false) |
281 |
{ |
282 |
$controller = $this; |
283 | |
284 |
parent::__set('__call', function($method, $arguments) use ($controller) { |
285 |
return $controller->invoke($method, $arguments); |
286 |
} |
287 |
); |
288 |
} |
289 |
} |
290 | |
291 |
return $this; |
292 |
} |
293 | |
294 |
protected function buildInvoker($methodName, \closure $factory = null)100% |
295 |
{ |
296 |
if ($factory === null) |
297 |
{ |
298 |
$factory = function($methodName, $mock) { return new mock\controller\invoker($methodName, $mock); }; |
299 |
} |
300 | |
301 |
return $factory($methodName, $this->getMock()); |
302 |
} |
303 | |
304 |
protected function setInvoker($methodName, \closure $factory = null)100% |
305 |
{ |
306 |
$invoker = parent::setInvoker($methodName, $factory); |
307 | |
308 |
$mock = $this->getMock(); |
309 | |
310 |
if ($mock !== null) |
311 |
{ |
312 |
$invoker->setMock($this->getMock()); |
313 |
} |
314 | |
315 |
if ($this->autoBind === true) |
316 |
{ |
317 |
$invoker->bindTo($mock); |
318 |
} |
319 | |
320 |
return $invoker; |
321 |
} |
322 | |
323 |
protected function buildCall($function, array $arguments)100% |
324 |
{ |
325 |
$call = parent::buildCall($function, $arguments); |
326 | |
327 |
if ($this->mockClass !== null) |
328 |
{ |
329 |
$call->setDecorator(new decorators\addClass($this->mockClass)); |
330 |
} |
331 | |
332 |
return $call; |
333 |
} |
334 |
} |
335 | |
336 |
controller::setLinker(); |