96% of 1707OPs |
98% of 270Lines |
84% of 238Branches |
38% of 137Paths |
# | |
---|---|
1 |
<?php |
2 |
|
3 |
namespace mageekguy\atoum\asserters; |
4 |
|
5 |
use |
6 |
mageekguy\atoum\asserters, |
7 |
mageekguy\atoum\exceptions |
8 |
; |
9 |
|
10 |
class phpArray extends asserters\variable implements \arrayAccess |
11 |
{ |
12 |
private $key = null; |
13 |
private $innerAsserter = null; |
14 |
private $innerAsserterUsed = false; |
15 |
private $innerValue = null; |
16 |
private $innerValueIsSet = false; |
17 |
|
18 |
public function __get($asserter)100% |
19 |
{ |
20 |
switch (strtolower($asserter)) |
21 |
{ |
22 |
case 'keys': |
23 |
return $this->getKeysAsserter(); |
24 |
|
25 |
case 'size': |
26 |
return $this->getSizeAsserter(); |
27 |
|
28 |
case 'isempty': |
29 |
return $this->isEmpty(); |
30 |
|
31 |
default: |
32 |
$asserter = parent::__get($asserter); |
33 |
|
34 |
if ($asserter instanceof asserters\variable === false) |
35 |
{ |
36 |
$this->resetInnerAsserter(); |
37 |
|
38 |
return $asserter; |
39 |
} |
40 |
else |
41 |
{ |
42 |
if ($this->innerAsserter === null || $this->innerAsserterUsed === true) |
43 |
{ |
44 |
$this->innerValue = $this->value; |
45 |
$this->innerAsserterUsed = false; |
46 |
} |
47 |
|
48 |
$this->innerAsserter = $asserter; |
49 |
|
50 |
return $this; |
51 |
} |
52 |
} |
53 |
} |
54 |
|
55 |
public function __call($method, $arguments)100% |
56 |
{ |
57 |
if ($this->innerAsserterCanUse($method) === false) |
58 |
{ |
59 |
return parent::__call($method, $arguments); |
60 |
} |
61 |
else |
62 |
{ |
63 |
return $this->callInnerAsserterMethod($method, $arguments); |
64 |
} |
65 |
} |
66 |
|
67 |
public function getKey()100% |
68 |
{ |
69 |
return $this->key; |
70 |
} |
71 |
|
72 |
public function getInnerAsserter()100% |
73 |
{ |
74 |
return $this->innerAsserter; |
75 |
} |
76 |
|
77 |
public function getInnerValue()100% |
78 |
{ |
79 |
return $this->innerValue; |
80 |
} |
81 |
|
82 |
public function reset()100% |
83 |
{ |
84 |
$this->key = null; |
85 |
|
86 |
return parent::reset()->resetInnerAsserter(); |
87 |
} |
88 |
|
89 |
public function offsetGet($key)93% |
90 |
{ |
91 |
if ($this->innerAsserter === null) |
92 |
{ |
93 |
if ($this->analyzer->isArray($this->hasKey($key)->value[$key]) === true) |
94 |
{ |
95 |
parent::setWith($this->value[$key]); |
96 |
} |
97 |
else |
98 |
{ |
99 |
$this->fail($this->_('Value %s at key %s is not an array', $this->getTypeOf($this->value[$key]), $key)); |
100 |
} |
101 |
} |
102 |
else |
103 |
{ |
104 |
if (array_key_exists($key, $this->innerValue) === false) |
105 |
{ |
106 |
$this->fail($this->_('%s has no key %s', $this->getTypeOf($this->innerValue), $this->getTypeOf($key))); |
107 |
} |
108 |
else |
109 |
{ |
110 |
$this->innerValue = $this->innerValue[$key]; |
111 |
$this->innerValueIsSet = true; |
112 |
} |
113 |
} |
114 |
|
115 |
return $this; |
116 |
} |
117 |
|
118 |
public function offsetSet($key, $value)100% |
119 |
{ |
120 |
throw new exceptions\logic('Tested array is read only'); |
121 |
} |
122 |
|
123 |
public function offsetUnset($key)100% |
124 |
{ |
125 |
throw new exceptions\logic('Array is read only'); |
126 |
} |
127 |
|
128 |
public function offsetExists($key)100% |
129 |
{ |
130 |
$value = ($this->innerAsserter === null ? $this->value : $this->innerValue); |
131 |
|
132 |
return ($value !== null && array_key_exists($key, $value) === true); |
133 |
} |
134 |
|
135 |
public function setWith($value)100% |
136 |
{ |
137 |
$innerAsserter = $this->innerAsserter; |
138 |
|
139 |
if ($innerAsserter !== null) |
140 |
{ |
141 |
$this->reset(); |
142 |
|
143 |
return $innerAsserter->setWith($value); |
144 |
} |
145 |
else |
146 |
{ |
147 |
parent::setWith($value); |
148 |
|
149 |
if ($this->analyzer->isArray($this->value) === true) |
150 |
{ |
151 |
$this->pass(); |
152 |
} |
153 |
else |
154 |
{ |
155 |
$this->fail($this->_('%s is not an array', $this)); |
156 |
} |
157 |
|
158 |
return $this; |
159 |
} |
160 |
} |
161 |
|
162 |
public function setByReferenceWith(& $value)80% |
163 |
{ |
164 |
if ($this->innerAsserter !== null) |
165 |
{ |
166 |
return $this->innerAsserter->setByReferenceWith($value); |
167 |
} |
168 |
else |
169 |
{ |
170 |
parent::setByReferenceWith($value); |
171 |
|
172 |
if ($this->analyzer->isArray($this->value) === true) |
173 |
{ |
174 |
$this->pass(); |
175 |
} |
176 |
else |
177 |
{ |
178 |
$this->fail($this->_('%s is not an array', $this)); |
179 |
} |
180 |
|
181 |
return $this; |
182 |
} |
183 |
} |
184 |
|
185 |
public function hasSize($size, $failMessage = null)100% |
186 |
{ |
187 |
if (sizeof($this->valueIsSet()->value) == $size) |
188 |
{ |
189 |
$this->pass(); |
190 |
} |
191 |
else |
192 |
{ |
193 |
$this->fail($failMessage ?: $this->_('%s has size %d, expected size %d', $this, sizeof($this->valueIsSet()->value), $size)); |
194 |
} |
195 |
|
196 |
return $this; |
197 |
} |
198 |
|
199 |
public function isEmpty($failMessage = null)100% |
200 |
{ |
201 |
if (sizeof($this->valueIsSet()->value) == 0) |
202 |
{ |
203 |
$this->pass(); |
204 |
} |
205 |
else |
206 |
{ |
207 |
$this->fail($failMessage ?: $this->_('%s is not empty', $this)); |
208 |
} |
209 |
|
210 |
return $this; |
211 |
} |
212 |
|
213 |
public function isNotEmpty($failMessage = null)100% |
214 |
{ |
215 |
if (sizeof($this->valueIsSet()->value) > 0) |
216 |
{ |
217 |
$this->pass(); |
218 |
} |
219 |
else |
220 |
{ |
221 |
$this->fail($failMessage ?: $this->_('%s is empty', $this)); |
222 |
} |
223 |
|
224 |
return $this; |
225 |
} |
226 |
|
227 |
public function strictlyContains($value, $failMessage = null)100% |
228 |
{ |
229 |
return $this->containsValue($value, $failMessage, true); |
230 |
} |
231 |
|
232 |
public function contains($value, $failMessage = null)100% |
233 |
{ |
234 |
return $this->containsValue($value, $failMessage, false); |
235 |
} |
236 |
|
237 |
public function strictlyNotContains($value, $failMessage = null)100% |
238 |
{ |
239 |
return $this->notContainsValue($value, $failMessage, true); |
240 |
} |
241 |
|
242 |
public function notContains($value, $failMessage = null)100% |
243 |
{ |
244 |
return $this->notContainsValue($value, $failMessage, false); |
245 |
} |
246 |
|
247 |
public function atKey($key, $failMessage = null)100% |
248 |
{ |
249 |
$this->hasKey($key, $failMessage)->key = $key; |
250 |
|
251 |
return $this; |
252 |
} |
253 |
|
254 |
public function hasKeys(array $keys, $failMessage = null)100% |
255 |
{ |
256 |
if (sizeof($undefinedKeys = array_diff($keys, array_keys($this->valueIsSet()->value))) <= 0) |
257 |
{ |
258 |
$this->pass(); |
259 |
} |
260 |
else |
261 |
{ |
262 |
$this->fail($failMessage ?: $this->_('%s has no keys %s', $this, $this->getTypeOf($undefinedKeys))); |
263 |
} |
264 |
|
265 |
return $this; |
266 |
} |
267 |
|
268 |
public function notHasKeys(array $keys, $failMessage = null)100% |
269 |
{ |
270 |
$this->valueIsSet(); |
271 | |
272 |
if (sizeof($definedKeys = array_intersect($keys, array_keys($this->value))) <= 0) |
273 |
{ |
274 |
$this->pass(); |
275 |
} |
276 |
else |
277 |
{ |
278 |
$this->fail($failMessage ?: $this->_('%s has keys %s', $this, $this->getTypeOf($definedKeys))); |
279 |
} |
280 |
|
281 |
return $this; |
282 |
} |
283 |
|
284 |
public function hasKey($key, $failMessage = null)100% |
285 |
{ |
286 |
if (array_key_exists($key, $this->valueIsSet()->value)) |
287 |
{ |
288 |
$this->pass(); |
289 |
} |
290 |
else |
291 |
{ |
292 |
$this->fail($failMessage ?: $this->_('%s has no key %s', $this, $this->getTypeOf($key))); |
293 |
} |
294 |
|
295 |
return $this; |
296 |
} |
297 |
|
298 |
public function notHasKey($key, $failMessage = null)100% |
299 |
{ |
300 |
if (array_key_exists($key, $this->valueIsSet()->value) === false) |
301 |
{ |
302 |
$this->pass(); |
303 |
} |
304 |
else |
305 |
{ |
306 |
$this->fail($failMessage ?: $this->_('%s has key %s', $this, $this->getTypeOf($key))); |
307 |
} |
308 |
|
309 |
return $this; |
310 |
} |
311 |
|
312 |
public function containsValues(array $values, $failMessage = null)100% |
313 |
{ |
314 |
return $this->intersect($values, $failMessage, false); |
315 |
} |
316 |
|
317 |
public function strictlyContainsValues(array $values, $failMessage = null)100% |
318 |
{ |
319 |
return $this->intersect($values, $failMessage, true); |
320 |
} |
321 |
|
322 |
public function notContainsValues(array $values, $failMessage = null)100% |
323 |
{ |
324 |
return $this->notIntersect($values, $failMessage, false); |
325 |
} |
326 |
|
327 |
public function strictlyNotContainsValues(array $values, $failMessage = null)100% |
328 |
{ |
329 |
return $this->notIntersect($values, $failMessage, true); |
330 |
} |
331 |
|
332 |
public function isEqualTo($value, $failMessage = null)100% |
333 |
{ |
334 |
return $this->callAssertion(__FUNCTION__, array($value, $failMessage)); |
335 |
} |
336 |
|
337 |
public function isNotEqualTo($value, $failMessage = null)100% |
338 |
{ |
339 |
return $this->callAssertion(__FUNCTION__, array($value, $failMessage)); |
340 |
} |
341 |
|
342 |
public function isIdenticalTo($value, $failMessage = null)100% |
343 |
{ |
344 |
return $this->callAssertion(__FUNCTION__, array($value, $failMessage)); |
345 |
} |
346 |
|
347 |
public function isNotIdenticalTo($value, $failMessage = null)100% |
348 |
{ |
349 |
return $this->callAssertion(__FUNCTION__, array($value, $failMessage)); |
350 |
} |
351 |
|
352 |
public function isReferenceTo(& $reference, $failMessage = null)0% |
353 |
{ |
354 |
return $this->callAssertion(__FUNCTION__, array(& $reference, $failMessage)); |
355 |
} |
356 |
|
357 |
protected function containsValue($value, $failMessage, $strict)100% |
358 |
{ |
359 |
if (in_array($value, $this->valueIsSet()->value, $strict) === true) |
360 |
{ |
361 |
if ($this->key === null) |
362 |
{ |
363 |
$this->pass(); |
364 |
} |
365 |
else |
366 |
{ |
367 |
if ($strict === false) |
368 |
{ |
369 |
$pass = ($this->value[$this->key] == $value); |
370 |
} |
371 |
else |
372 |
{ |
373 |
$pass = ($this->value[$this->key] === $value); |
374 |
} |
375 |
|
376 |
if ($pass === false) |
377 |
{ |
378 |
$key = $this->key; |
379 |
} |
380 |
|
381 |
$this->key = null; |
382 |
|
383 |
if ($pass === true) |
384 |
{ |
385 |
$this->pass(); |
386 |
} |
387 |
else |
388 |
{ |
389 |
if ($failMessage === null) |
390 |
{ |
391 |
if ($strict === false) |
392 |
{ |
393 |
$failMessage = $this->_('%s does not contain %s at key %s', $this, $this->getTypeOf($value), $this->getTypeOf($key)); |
394 |
} |
395 |
else |
396 |
{ |
397 |
$failMessage = $this->_('%s does not strictly contain %s at key %s', $this, $this->getTypeOf($value), $this->getTypeOf($key)); |
398 |
} |
399 |
} |
400 |
|
401 |
$this->fail($failMessage); |
402 |
} |
403 |
} |
404 |
} |
405 |
else |
406 |
{ |
407 |
if ($failMessage === null) |
408 |
{ |
409 |
if ($strict === false) |
410 |
{ |
411 |
$failMessage = $this->_('%s does not contain %s', $this, $this->getTypeOf($value)); |
412 |
} |
413 |
else |
414 |
{ |
415 |
$failMessage = $this->_('%s does not strictly contain %s', $this, $this->getTypeOf($value)); |
416 |
} |
417 |
} |
418 |
|
419 |
$this->fail($failMessage); |
420 |
} |
421 |
|
422 |
return $this; |
423 |
} |
424 |
|
425 |
protected function notContainsValue($value, $failMessage, $strict)98% |
426 |
{ |
427 |
if (in_array($value, $this->valueIsSet()->value, $strict) === false) |
428 |
{ |
429 |
$this->pass(); |
430 |
} |
431 |
else |
432 |
{ |
433 |
if ($this->key === null) |
434 |
{ |
435 |
if ($failMessage === null) |
436 |
{ |
437 |
if ($strict === false) |
438 |
{ |
439 |
$failMessage = $this->_('%s contains %s', $this, $this->getTypeOf($value)); |
440 |
} |
441 |
else |
442 |
{ |
443 |
$failMessage = $this->_('%s strictly contains %s', $this, $this->getTypeOf($value)); |
444 |
} |
445 |
} |
446 |
|
447 |
$this->fail($failMessage); |
448 |
} |
449 |
else |
450 |
{ |
451 |
if ($strict === false) |
452 |
{ |
453 |
$pass = ($this->value[$this->key] != $value); |
454 |
} |
455 |
else |
456 |
{ |
457 |
$pass = ($this->value[$this->key] !== $value); |
458 |
} |
459 |
|
460 |
if ($pass === false) |
461 |
{ |
462 |
$key = $this->key; |
463 |
} |
464 |
|
465 |
$this->key = null; |
466 |
|
467 |
if ($pass === true) |
468 |
{ |
469 |
$this->pass(); |
470 |
} |
471 |
else |
472 |
{ |
473 |
if ($failMessage === null) |
474 |
{ |
475 |
if ($strict === false) |
476 |
{ |
477 |
$failMessage = $this->_('%s contains %s at key %s', $this, $this->getTypeOf($value), $this->getTypeOf($key)); |
478 |
} |
479 |
else |
480 |
{ |
481 |
$failMessage = $this->_('%s strictly contains %s at key %s', $this, $this->getTypeOf($value), $this->getTypeOf($key)); |
482 |
} |
483 |
} |
484 |
|
485 |
$this->fail($failMessage); |
486 |
} |
487 |
} |
488 |
} |
489 |
|
490 |
return $this; |
491 |
} |
492 |
|
493 |
protected function intersect(array $values, $failMessage, $strict)100% |
494 |
{ |
495 |
$this->valueIsSet(); |
496 |
|
497 |
$unknownValues = array(); |
498 |
|
499 |
foreach ($values as $value) if (in_array($value, $this->value, $strict) === false) |
500 |
{ |
501 |
$unknownValues[] = $value; |
502 |
} |
503 |
|
504 |
if (sizeof($unknownValues) <= 0) |
505 |
{ |
506 |
$this->pass(); |
507 |
} |
508 |
else |
509 |
{ |
510 |
if ($failMessage === null) |
511 |
{ |
512 |
if ($strict === false) |
513 |
{ |
514 |
$failMessage = $this->_('%s does not contain values %s', $this, $this->getTypeOf($unknownValues)); |
515 |
} |
516 |
else |
517 |
{ |
518 |
$failMessage = $this->_('%s does not contain strictly values %s', $this, $this->getTypeOf($unknownValues)); |
519 |
} |
520 |
} |
521 |
|
522 |
$this->fail($failMessage); |
523 |
} |
524 |
|
525 |
return $this; |
526 |
} |
527 |
|
528 |
protected function notIntersect(array $values, $failMessage, $strict)100% |
529 |
{ |
530 |
$this->valueIsSet(); |
531 |
|
532 |
$knownValues = array(); |
533 |
|
534 |
foreach ($values as $value) if (in_array($value, $this->value, $strict) === true) |
535 |
{ |
536 |
$knownValues[] = $value; |
537 |
} |
538 |
|
539 |
if (sizeof($knownValues) <= 0) |
540 |
{ |
541 |
$this->pass(); |
542 |
} |
543 |
else |
544 |
{ |
545 |
if ($failMessage === null) |
546 |
{ |
547 |
if ($strict === false) |
548 |
{ |
549 |
$failMessage = $this->_('%s contains values %s', $this, $this->getTypeOf($knownValues)); |
550 |
} |
551 |
else |
552 |
{ |
553 |
$failMessage = $this->_('%s contains strictly values %s', $this, $this->getTypeOf($knownValues)); |
554 |
} |
555 |
} |
556 |
|
557 |
$this->fail($failMessage); |
558 |
} |
559 |
|
560 |
return $this; |
561 |
} |
562 |
|
563 |
protected function valueIsSet($message = 'Array is undefined')100% |
564 |
{ |
565 |
return parent::valueIsSet($message); |
566 |
} |
567 |
|
568 |
protected function getKeysAsserter()100% |
569 |
{ |
570 |
return $this->generator->__call('phpArray', array(array_keys($this->valueIsSet()->value))); |
571 |
} |
572 |
|
573 |
protected function getSizeAsserter()100% |
574 |
{ |
575 |
return $this->generator->__call('integer', array(sizeof($this->valueIsSet()->value))); |
576 |
} |
577 |
|
578 |
protected function callAssertion($method, array $arguments)100% |
579 |
{ |
580 |
if ($this->innerAsserterCanUse($method) === false) |
581 |
{ |
582 |
call_user_func_array(array('parent', $method), $arguments); |
583 |
} |
584 |
else |
585 |
{ |
586 |
$this->callInnerAsserterMethod($method, $arguments); |
587 |
} |
588 |
|
589 |
return $this; |
590 |
} |
591 |
|
592 |
protected function innerAsserterCanUse($method)100% |
593 |
{ |
594 |
return ($this->innerAsserter !== null && $this->innerValueIsSet === true && method_exists($this->innerAsserter, $method) === true); |
595 |
} |
596 |
|
597 |
protected function callInnerAsserterMethod($method, $arguments)100% |
598 |
{ |
599 |
call_user_func_array(array($this->innerAsserter->setWith($this->innerValue), $method), $arguments); |
600 |
|
601 |
$this->innerAsserterUsed = true; |
602 |
|
603 |
return $this; |
604 |
} |
605 |
|
606 |
protected function resetInnerAsserter()100% |
607 |
{ |
608 |
$this->innerAsserter = null; |
609 |
$this->innerValue = null; |
610 |
$this->innerValueIsSet = false; |
611 |
|
612 |
return $this; |
613 |
} |
614 |
} |