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(); |